Tue Sep 30 01:19:32 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  * Hangup cause signalling implementation by
00015  * Levent Guendogdu <levon@feature-it.com>
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Implementation of Inter-Asterisk eXchange Version 2
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  *
00028  * \par See also
00029  * \arg \ref Config_iax
00030  *
00031  * \ingroup channel_drivers
00032  */
00033 
00034 /*** MODULEINFO
00035    <use>zaptel</use>
00036         <depend>res_features</depend>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <sys/types.h>
00046 #include <sys/mman.h>
00047 #include <dirent.h>
00048 #include <sys/socket.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #include <netinet/in_systm.h>
00052 #include <netinet/ip.h>
00053 #include <sys/time.h>
00054 #include <sys/signal.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include <strings.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netdb.h>
00061 #include <fcntl.h>
00062 #include <sys/stat.h>
00063 #include <regex.h>
00064 
00065 #ifdef HAVE_ZAPTEL
00066 #include <sys/ioctl.h>
00067 #include <zaptel/zaptel.h>
00068 #endif
00069 
00070 #include "asterisk/lock.h"
00071 #include "asterisk/frame.h" 
00072 #include "asterisk/channel.h"
00073 #include "asterisk/logger.h"
00074 #include "asterisk/module.h"
00075 #include "asterisk/pbx.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/io.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/options.h"
00080 #include "asterisk/cli.h"
00081 #include "asterisk/translate.h"
00082 #include "asterisk/md5.h"
00083 #include "asterisk/cdr.h"
00084 #include "asterisk/crypto.h"
00085 #include "asterisk/acl.h"
00086 #include "asterisk/manager.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/app.h"
00089 #include "asterisk/astdb.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/utils.h"
00093 #include "asterisk/causes.h"
00094 #include "asterisk/localtime.h"
00095 #include "asterisk/aes.h"
00096 #include "asterisk/dnsmgr.h"
00097 #include "asterisk/devicestate.h"
00098 #include "asterisk/netsock.h"
00099 #include "asterisk/stringfields.h"
00100 #include "asterisk/linkedlists.h"
00101 #include "asterisk/astobj2.h"
00102 
00103 #include "iax2.h"
00104 #include "iax2-parser.h"
00105 #include "iax2-provision.h"
00106 #include "jitterbuf.h"
00107 
00108 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00109    multithreaded mode. */
00110 #define SCHED_MULTITHREADED
00111 
00112 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00113    thread is actually doing. */
00114 #define DEBUG_SCHED_MULTITHREAD
00115 
00116 #ifndef IPTOS_MINCOST
00117 #define IPTOS_MINCOST 0x02
00118 #endif
00119 
00120 #ifdef SO_NO_CHECK
00121 static int nochecksums = 0;
00122 #endif
00123 
00124 
00125 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00126 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00127 
00128 #define DEFAULT_THREAD_COUNT 10
00129 #define DEFAULT_MAX_THREAD_COUNT 100
00130 #define DEFAULT_RETRY_TIME 1000
00131 #define MEMORY_SIZE 100
00132 #define DEFAULT_DROP 3
00133 
00134 #define DEBUG_SUPPORT
00135 
00136 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00137 
00138 /* Sample over last 100 units to determine historic jitter */
00139 #define GAMMA (0.01)
00140 
00141 static struct ast_codec_pref prefs;
00142 
00143 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00144 
00145 static char context[80] = "default";
00146 
00147 static char language[MAX_LANGUAGE] = "";
00148 static char regcontext[AST_MAX_CONTEXT] = "";
00149 
00150 static int maxauthreq = 3;
00151 static int max_retries = 4;
00152 static int ping_time = 21;
00153 static int lagrq_time = 10;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 
00162 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00163 
00164 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00165 
00166 static unsigned int tos = 0;
00167 
00168 static int min_reg_expire;
00169 static int max_reg_expire;
00170 
00171 static int timingfd = -1;           /* Timing file descriptor */
00172 
00173 static struct ast_netsock_list *netsock;
00174 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00175 static int defaultsockfd = -1;
00176 
00177 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00178 
00179 /* Ethernet, etc */
00180 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00181 /* T1, maybe ISDN */
00182 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00183                 ~AST_FORMAT_SLINEAR &        \
00184                 ~AST_FORMAT_ULAW &        \
00185                 ~AST_FORMAT_ALAW &        \
00186                 ~AST_FORMAT_G722) 
00187 /* A modem */
00188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00189                 ~AST_FORMAT_G726 &        \
00190                 ~AST_FORMAT_G726_AAL2 &      \
00191                 ~AST_FORMAT_ADPCM)
00192 
00193 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00194                 ~AST_FORMAT_G723_1)
00195 
00196 
00197 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00198 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00199 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00200 
00201 static   struct io_context *io;
00202 static   struct sched_context *sched;
00203 
00204 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00205 
00206 static int iaxdebug = 0;
00207 
00208 static int iaxtrunkdebug = 0;
00209 
00210 static int test_losspct = 0;
00211 #ifdef IAXTESTS
00212 static int test_late = 0;
00213 static int test_resync = 0;
00214 static int test_jit = 0;
00215 static int test_jitpct = 0;
00216 #endif /* IAXTESTS */
00217 
00218 static char accountcode[AST_MAX_ACCOUNT_CODE];
00219 static char mohinterpret[MAX_MUSICCLASS];
00220 static char mohsuggest[MAX_MUSICCLASS];
00221 static int amaflags = 0;
00222 static int adsi = 0;
00223 static int delayreject = 0;
00224 static int iax2_encryption = 0;
00225 
00226 static struct ast_flags globalflags = { 0 };
00227 
00228 static pthread_t netthreadid = AST_PTHREADT_NULL;
00229 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00230 AST_MUTEX_DEFINE_STATIC(sched_lock);
00231 static ast_cond_t sched_cond;
00232 
00233 enum {
00234    IAX_STATE_STARTED =     (1 << 0),
00235    IAX_STATE_AUTHENTICATED =  (1 << 1),
00236    IAX_STATE_TBD =      (1 << 2),
00237    IAX_STATE_UNCHANGED =      (1 << 3),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00272                        response, so that we've achieved a three-way handshake with
00273                        them before sending voice or anything else*/
00274    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00275 } iax2_flags;
00276 
00277 static int global_rtautoclear = 120;
00278 
00279 static int reload_config(void);
00280 static int iax2_reload(int fd, int argc, char *argv[]);
00281 
00282 
00283 struct iax2_user {
00284    AST_DECLARE_STRING_FIELDS(
00285       AST_STRING_FIELD(name);
00286       AST_STRING_FIELD(secret);
00287       AST_STRING_FIELD(dbsecret);
00288       AST_STRING_FIELD(accountcode);
00289       AST_STRING_FIELD(mohinterpret);
00290       AST_STRING_FIELD(mohsuggest);
00291       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00292       AST_STRING_FIELD(language);
00293       AST_STRING_FIELD(cid_num);
00294       AST_STRING_FIELD(cid_name);
00295    );
00296    
00297    int authmethods;
00298    int encmethods;
00299    int amaflags;
00300    int adsi;
00301    unsigned int flags;
00302    int capability;
00303    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00304    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00305    struct ast_codec_pref prefs;
00306    struct ast_ha *ha;
00307    struct iax2_context *contexts;
00308    struct ast_variable *vars;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361 };
00362 
00363 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00364 
00365 static struct iax2_trunk_peer {
00366    ast_mutex_t lock;
00367    int sockfd;
00368    struct sockaddr_in addr;
00369    struct timeval txtrunktime;      /*!< Transmit trunktime */
00370    struct timeval rxtrunktime;      /*!< Receive trunktime */
00371    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00372    struct timeval trunkact;      /*!< Last trunk activity */
00373    unsigned int lastsent;        /*!< Last sent time */
00374    /* Trunk data and length */
00375    unsigned char *trunkdata;
00376    unsigned int trunkdatalen;
00377    unsigned int trunkdataalloc;
00378    struct iax2_trunk_peer *next;
00379    int trunkerror;
00380    int calls;
00381 } *tpeers = NULL;
00382 
00383 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00384 
00385 struct iax_firmware {
00386    struct iax_firmware *next;
00387    int fd;
00388    int mmaplen;
00389    int dead;
00390    struct ast_iax2_firmware_header *fwh;
00391    unsigned char *buf;
00392 };
00393 
00394 enum iax_reg_state {
00395    REG_STATE_UNREGISTERED = 0,
00396    REG_STATE_REGSENT,
00397    REG_STATE_AUTHSENT,
00398    REG_STATE_REGISTERED,
00399    REG_STATE_REJECTED,
00400    REG_STATE_TIMEOUT,
00401    REG_STATE_NOAUTH
00402 };
00403 
00404 enum iax_transfer_state {
00405    TRANSFER_NONE = 0,
00406    TRANSFER_BEGIN,
00407    TRANSFER_READY,
00408    TRANSFER_RELEASED,
00409    TRANSFER_PASSTHROUGH,
00410    TRANSFER_MBEGIN,
00411    TRANSFER_MREADY,
00412    TRANSFER_MRELEASED,
00413    TRANSFER_MPASSTHROUGH,
00414    TRANSFER_MEDIA,
00415    TRANSFER_MEDIAPASS
00416 };
00417 
00418 struct iax2_registry {
00419    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00420    char username[80];
00421    char secret[80];        /*!< Password or key name in []'s */
00422    char random[80];
00423    int expire;          /*!< Sched ID of expiration */
00424    int refresh;            /*!< How often to refresh */
00425    enum iax_reg_state regstate;
00426    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00427    int callno;          /*!< Associated call number if applicable */
00428    struct sockaddr_in us;        /*!< Who the server thinks we are */
00429    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00430    AST_LIST_ENTRY(iax2_registry) entry;
00431 };
00432 
00433 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00434 
00435 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00436 #define MIN_RETRY_TIME     100
00437 #define MAX_RETRY_TIME     10000
00438 
00439 #define MAX_JITTER_BUFFER  50
00440 #define MIN_JITTER_BUFFER  10
00441 
00442 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00443 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00444 
00445 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00446 
00447 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00448 #define TS_GAP_FOR_JB_RESYNC  5000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxactivethreadcount = 0;
00454 
00455 struct iax_rr {
00456    int jitter;
00457    int losspct;
00458    int losscnt;
00459    int packets;
00460    int delay;
00461    int dropped;
00462    int ooo;
00463 };
00464 
00465 struct chan_iax2_pvt {
00466    /*! Socket to send/receive on for this call */
00467    int sockfd;
00468    /*! Last received voice format */
00469    int voiceformat;
00470    /*! Last received video format */
00471    int videoformat;
00472    /*! Last sent voice format */
00473    int svoiceformat;
00474    /*! Last sent video format */
00475    int svideoformat;
00476    /*! What we are capable of sending */
00477    int capability;
00478    /*! Last received timestamp */
00479    unsigned int last;
00480    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00481    unsigned int lastsent;
00482    /*! Timestamp of the last video frame sent */
00483    unsigned int lastvsent;
00484    /*! Next outgoing timestamp if everything is good */
00485    unsigned int nextpred;
00486    /*! True if the last voice we transmitted was not silence/CNG */
00487    int notsilenttx;
00488    /*! Ping time */
00489    unsigned int pingtime;
00490    /*! Max time for initial response */
00491    int maxtime;
00492    /*! Peer Address */
00493    struct sockaddr_in addr;
00494    /*! Actual used codec preferences */
00495    struct ast_codec_pref prefs;
00496    /*! Requested codec preferences */
00497    struct ast_codec_pref rprefs;
00498    /*! Our call number */
00499    unsigned short callno;
00500    /*! Peer callno */
00501    unsigned short peercallno;
00502    /*! Negotiated format, this is only used to remember what format was
00503        chosen for an unauthenticated call so that the channel can get
00504        created later using the right format */
00505    int chosenformat;
00506    /*! Peer selected format */
00507    int peerformat;
00508    /*! Peer capability */
00509    int peercapability;
00510    /*! timeval that we base our transmission on */
00511    struct timeval offset;
00512    /*! timeval that we base our delivery on */
00513    struct timeval rxcore;
00514    /*! The jitterbuffer */
00515         jitterbuf *jb;
00516    /*! active jb read scheduler id */
00517         int jbid;                       
00518    /*! LAG */
00519    int lag;
00520    /*! Error, as discovered by the manager */
00521    int error;
00522    /*! Owner if we have one */
00523    struct ast_channel *owner;
00524    /*! What's our state? */
00525    struct ast_flags state;
00526    /*! Expiry (optional) */
00527    int expiry;
00528    /*! Next outgoing sequence number */
00529    unsigned char oseqno;
00530    /*! Next sequence number they have not yet acknowledged */
00531    unsigned char rseqno;
00532    /*! Next incoming sequence number */
00533    unsigned char iseqno;
00534    /*! Last incoming sequence number we have acknowledged */
00535    unsigned char aseqno;
00536 
00537    AST_DECLARE_STRING_FIELDS(
00538       /*! Peer name */
00539       AST_STRING_FIELD(peer);
00540       /*! Default Context */
00541       AST_STRING_FIELD(context);
00542       /*! Caller ID if available */
00543       AST_STRING_FIELD(cid_num);
00544       AST_STRING_FIELD(cid_name);
00545       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00546       AST_STRING_FIELD(ani);
00547       /*! DNID */
00548       AST_STRING_FIELD(dnid);
00549       /*! RDNIS */
00550       AST_STRING_FIELD(rdnis);
00551       /*! Requested Extension */
00552       AST_STRING_FIELD(exten);
00553       /*! Expected Username */
00554       AST_STRING_FIELD(username);
00555       /*! Expected Secret */
00556       AST_STRING_FIELD(secret);
00557       /*! MD5 challenge */
00558       AST_STRING_FIELD(challenge);
00559       /*! Public keys permitted keys for incoming authentication */
00560       AST_STRING_FIELD(inkeys);
00561       /*! Private key for outgoing authentication */
00562       AST_STRING_FIELD(outkey);
00563       /*! Preferred language */
00564       AST_STRING_FIELD(language);
00565       /*! Hostname/peername for naming purposes */
00566       AST_STRING_FIELD(host);
00567 
00568       AST_STRING_FIELD(dproot);
00569       AST_STRING_FIELD(accountcode);
00570       AST_STRING_FIELD(mohinterpret);
00571       AST_STRING_FIELD(mohsuggest);
00572    );
00573    
00574    /*! permitted authentication methods */
00575    int authmethods;
00576    /*! permitted encryption methods */
00577    int encmethods;
00578    /*! Encryption AES-128 Key */
00579    aes_encrypt_ctx ecx;
00580    /*! Decryption AES-128 Key */
00581    aes_decrypt_ctx dcx;
00582    /*! 32 bytes of semi-random data */
00583    unsigned char semirand[32];
00584    /*! Associated registry */
00585    struct iax2_registry *reg;
00586    /*! Associated peer for poking */
00587    struct iax2_peer *peerpoke;
00588    /*! IAX_ flags */
00589    unsigned int flags;
00590    int adsi;
00591 
00592    /*! Transferring status */
00593    enum iax_transfer_state transferring;
00594    /*! Transfer identifier */
00595    int transferid;
00596    /*! Who we are IAX transfering to */
00597    struct sockaddr_in transfer;
00598    /*! What's the new call number for the transfer */
00599    unsigned short transfercallno;
00600    /*! Transfer decrypt AES-128 Key */
00601    aes_encrypt_ctx tdcx;
00602 
00603    /*! Status of knowledge of peer ADSI capability */
00604    int peeradsicpe;
00605 
00606    /*! Who we are bridged to */
00607    unsigned short bridgecallno;
00608    
00609    int pingid;       /*!< Transmit PING request */
00610    int lagid;        /*!< Retransmit lag request */
00611    int autoid;       /*!< Auto hangup for Dialplan requestor */
00612    int authid;       /*!< Authentication rejection ID */
00613    int authfail;        /*!< Reason to report failure */
00614    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00615    int calling_ton;
00616    int calling_tns;
00617    int calling_pres;
00618    int amaflags;
00619    struct iax2_dpcache *dpentries;
00620    struct ast_variable *vars;
00621    /*! last received remote rr */
00622    struct iax_rr remote_rr;
00623    /*! Current base time: (just for stats) */
00624    int min;
00625    /*! Dropped frame count: (just for stats) */
00626    int frames_dropped;
00627    /*! received frame count: (just for stats) */
00628    int frames_received;
00629 };
00630 
00631 static struct ast_iax2_queue {
00632    AST_LIST_HEAD(, iax_frame) queue;
00633    int count;
00634 } iaxq;
00635 
00636 /*!
00637  * This module will get much higher performance when doing a lot of
00638  * user and peer lookups if the number of buckets is increased from 1.
00639  * However, to maintain old behavior for Asterisk 1.4, these are set to
00640  * 1 by default.  When using multiple buckets, search order through these
00641  * containers is considered random, so you will not be able to depend on
00642  * the order the entires are specified in iax.conf for matching order. */
00643 #ifdef LOW_MEMORY
00644 #define MAX_PEER_BUCKETS 1
00645 /* #define MAX_PEER_BUCKETS 17 */
00646 #else
00647 #define MAX_PEER_BUCKETS 1
00648 /* #define MAX_PEER_BUCKETS 563 */
00649 #endif
00650 static struct ao2_container *peers;
00651 
00652 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00653 static struct ao2_container *users;
00654 
00655 static struct ast_firmware_list {
00656    struct iax_firmware *wares;
00657    ast_mutex_t lock;
00658 } waresl;
00659 
00660 /*! Extension exists */
00661 #define CACHE_FLAG_EXISTS     (1 << 0)
00662 /*! Extension is nonexistent */
00663 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00664 /*! Extension can exist */
00665 #define CACHE_FLAG_CANEXIST      (1 << 2)
00666 /*! Waiting to hear back response */
00667 #define CACHE_FLAG_PENDING    (1 << 3)
00668 /*! Timed out */
00669 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00670 /*! Request transmitted */
00671 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00672 /*! Timeout */
00673 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00674 /*! Matchmore */
00675 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00676 
00677 static struct iax2_dpcache {
00678    char peercontext[AST_MAX_CONTEXT];
00679    char exten[AST_MAX_EXTENSION];
00680    struct timeval orig;
00681    struct timeval expiry;
00682    int flags;
00683    unsigned short callno;
00684    int waiters[256];
00685    struct iax2_dpcache *next;
00686    struct iax2_dpcache *peer; /*!< For linking in peers */
00687 } *dpcache;
00688 
00689 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00690 
00691 static void reg_source_db(struct iax2_peer *p);
00692 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00693 
00694 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00695 
00696 #define IAX_IOSTATE_IDLE      0
00697 #define IAX_IOSTATE_READY     1
00698 #define IAX_IOSTATE_PROCESSING   2
00699 #define IAX_IOSTATE_SCHEDREADY   3
00700 
00701 #define IAX_TYPE_POOL    1
00702 #define IAX_TYPE_DYNAMIC 2
00703 
00704 struct iax2_pkt_buf {
00705    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00706    size_t len;
00707    unsigned char buf[1];
00708 };
00709 
00710 struct iax2_thread {
00711    AST_LIST_ENTRY(iax2_thread) list;
00712    int type;
00713    int iostate;
00714 #ifdef SCHED_MULTITHREADED
00715    void (*schedfunc)(const void *);
00716    const void *scheddata;
00717 #endif
00718 #ifdef DEBUG_SCHED_MULTITHREAD
00719    char curfunc[80];
00720 #endif   
00721    int actions;
00722    pthread_t threadid;
00723    int threadnum;
00724    struct sockaddr_in iosin;
00725    unsigned char readbuf[4096]; 
00726    unsigned char *buf;
00727    ssize_t buf_len;
00728    size_t buf_size;
00729    int iofd;
00730    time_t checktime;
00731    ast_mutex_t lock;
00732    ast_cond_t cond;
00733    unsigned int ready_for_signal:1;
00734    /*! if this thread is processing a full frame,
00735      some information about that frame will be stored
00736      here, so we can avoid dispatching any more full
00737      frames for that callno to other threads */
00738    struct {
00739       unsigned short callno;
00740       struct sockaddr_in sin;
00741       unsigned char type;
00742       unsigned char csub;
00743    } ffinfo;
00744    /*! Queued up full frames for processing.  If more full frames arrive for
00745     *  a call which this thread is already processing a full frame for, they
00746     *  are queued up here. */
00747    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00748 };
00749 
00750 /* Thread lists */
00751 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00752 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00753 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00754 
00755 static void *iax2_process_thread(void *data);
00756 
00757 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00758 {
00759    ast_mutex_lock(lock);
00760    ast_cond_signal(cond);
00761    ast_mutex_unlock(lock);
00762 }
00763 
00764 static void iax_debug_output(const char *data)
00765 {
00766    if (iaxdebug)
00767       ast_verbose("%s", data);
00768 }
00769 
00770 static void iax_error_output(const char *data)
00771 {
00772    ast_log(LOG_WARNING, "%s", data);
00773 }
00774 
00775 static void jb_error_output(const char *fmt, ...)
00776 {
00777    va_list args;
00778    char buf[1024];
00779 
00780    va_start(args, fmt);
00781    vsnprintf(buf, 1024, fmt, args);
00782    va_end(args);
00783 
00784    ast_log(LOG_ERROR, buf);
00785 }
00786 
00787 static void jb_warning_output(const char *fmt, ...)
00788 {
00789    va_list args;
00790    char buf[1024];
00791 
00792    va_start(args, fmt);
00793    vsnprintf(buf, 1024, fmt, args);
00794    va_end(args);
00795 
00796    ast_log(LOG_WARNING, buf);
00797 }
00798 
00799 static void jb_debug_output(const char *fmt, ...)
00800 {
00801    va_list args;
00802    char buf[1024];
00803 
00804    va_start(args, fmt);
00805    vsnprintf(buf, 1024, fmt, args);
00806    va_end(args);
00807 
00808    ast_verbose(buf);
00809 }
00810 
00811 /* XXX We probably should use a mutex when working with this XXX */
00812 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00813 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00814 static struct timeval lastused[ARRAY_LEN(iaxs)];
00815 
00816 /*!
00817  * \brief Another container of iax2_pvt structures
00818  *
00819  * Active IAX2 pvt structs are also stored in this container, if they are a part
00820  * of an active call where we know the remote side's call number.  The reason
00821  * for this is that incoming media frames do not contain our call number.  So,
00822  * instead of having to iterate the entire iaxs array, we use this container to
00823  * look up calls where the remote side is using a given call number.
00824  */
00825 static struct ao2_container *iax_peercallno_pvts;
00826 
00827 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00828    but keeps the division between trunked and non-trunked better. */
00829 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00830 
00831 static int maxtrunkcall = TRUNK_CALL_START;
00832 static int maxnontrunkcall = 1;
00833 
00834 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);
00835 static int expire_registry(const void *data);
00836 static int iax2_answer(struct ast_channel *c);
00837 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00838 static int iax2_devicestate(void *data);
00839 static int iax2_digit_begin(struct ast_channel *c, char digit);
00840 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00841 static int iax2_do_register(struct iax2_registry *reg);
00842 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00843 static int iax2_hangup(struct ast_channel *c);
00844 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00845 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00846 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00847 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00848 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00849 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00850 static int iax2_sendtext(struct ast_channel *c, const char *text);
00851 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00852 static int iax2_transfer(struct ast_channel *c, const char *dest);
00853 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00854 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00855 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00856 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00857 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00858 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00859 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00860 static struct ast_frame *iax2_read(struct ast_channel *c);
00861 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00862 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00863 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00864 static void prune_peers(void);
00865 
00866 static const struct ast_channel_tech iax2_tech = {
00867    .type = "IAX2",
00868    .description = tdesc,
00869    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00870    .properties = AST_CHAN_TP_WANTSJITTER,
00871    .requester = iax2_request,
00872    .devicestate = iax2_devicestate,
00873    .send_digit_begin = iax2_digit_begin,
00874    .send_digit_end = iax2_digit_end,
00875    .send_text = iax2_sendtext,
00876    .send_image = iax2_sendimage,
00877    .send_html = iax2_sendhtml,
00878    .call = iax2_call,
00879    .hangup = iax2_hangup,
00880    .answer = iax2_answer,
00881    .read = iax2_read,
00882    .write = iax2_write,
00883    .write_video = iax2_write,
00884    .indicate = iax2_indicate,
00885    .setoption = iax2_setoption,
00886    .bridge = iax2_bridge,
00887    .transfer = iax2_transfer,
00888    .fixup = iax2_fixup,
00889 };
00890 
00891 /* WARNING: insert_idle_thread should only ever be called within the
00892  * context of an iax2_process_thread() thread.
00893  */
00894 static void insert_idle_thread(struct iax2_thread *thread)
00895 {
00896    if (thread->type == IAX_TYPE_DYNAMIC) {
00897       AST_LIST_LOCK(&dynamic_list);
00898       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00899       AST_LIST_UNLOCK(&dynamic_list);
00900    } else {
00901       AST_LIST_LOCK(&idle_list);
00902       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00903       AST_LIST_UNLOCK(&idle_list);
00904    }
00905 
00906    return;
00907 }
00908 
00909 static struct iax2_thread *find_idle_thread(void)
00910 {
00911    pthread_attr_t attr;
00912    struct iax2_thread *thread = NULL;
00913 
00914    /* Pop the head of the list off */
00915    AST_LIST_LOCK(&idle_list);
00916    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00917    AST_LIST_UNLOCK(&idle_list);
00918 
00919    /* If no idle thread is available from the regular list, try dynamic */
00920    if (thread == NULL) {
00921       AST_LIST_LOCK(&dynamic_list);
00922       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00923       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00924       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00925          /* We need to MAKE a thread! */
00926          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00927             thread->threadnum = iaxdynamicthreadcount;
00928             thread->type = IAX_TYPE_DYNAMIC;
00929             ast_mutex_init(&thread->lock);
00930             ast_cond_init(&thread->cond, NULL);
00931             pthread_attr_init(&attr);
00932             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00933             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00934                free(thread);
00935                thread = NULL;
00936             } else {
00937                /* All went well and the thread is up, so increment our count */
00938                iaxdynamicthreadcount++;
00939                
00940                /* Wait for the thread to be ready before returning it to the caller */
00941                while (!thread->ready_for_signal)
00942                   usleep(1);
00943             }
00944          }
00945       }
00946       AST_LIST_UNLOCK(&dynamic_list);
00947    }
00948 
00949    /* this thread is not processing a full frame (since it is idle),
00950       so ensure that the field for the full frame call number is empty */
00951    if (thread)
00952       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00953 
00954    return thread;
00955 }
00956 
00957 #ifdef SCHED_MULTITHREADED
00958 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00959 {
00960    struct iax2_thread *thread = NULL;
00961    static time_t lasterror;
00962    static time_t t;
00963 
00964    thread = find_idle_thread();
00965 
00966    if (thread != NULL) {
00967       thread->schedfunc = func;
00968       thread->scheddata = data;
00969       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00970 #ifdef DEBUG_SCHED_MULTITHREAD
00971       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00972 #endif
00973       signal_condition(&thread->lock, &thread->cond);
00974       return 0;
00975    }
00976    time(&t);
00977    if (t != lasterror && option_debug) 
00978       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00979    lasterror = t;
00980 
00981    return -1;
00982 }
00983 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00984 #endif
00985 
00986 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00987 {
00988    int res;
00989 
00990    res = ast_sched_add(con, when, callback, data);
00991    signal_condition(&sched_lock, &sched_cond);
00992 
00993    return res;
00994 }
00995 
00996 static int send_ping(const void *data);
00997 
00998 static void __send_ping(const void *data)
00999 {
01000    int callno = (long) data;
01001 
01002    ast_mutex_lock(&iaxsl[callno]);
01003 
01004    while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01005       if (iaxs[callno]->peercallno) {
01006          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01007       }
01008       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01009       break;
01010    }
01011 
01012    ast_mutex_unlock(&iaxsl[callno]);
01013 }
01014 
01015 static int send_ping(const void *data)
01016 {
01017 #ifdef SCHED_MULTITHREADED
01018    if (schedule_action(__send_ping, data))
01019 #endif      
01020       __send_ping(data);
01021    return 0;
01022 }
01023 
01024 static int get_encrypt_methods(const char *s)
01025 {
01026    int e;
01027    if (!strcasecmp(s, "aes128"))
01028       e = IAX_ENCRYPT_AES128;
01029    else if (ast_true(s))
01030       e = IAX_ENCRYPT_AES128;
01031    else
01032       e = 0;
01033    return e;
01034 }
01035 
01036 static int send_lagrq(const void *data);
01037 
01038 static void __send_lagrq(const void *data)
01039 {
01040    int callno = (long) data;
01041 
01042    ast_mutex_lock(&iaxsl[callno]);
01043 
01044    while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01045       if (iaxs[callno]->peercallno) {
01046          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01047       }
01048       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01049       break;
01050    }
01051 
01052    ast_mutex_unlock(&iaxsl[callno]);
01053 }
01054 
01055 static int send_lagrq(const void *data)
01056 {
01057 #ifdef SCHED_MULTITHREADED
01058    if (schedule_action(__send_lagrq, data))
01059 #endif      
01060       __send_lagrq(data);
01061    return 0;
01062 }
01063 
01064 static unsigned char compress_subclass(int subclass)
01065 {
01066    int x;
01067    int power=-1;
01068    /* If it's 128 or smaller, just return it */
01069    if (subclass < IAX_FLAG_SC_LOG)
01070       return subclass;
01071    /* Otherwise find its power */
01072    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01073       if (subclass & (1 << x)) {
01074          if (power > -1) {
01075             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01076             return 0;
01077          } else
01078             power = x;
01079       }
01080    }
01081    return power | IAX_FLAG_SC_LOG;
01082 }
01083 
01084 static int uncompress_subclass(unsigned char csub)
01085 {
01086    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01087    if (csub & IAX_FLAG_SC_LOG) {
01088       /* special case for 'compressed' -1 */
01089       if (csub == 0xff)
01090          return -1;
01091       else
01092          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01093    }
01094    else
01095       return csub;
01096 }
01097 
01098 /*!
01099  * \note The only member of the peer passed here guaranteed to be set is the name field
01100  */
01101 static int peer_hash_cb(const void *obj, const int flags)
01102 {
01103    const struct iax2_peer *peer = obj;
01104 
01105    return ast_str_hash(peer->name);
01106 }
01107 
01108 /*!
01109  * \note The only member of the peer passed here guaranteed to be set is the name field
01110  */
01111 static int peer_cmp_cb(void *obj, void *arg, int flags)
01112 {
01113    struct iax2_peer *peer = obj, *peer2 = arg;
01114 
01115    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01116 }
01117 
01118 /*!
01119  * \note The only member of the user passed here guaranteed to be set is the name field
01120  */
01121 static int user_hash_cb(const void *obj, const int flags)
01122 {
01123    const struct iax2_user *user = obj;
01124 
01125    return ast_str_hash(user->name);
01126 }
01127 
01128 /*!
01129  * \note The only member of the user passed here guaranteed to be set is the name field
01130  */
01131 static int user_cmp_cb(void *obj, void *arg, int flags)
01132 {
01133    struct iax2_user *user = obj, *user2 = arg;
01134 
01135    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01136 }
01137 
01138 /*!
01139  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01140  *       so do not call it with a pvt lock held.
01141  */
01142 static struct iax2_peer *find_peer(const char *name, int realtime) 
01143 {
01144    struct iax2_peer *peer = NULL;
01145    struct iax2_peer tmp_peer = {
01146       .name = name,
01147    };
01148 
01149    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01150 
01151    /* Now go for realtime if applicable */
01152    if(!peer && realtime)
01153       peer = realtime_peer(name, NULL);
01154 
01155    return peer;
01156 }
01157 
01158 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01159 {
01160    ao2_ref(peer, +1);
01161    return peer;
01162 }
01163 
01164 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01165 {
01166    ao2_ref(peer, -1);
01167    return NULL;
01168 }
01169 
01170 static inline struct iax2_user *user_ref(struct iax2_user *user)
01171 {
01172    ao2_ref(user, +1);
01173    return user;
01174 }
01175 
01176 static inline struct iax2_user *user_unref(struct iax2_user *user)
01177 {
01178    ao2_ref(user, -1);
01179    return NULL;
01180 }
01181 
01182 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01183 {
01184    struct iax2_peer *peer = NULL;
01185    int res = 0;
01186    struct ao2_iterator i;
01187 
01188    i = ao2_iterator_init(peers, 0);
01189    while ((peer = ao2_iterator_next(&i))) {
01190       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01191           (peer->addr.sin_port == sin.sin_port)) {
01192          ast_copy_string(host, peer->name, len);
01193          peer_unref(peer);
01194          res = 1;
01195          break;
01196       }
01197       peer_unref(peer);
01198    }
01199 
01200    if (!peer) {
01201       peer = realtime_peer(NULL, &sin);
01202       if (peer) {
01203          ast_copy_string(host, peer->name, len);
01204          peer_unref(peer);
01205          res = 1;
01206       }
01207    }
01208 
01209    return res;
01210 }
01211 
01212 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01213 {
01214    /* Decrement AUTHREQ count if needed */
01215    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01216       struct iax2_user *user;
01217       struct iax2_user tmp_user = {
01218          .name = pvt->username,
01219       };
01220 
01221       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01222       if (user) {
01223          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01224          user = user_unref(user);       
01225       }
01226 
01227       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01228    }
01229 
01230    /* No more pings or lagrq's */
01231    AST_SCHED_DEL(sched, pvt->pingid);
01232    AST_SCHED_DEL(sched, pvt->lagid);
01233    AST_SCHED_DEL(sched, pvt->autoid);
01234    AST_SCHED_DEL(sched, pvt->authid);
01235    AST_SCHED_DEL(sched, pvt->initid);
01236    AST_SCHED_DEL(sched, pvt->jbid);
01237 }
01238 
01239 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01240 {
01241    if (!pvt->peercallno) {
01242       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01243       return;
01244    }
01245 
01246    ao2_link(iax_peercallno_pvts, pvt);
01247 }
01248 
01249 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01250 {
01251    if (!pvt->peercallno) {
01252       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01253       return;
01254    }
01255 
01256    ao2_unlink(iax_peercallno_pvts, pvt);
01257 }
01258 
01259 static void update_max_trunk(void)
01260 {
01261    int max = TRUNK_CALL_START;
01262    int x;
01263 
01264    /* XXX Prolly don't need locks here XXX */
01265    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01266       if (iaxs[x]) {
01267          max = x + 1;
01268       }
01269    }
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 iax2_frame_free(struct iax_frame *fr)
01277 {
01278    AST_SCHED_DEL(sched, fr->retrans);
01279    iax_frame_free(fr);
01280 }
01281 
01282 static void iax2_destroy(int callno)
01283 {
01284    struct chan_iax2_pvt *pvt;
01285    struct ast_channel *owner;
01286 
01287 retry:
01288    pvt = iaxs[callno];
01289    gettimeofday(&lastused[callno], NULL);
01290    
01291    owner = pvt ? pvt->owner : NULL;
01292 
01293    if (owner) {
01294       if (ast_mutex_trylock(&owner->lock)) {
01295          if (option_debug > 2)
01296             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01297          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01298          goto retry;
01299       }
01300    }
01301    if (!owner) {
01302       iaxs[callno] = NULL;
01303    }
01304 
01305    if (pvt) {
01306       if (!owner) {
01307          pvt->owner = NULL;
01308       } else {
01309          /* If there's an owner, prod it to give up */
01310          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01311           * because we already hold the owner channel lock. */
01312          ast_queue_hangup(owner);
01313       }
01314 
01315       if (pvt->peercallno) {
01316          remove_by_peercallno(pvt);
01317       }
01318 
01319       if (!owner) {
01320          ao2_ref(pvt, -1);
01321          pvt = NULL;
01322       }
01323    }
01324 
01325    if (owner) {
01326       ast_mutex_unlock(&owner->lock);
01327    }
01328 
01329    if (callno & 0x4000) {
01330       update_max_trunk();
01331    }
01332 }
01333 
01334 static void pvt_destructor(void *obj)
01335 {
01336    struct chan_iax2_pvt *pvt = obj;
01337    struct iax_frame *cur = NULL;
01338 
01339    iax2_destroy_helper(pvt);
01340 
01341    /* Already gone */
01342    ast_set_flag(pvt, IAX_ALREADYGONE); 
01343 
01344    AST_LIST_LOCK(&iaxq.queue);
01345    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01346       /* Cancel any pending transmissions */
01347       if (cur->callno == pvt->callno) { 
01348          cur->retries = -1;
01349       }
01350    }
01351    AST_LIST_UNLOCK(&iaxq.queue);
01352 
01353    if (pvt->reg) {
01354       pvt->reg->callno = 0;
01355    }
01356 
01357    if (!pvt->owner) {
01358       jb_frame frame;
01359       if (pvt->vars) {
01360           ast_variables_destroy(pvt->vars);
01361           pvt->vars = NULL;
01362       }
01363 
01364       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01365          iax2_frame_free(frame.data);
01366       }
01367 
01368       jb_destroy(pvt->jb);
01369       ast_string_field_free_memory(pvt);
01370    }
01371 }
01372 
01373 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01374 {
01375    struct chan_iax2_pvt *tmp;
01376    jb_conf jbconf;
01377 
01378    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01379       return NULL;
01380    }
01381 
01382    if (ast_string_field_init(tmp, 32)) {
01383       ao2_ref(tmp, -1);
01384       tmp = NULL;
01385       return NULL;
01386    }
01387       
01388    tmp->prefs = prefs;
01389    tmp->callno = 0;
01390    tmp->peercallno = 0;
01391    tmp->transfercallno = 0;
01392    tmp->bridgecallno = 0;
01393    tmp->pingid = -1;
01394    tmp->lagid = -1;
01395    tmp->autoid = -1;
01396    tmp->authid = -1;
01397    tmp->initid = -1;
01398 
01399    ast_string_field_set(tmp,exten, "s");
01400    ast_string_field_set(tmp,host, host);
01401 
01402    tmp->jb = jb_new();
01403    tmp->jbid = -1;
01404    jbconf.max_jitterbuf = maxjitterbuffer;
01405    jbconf.resync_threshold = resyncthreshold;
01406    jbconf.max_contig_interp = maxjitterinterps;
01407    jb_setconf(tmp->jb,&jbconf);
01408 
01409    return tmp;
01410 }
01411 
01412 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01413 {
01414    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01415    if (new) {
01416       size_t afdatalen = new->afdatalen;
01417       memcpy(new, fr, sizeof(*new));
01418       iax_frame_wrap(new, &fr->af);
01419       new->afdatalen = afdatalen;
01420       new->data = NULL;
01421       new->datalen = 0;
01422       new->direction = DIRECTION_INGRESS;
01423       new->retrans = -1;
01424    }
01425    return new;
01426 }
01427 
01428 #define NEW_PREVENT  0
01429 #define NEW_ALLOW    1
01430 #define NEW_FORCE    2
01431 
01432 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01433 {
01434    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01435       (cur->addr.sin_port == sin->sin_port)) {
01436       /* This is the main host */
01437       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01438           (check_dcallno ? dcallno == cur->callno : 1) ) {
01439          /* That's us.  Be sure we keep track of the peer call number */
01440          return 1;
01441       }
01442    }
01443    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01444        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01445       /* We're transferring */
01446       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01447          return 1;
01448    }
01449    return 0;
01450 }
01451 
01452 static void update_max_nontrunk(void)
01453 {
01454    int max = 1;
01455    int x;
01456    /* XXX Prolly don't need locks here XXX */
01457    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01458       if (iaxs[x])
01459          max = x + 1;
01460    }
01461    maxnontrunkcall = max;
01462    if (option_debug && iaxdebug)
01463       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01464 }
01465 
01466 static int make_trunk(unsigned short callno, int locked)
01467 {
01468    int x;
01469    int res= 0;
01470    struct timeval now;
01471    if (iaxs[callno]->oseqno) {
01472       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01473       return -1;
01474    }
01475    if (callno & TRUNK_CALL_START) {
01476       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01477       return -1;
01478    }
01479    gettimeofday(&now, NULL);
01480    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01481       ast_mutex_lock(&iaxsl[x]);
01482       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01483          iaxs[x] = iaxs[callno];
01484          iaxs[x]->callno = x;
01485          iaxs[callno] = NULL;
01486          /* Update the two timers that should have been started */
01487          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01488          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01489          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01490          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01491          if (locked)
01492             ast_mutex_unlock(&iaxsl[callno]);
01493          res = x;
01494          if (!locked)
01495             ast_mutex_unlock(&iaxsl[x]);
01496          break;
01497       }
01498       ast_mutex_unlock(&iaxsl[x]);
01499    }
01500    if (x >= ARRAY_LEN(iaxs) - 1) {
01501       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01502       return -1;
01503    }
01504    if (option_debug)
01505       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01506    /* We move this call from a non-trunked to a trunked call */
01507    update_max_trunk();
01508    update_max_nontrunk();
01509    return res;
01510 }
01511 
01512 /*!
01513  * \note Calling this function while holding another pvt lock can cause a deadlock.
01514  */
01515 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01516 {
01517    int res = 0;
01518    int x;
01519    struct timeval now;
01520    char host[80];
01521 
01522    if (new <= NEW_ALLOW) {
01523       if (callno) {
01524          struct chan_iax2_pvt *pvt;
01525          struct chan_iax2_pvt tmp_pvt = {
01526             .callno = dcallno,
01527             .peercallno = callno,
01528             /* hack!! */
01529             .frames_received = check_dcallno,
01530          };
01531  
01532          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01533  
01534          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01535             if (return_locked) {
01536                ast_mutex_lock(&iaxsl[pvt->callno]);
01537             }
01538             res = pvt->callno;
01539             ao2_ref(pvt, -1);
01540             pvt = NULL;
01541             return res;
01542          }
01543       }
01544 
01545       /* Look for an existing connection first */
01546       for (x = 1; !res && x < maxnontrunkcall; x++) {
01547          ast_mutex_lock(&iaxsl[x]);
01548          if (iaxs[x]) {
01549             /* Look for an exact match */
01550             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01551                res = x;
01552             }
01553          }
01554          if (!res || !return_locked)
01555             ast_mutex_unlock(&iaxsl[x]);
01556       }
01557       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01558          ast_mutex_lock(&iaxsl[x]);
01559          if (iaxs[x]) {
01560             /* Look for an exact match */
01561             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01562                res = x;
01563             }
01564          }
01565          if (!res || !return_locked)
01566             ast_mutex_unlock(&iaxsl[x]);
01567       }
01568    }
01569    if (!res && (new >= NEW_ALLOW)) {
01570       int start, found = 0;
01571 
01572       /* It may seem odd that we look through the peer list for a name for
01573        * this *incoming* call.  Well, it is weird.  However, users don't
01574        * have an IP address/port number that we can match against.  So,
01575        * this is just checking for a peer that has that IP/port and
01576        * assuming that we have a user of the same name.  This isn't always
01577        * correct, but it will be changed if needed after authentication. */
01578       if (!iax2_getpeername(*sin, host, sizeof(host)))
01579          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01580 
01581       now = ast_tvnow();
01582       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01583       for (x = start; 1; x++) {
01584          if (x == TRUNK_CALL_START) {
01585             x = 1;
01586             continue;
01587          }
01588 
01589          /* Find first unused call number that hasn't been used in a while */
01590          ast_mutex_lock(&iaxsl[x]);
01591          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01592             found = 1;
01593             break;
01594          }
01595          ast_mutex_unlock(&iaxsl[x]);
01596          
01597          if (x == start - 1) {
01598             break;
01599          }
01600       }
01601       /* We've still got lock held if we found a spot */
01602       if (x == start - 1 && !found) {
01603          ast_log(LOG_WARNING, "No more space\n");
01604          return 0;
01605       }
01606       iaxs[x] = new_iax(sin, host);
01607       update_max_nontrunk();
01608       if (iaxs[x]) {
01609          if (option_debug && iaxdebug)
01610             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01611          iaxs[x]->sockfd = sockfd;
01612          iaxs[x]->addr.sin_port = sin->sin_port;
01613          iaxs[x]->addr.sin_family = sin->sin_family;
01614          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01615          iaxs[x]->peercallno = callno;
01616          iaxs[x]->callno = x;
01617          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01618          iaxs[x]->expiry = min_reg_expire;
01619          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01620          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01621          iaxs[x]->amaflags = amaflags;
01622          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01623          
01624          ast_string_field_set(iaxs[x], accountcode, accountcode);
01625          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01626          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01627 
01628          if (iaxs[x]->peercallno) {
01629             store_by_peercallno(iaxs[x]);
01630          }
01631       } else {
01632          ast_log(LOG_WARNING, "Out of resources\n");
01633          ast_mutex_unlock(&iaxsl[x]);
01634          return 0;
01635       }
01636       if (!return_locked)
01637          ast_mutex_unlock(&iaxsl[x]);
01638       res = x;
01639    }
01640    return res;
01641 }
01642 
01643 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01644 
01645    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01646 }
01647 
01648 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01649 
01650    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01651 }
01652 
01653 /*!
01654  * \brief Queue a frame to a call's owning asterisk channel
01655  *
01656  * \pre This function assumes that iaxsl[callno] is locked when called.
01657  *
01658  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01659  * was valid before calling it, it may no longer be valid after calling it.
01660  * This function may unlock and lock the mutex associated with this callno,
01661  * meaning that another thread may grab it and destroy the call.
01662  */
01663 static int iax2_queue_frame(int callno, struct ast_frame *f)
01664 {
01665    for (;;) {
01666       if (iaxs[callno] && iaxs[callno]->owner) {
01667          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01668             /* Avoid deadlock by pausing and trying again */
01669             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01670          } else {
01671             ast_queue_frame(iaxs[callno]->owner, f);
01672             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01673             break;
01674          }
01675       } else
01676          break;
01677    }
01678    return 0;
01679 }
01680 
01681 /*!
01682  * \brief Queue a hangup frame on the ast_channel owner
01683  *
01684  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01685  * is active for the given call number.
01686  *
01687  * \pre Assumes lock for callno is already held.
01688  *
01689  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01690  * was valid before calling it, it may no longer be valid after calling it.
01691  * This function may unlock and lock the mutex associated with this callno,
01692  * meaning that another thread may grab it and destroy the call.
01693  */
01694 static int iax2_queue_hangup(int callno)
01695 {
01696    for (;;) {
01697       if (iaxs[callno] && iaxs[callno]->owner) {
01698          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01699             /* Avoid deadlock by pausing and trying again */
01700             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01701          } else {
01702             ast_queue_hangup(iaxs[callno]->owner);
01703             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01704             break;
01705          }
01706       } else
01707          break;
01708    }
01709    return 0;
01710 }
01711 
01712 /*!
01713  * \brief Queue a control frame on the ast_channel owner
01714  *
01715  * This function queues a control frame on the owner of the IAX2 pvt struct that
01716  * is active for the given call number.
01717  *
01718  * \pre Assumes lock for callno is already held.
01719  *
01720  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01721  * was valid before calling it, it may no longer be valid after calling it.
01722  * This function may unlock and lock the mutex associated with this callno,
01723  * meaning that another thread may grab it and destroy the call.
01724  */
01725 static int iax2_queue_control_data(int callno, 
01726    enum ast_control_frame_type control, const void *data, size_t datalen)
01727 {
01728    for (;;) {
01729       if (iaxs[callno] && iaxs[callno]->owner) {
01730          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01731             /* Avoid deadlock by pausing and trying again */
01732             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01733          } else {
01734             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01735             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01736             break;
01737          }
01738       } else
01739          break;
01740    }
01741    return 0;
01742 }
01743 static void destroy_firmware(struct iax_firmware *cur)
01744 {
01745    /* Close firmware */
01746    if (cur->fwh) {
01747       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01748    }
01749    close(cur->fd);
01750    free(cur);
01751 }
01752 
01753 static int try_firmware(char *s)
01754 {
01755    struct stat stbuf;
01756    struct iax_firmware *cur;
01757    int ifd;
01758    int fd;
01759    int res;
01760    
01761    struct ast_iax2_firmware_header *fwh, fwh2;
01762    struct MD5Context md5;
01763    unsigned char sum[16];
01764    unsigned char buf[1024];
01765    int len, chunk;
01766    char *s2;
01767    char *last;
01768    s2 = alloca(strlen(s) + 100);
01769    if (!s2) {
01770       ast_log(LOG_WARNING, "Alloca failed!\n");
01771       return -1;
01772    }
01773    last = strrchr(s, '/');
01774    if (last)
01775       last++;
01776    else
01777       last = s;
01778    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01779    res = stat(s, &stbuf);
01780    if (res < 0) {
01781       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01782       return -1;
01783    }
01784    /* Make sure it's not a directory */
01785    if (S_ISDIR(stbuf.st_mode))
01786       return -1;
01787    ifd = open(s, O_RDONLY);
01788    if (ifd < 0) {
01789       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01790       return -1;
01791    }
01792    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01793    if (fd < 0) {
01794       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01795       close(ifd);
01796       return -1;
01797    }
01798    /* Unlink our newly created file */
01799    unlink(s2);
01800    
01801    /* Now copy the firmware into it */
01802    len = stbuf.st_size;
01803    while(len) {
01804       chunk = len;
01805       if (chunk > sizeof(buf))
01806          chunk = sizeof(buf);
01807       res = read(ifd, buf, chunk);
01808       if (res != chunk) {
01809          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01810          close(ifd);
01811          close(fd);
01812          return -1;
01813       }
01814       res = write(fd, buf, chunk);
01815       if (res != chunk) {
01816          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01817          close(ifd);
01818          close(fd);
01819          return -1;
01820       }
01821       len -= chunk;
01822    }
01823    close(ifd);
01824    /* Return to the beginning */
01825    lseek(fd, 0, SEEK_SET);
01826    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01827       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01828       close(fd);
01829       return -1;
01830    }
01831    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01832       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01833       close(fd);
01834       return -1;
01835    }
01836    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01837       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01838       close(fd);
01839       return -1;
01840    }
01841    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01842       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01843       close(fd);
01844       return -1;
01845    }
01846    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01847    if (fwh == (void *) -1) {
01848       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01849       close(fd);
01850       return -1;
01851    }
01852    MD5Init(&md5);
01853    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01854    MD5Final(sum, &md5);
01855    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01856       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01857       munmap((void*)fwh, stbuf.st_size);
01858       close(fd);
01859       return -1;
01860    }
01861    cur = waresl.wares;
01862    while(cur) {
01863       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01864          /* Found a candidate */
01865          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01866             /* The version we have on loaded is older, load this one instead */
01867             break;
01868          /* This version is no newer than what we have.  Don't worry about it.
01869             We'll consider it a proper load anyhow though */
01870          munmap((void*)fwh, stbuf.st_size);
01871          close(fd);
01872          return 0;
01873       }
01874       cur = cur->next;
01875    }
01876    if (!cur) {
01877       /* Allocate a new one and link it */
01878       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01879          cur->fd = -1;
01880          cur->next = waresl.wares;
01881          waresl.wares = cur;
01882       }
01883    }
01884    if (cur) {
01885       if (cur->fwh) {
01886          munmap((void*)cur->fwh, cur->mmaplen);
01887       }
01888       if (cur->fd > -1)
01889          close(cur->fd);
01890       cur->fwh = fwh;
01891       cur->fd = fd;
01892       cur->mmaplen = stbuf.st_size;
01893       cur->dead = 0;
01894    }
01895    return 0;
01896 }
01897 
01898 static int iax_check_version(char *dev)
01899 {
01900    int res = 0;
01901    struct iax_firmware *cur;
01902    if (!ast_strlen_zero(dev)) {
01903       ast_mutex_lock(&waresl.lock);
01904       cur = waresl.wares;
01905       while(cur) {
01906          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01907             res = ntohs(cur->fwh->version);
01908             break;
01909          }
01910          cur = cur->next;
01911       }
01912       ast_mutex_unlock(&waresl.lock);
01913    }
01914    return res;
01915 }
01916 
01917 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01918 {
01919    int res = -1;
01920    unsigned int bs = desc & 0xff;
01921    unsigned int start = (desc >> 8) & 0xffffff;
01922    unsigned int bytes;
01923    struct iax_firmware *cur;
01924    if (!ast_strlen_zero((char *)dev) && bs) {
01925       start *= bs;
01926       ast_mutex_lock(&waresl.lock);
01927       cur = waresl.wares;
01928       while(cur) {
01929          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01930             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01931             if (start < ntohl(cur->fwh->datalen)) {
01932                bytes = ntohl(cur->fwh->datalen) - start;
01933                if (bytes > bs)
01934                   bytes = bs;
01935                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01936             } else {
01937                bytes = 0;
01938                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01939             }
01940             if (bytes == bs)
01941                res = 0;
01942             else
01943                res = 1;
01944             break;
01945          }
01946          cur = cur->next;
01947       }
01948       ast_mutex_unlock(&waresl.lock);
01949    }
01950    return res;
01951 }
01952 
01953 
01954 static void reload_firmware(int unload)
01955 {
01956    struct iax_firmware *cur, *curl, *curp;
01957    DIR *fwd;
01958    struct dirent *de;
01959    char dir[256];
01960    char fn[256];
01961    /* Mark all as dead */
01962    ast_mutex_lock(&waresl.lock);
01963    cur = waresl.wares;
01964    while(cur) {
01965       cur->dead = 1;
01966       cur = cur->next;
01967    }
01968 
01969    /* Now that we've freed them, load the new ones */
01970    if (!unload) {
01971       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01972       fwd = opendir(dir);
01973       if (fwd) {
01974          while((de = readdir(fwd))) {
01975             if (de->d_name[0] != '.') {
01976                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01977                if (!try_firmware(fn)) {
01978                   if (option_verbose > 1)
01979                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01980                }
01981             }
01982          }
01983          closedir(fwd);
01984       } else 
01985          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01986    }
01987 
01988    /* Clean up leftovers */
01989    cur = waresl.wares;
01990    curp = NULL;
01991    while(cur) {
01992       curl = cur;
01993       cur = cur->next;
01994       if (curl->dead) {
01995          if (curp) {
01996             curp->next = cur;
01997          } else {
01998             waresl.wares = cur;
01999          }
02000          destroy_firmware(curl);
02001       } else {
02002          curp = cur;
02003       }
02004    }
02005    ast_mutex_unlock(&waresl.lock);
02006 }
02007 
02008 /*!
02009  * \note This function assumes that iaxsl[callno] is locked when called.
02010  *
02011  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02012  * was valid before calling it, it may no longer be valid after calling it.
02013  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02014  * associated with this callno, meaning that another thread may grab it and destroy the call.
02015  */
02016 static int __do_deliver(void *data)
02017 {
02018    /* Just deliver the packet by using queueing.  This is called by
02019      the IAX thread with the iaxsl lock held. */
02020    struct iax_frame *fr = data;
02021    fr->retrans = -1;
02022    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02023    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02024       iax2_queue_frame(fr->callno, &fr->af);
02025    /* Free our iax frame */
02026    iax2_frame_free(fr);
02027    /* And don't run again */
02028    return 0;
02029 }
02030 
02031 static int handle_error(void)
02032 {
02033    /* XXX Ideally we should figure out why an error occured and then abort those
02034       rather than continuing to try.  Unfortunately, the published interface does
02035       not seem to work XXX */
02036 #if 0
02037    struct sockaddr_in *sin;
02038    int res;
02039    struct msghdr m;
02040    struct sock_extended_err e;
02041    m.msg_name = NULL;
02042    m.msg_namelen = 0;
02043    m.msg_iov = NULL;
02044    m.msg_control = &e;
02045    m.msg_controllen = sizeof(e);
02046    m.msg_flags = 0;
02047    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02048    if (res < 0)
02049       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02050    else {
02051       if (m.msg_controllen) {
02052          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02053          if (sin) 
02054             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02055          else
02056             ast_log(LOG_WARNING, "No address detected??\n");
02057       } else {
02058          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02059       }
02060    }
02061 #endif
02062    return 0;
02063 }
02064 
02065 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02066 {
02067    int res;
02068    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02069                sizeof(*sin));
02070    if (res < 0) {
02071       if (option_debug)
02072          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02073       handle_error();
02074    } else
02075       res = 0;
02076    return res;
02077 }
02078 
02079 static int send_packet(struct iax_frame *f)
02080 {
02081    int res;
02082    int callno = f->callno;
02083 
02084    /* Don't send if there was an error, but return error instead */
02085    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02086        return -1;
02087    
02088    /* Called with iaxsl held */
02089    if (option_debug > 2 && iaxdebug)
02090       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));
02091    if (f->transfer) {
02092       if (iaxdebug)
02093          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02094       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02095                sizeof(iaxs[callno]->transfer));
02096    } else {
02097       if (iaxdebug)
02098          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02099       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02100                sizeof(iaxs[callno]->addr));
02101    }
02102    if (res < 0) {
02103       if (option_debug && iaxdebug)
02104          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02105       handle_error();
02106    } else
02107       res = 0;
02108    return res;
02109 }
02110 
02111 /*!
02112  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02113  *       for the given call number may disappear during its execution.
02114  */
02115 static int iax2_predestroy(int callno)
02116 {
02117    struct ast_channel *c;
02118    struct chan_iax2_pvt *pvt = iaxs[callno];
02119 
02120    if (!pvt)
02121       return -1;
02122    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02123       iax2_destroy_helper(pvt);
02124       ast_set_flag(pvt, IAX_ALREADYGONE); 
02125    }
02126    c = pvt->owner;
02127    if (c) {
02128       c->tech_pvt = NULL;
02129       iax2_queue_hangup(callno);
02130       pvt->owner = NULL;
02131       ast_module_unref(ast_module_info->self);
02132    }
02133    return 0;
02134 }
02135 
02136 static int update_packet(struct iax_frame *f)
02137 {
02138    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02139    struct ast_iax2_full_hdr *fh = f->data;
02140    /* Mark this as a retransmission */
02141    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02142    /* Update iseqno */
02143    f->iseqno = iaxs[f->callno]->iseqno;
02144    fh->iseqno = f->iseqno;
02145    return 0;
02146 }
02147 
02148 static int attempt_transmit(const void *data);
02149 static void __attempt_transmit(const void *data)
02150 {
02151    /* Attempt to transmit the frame to the remote peer...
02152       Called without iaxsl held. */
02153    struct iax_frame *f = (struct iax_frame *)data;
02154    int freeme=0;
02155    int callno = f->callno;
02156    /* Make sure this call is still active */
02157    if (callno) 
02158       ast_mutex_lock(&iaxsl[callno]);
02159    if (callno && iaxs[callno]) {
02160       if ((f->retries < 0) /* Already ACK'd */ ||
02161           (f->retries >= max_retries) /* Too many attempts */) {
02162             /* Record an error if we've transmitted too many times */
02163             if (f->retries >= max_retries) {
02164                if (f->transfer) {
02165                   /* Transfer timeout */
02166                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02167                } else if (f->final) {
02168                   if (f->final) 
02169                      iax2_destroy(callno);
02170                } else {
02171                   if (iaxs[callno]->owner)
02172                      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);
02173                   iaxs[callno]->error = ETIMEDOUT;
02174                   if (iaxs[callno]->owner) {
02175                      struct ast_frame fr = { 0, };
02176                      /* Hangup the fd */
02177                      fr.frametype = AST_FRAME_CONTROL;
02178                      fr.subclass = AST_CONTROL_HANGUP;
02179                      iax2_queue_frame(callno, &fr); // XXX
02180                      /* Remember, owner could disappear */
02181                      if (iaxs[callno] && iaxs[callno]->owner)
02182                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02183                   } else {
02184                      if (iaxs[callno]->reg) {
02185                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02186                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02187                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02188                      }
02189                      iax2_destroy(callno);
02190                   }
02191                }
02192 
02193             }
02194             freeme++;
02195       } else {
02196          /* Update it if it needs it */
02197          update_packet(f);
02198          /* Attempt transmission */
02199          send_packet(f);
02200          f->retries++;
02201          /* Try again later after 10 times as long */
02202          f->retrytime *= 10;
02203          if (f->retrytime > MAX_RETRY_TIME)
02204             f->retrytime = MAX_RETRY_TIME;
02205          /* Transfer messages max out at one second */
02206          if (f->transfer && (f->retrytime > 1000))
02207             f->retrytime = 1000;
02208          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02209       }
02210    } else {
02211       /* Make sure it gets freed */
02212       f->retries = -1;
02213       freeme++;
02214    }
02215    if (callno)
02216       ast_mutex_unlock(&iaxsl[callno]);
02217    /* Do not try again */
02218    if (freeme) {
02219       /* Don't attempt delivery, just remove it from the queue */
02220       AST_LIST_LOCK(&iaxq.queue);
02221       AST_LIST_REMOVE(&iaxq.queue, f, list);
02222       iaxq.count--;
02223       AST_LIST_UNLOCK(&iaxq.queue);
02224       f->retrans = -1;
02225       /* Free the IAX frame */
02226       iax2_frame_free(f);
02227    }
02228 }
02229 
02230 static int attempt_transmit(const void *data)
02231 {
02232 #ifdef SCHED_MULTITHREADED
02233    if (schedule_action(__attempt_transmit, data))
02234 #endif      
02235       __attempt_transmit(data);
02236    return 0;
02237 }
02238 
02239 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02240 {
02241    struct iax2_peer *peer;
02242 
02243    if (argc != 4)
02244         return RESULT_SHOWUSAGE;
02245    if (!strcmp(argv[3],"all")) {
02246       reload_config();
02247       ast_cli(fd, "OK cache is flushed.\n");
02248    } else if ((peer = find_peer(argv[3], 0))) {
02249       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02250          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02251          expire_registry(peer_ref(peer));
02252          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02253       } else {
02254          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02255       }
02256       peer_unref(peer);
02257    } else {
02258       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02259    }
02260    
02261    return RESULT_SUCCESS;
02262 }
02263 
02264 static int iax2_test_losspct(int fd, int argc, char *argv[])
02265 {
02266        if (argc != 4)
02267                return RESULT_SHOWUSAGE;
02268 
02269        test_losspct = atoi(argv[3]);
02270 
02271        return RESULT_SUCCESS;
02272 }
02273 
02274 #ifdef IAXTESTS
02275 static int iax2_test_late(int fd, int argc, char *argv[])
02276 {
02277    if (argc != 4)
02278       return RESULT_SHOWUSAGE;
02279 
02280    test_late = atoi(argv[3]);
02281 
02282    return RESULT_SUCCESS;
02283 }
02284 
02285 static int iax2_test_resync(int fd, int argc, char *argv[])
02286 {
02287    if (argc != 4)
02288       return RESULT_SHOWUSAGE;
02289 
02290    test_resync = atoi(argv[3]);
02291 
02292    return RESULT_SUCCESS;
02293 }
02294 
02295 static int iax2_test_jitter(int fd, int argc, char *argv[])
02296 {
02297    if (argc < 4 || argc > 5)
02298       return RESULT_SHOWUSAGE;
02299 
02300    test_jit = atoi(argv[3]);
02301    if (argc == 5) 
02302       test_jitpct = atoi(argv[4]);
02303 
02304    return RESULT_SUCCESS;
02305 }
02306 #endif /* IAXTESTS */
02307 
02308 /*! \brief  peer_status: Report Peer status in character string */
02309 /*    returns 1 if peer is online, -1 if unmonitored */
02310 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02311 {
02312    int res = 0;
02313    if (peer->maxms) {
02314       if (peer->lastms < 0) {
02315          ast_copy_string(status, "UNREACHABLE", statuslen);
02316       } else if (peer->lastms > peer->maxms) {
02317          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02318          res = 1;
02319       } else if (peer->lastms) {
02320          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02321          res = 1;
02322       } else {
02323          ast_copy_string(status, "UNKNOWN", statuslen);
02324       }
02325    } else { 
02326       ast_copy_string(status, "Unmonitored", statuslen);
02327       res = -1;
02328    }
02329    return res;
02330 }
02331 
02332 /*! \brief Show one peer in detail */
02333 static int iax2_show_peer(int fd, int argc, char *argv[])
02334 {
02335    char status[30];
02336    char cbuf[256];
02337    struct iax2_peer *peer;
02338    char codec_buf[512];
02339    int x = 0, codec = 0, load_realtime = 0;
02340 
02341    if (argc < 4)
02342       return RESULT_SHOWUSAGE;
02343 
02344    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02345 
02346    peer = find_peer(argv[3], load_realtime);
02347    if (peer) {
02348       ast_cli(fd,"\n\n");
02349       ast_cli(fd, "  * Name       : %s\n", peer->name);
02350       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02351       ast_cli(fd, "  Context      : %s\n", peer->context);
02352       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02353       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02354       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02355       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02356       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02357       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));
02358       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02359       ast_cli(fd, "  Username     : %s\n", peer->username);
02360       ast_cli(fd, "  Codecs       : ");
02361       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02362       ast_cli(fd, "%s\n", codec_buf);
02363 
02364       ast_cli(fd, "  Codec Order  : (");
02365       for(x = 0; x < 32 ; x++) {
02366          codec = ast_codec_pref_index(&peer->prefs,x);
02367          if(!codec)
02368             break;
02369          ast_cli(fd, "%s", ast_getformatname(codec));
02370          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02371             ast_cli(fd, "|");
02372       }
02373 
02374       if (!x)
02375          ast_cli(fd, "none");
02376       ast_cli(fd, ")\n");
02377 
02378       ast_cli(fd, "  Status       : ");
02379       peer_status(peer, status, sizeof(status));   
02380       ast_cli(fd, "%s\n",status);
02381       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02382       ast_cli(fd,"\n");
02383       peer_unref(peer);
02384    } else {
02385       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02386       ast_cli(fd,"\n");
02387    }
02388 
02389    return RESULT_SUCCESS;
02390 }
02391 
02392 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02393 {
02394    int which = 0;
02395    struct iax2_peer *peer;
02396    char *res = NULL;
02397    int wordlen = strlen(word);
02398    struct ao2_iterator i;
02399 
02400    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02401    if (pos != 3)
02402       return NULL;
02403 
02404    i = ao2_iterator_init(peers, 0);
02405    while ((peer = ao2_iterator_next(&i))) {
02406       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02407          res = ast_strdup(peer->name);
02408          peer_unref(peer);
02409          break;
02410       }
02411       peer_unref(peer);
02412    }
02413 
02414    return res;
02415 }
02416 
02417 static int iax2_show_stats(int fd, int argc, char *argv[])
02418 {
02419    struct iax_frame *cur;
02420    int cnt = 0, dead=0, final=0;
02421 
02422    if (argc != 3)
02423       return RESULT_SHOWUSAGE;
02424 
02425    AST_LIST_LOCK(&iaxq.queue);
02426    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02427       if (cur->retries < 0)
02428          dead++;
02429       if (cur->final)
02430          final++;
02431       cnt++;
02432    }
02433    AST_LIST_UNLOCK(&iaxq.queue);
02434 
02435    ast_cli(fd, "    IAX Statistics\n");
02436    ast_cli(fd, "---------------------\n");
02437    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02438    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02439    
02440    return RESULT_SUCCESS;
02441 }
02442 
02443 static int iax2_show_cache(int fd, int argc, char *argv[])
02444 {
02445    struct iax2_dpcache *dp;
02446    char tmp[1024], *pc;
02447    int s;
02448    int x,y;
02449    struct timeval tv;
02450    gettimeofday(&tv, NULL);
02451    ast_mutex_lock(&dpcache_lock);
02452    dp = dpcache;
02453    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02454    while(dp) {
02455       s = dp->expiry.tv_sec - tv.tv_sec;
02456       tmp[0] = '\0';
02457       if (dp->flags & CACHE_FLAG_EXISTS)
02458          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02459       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02460          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02461       if (dp->flags & CACHE_FLAG_CANEXIST)
02462          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02463       if (dp->flags & CACHE_FLAG_PENDING)
02464          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02465       if (dp->flags & CACHE_FLAG_TIMEOUT)
02466          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02467       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02468          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02469       if (dp->flags & CACHE_FLAG_MATCHMORE)
02470          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02471       if (dp->flags & CACHE_FLAG_UNKNOWN)
02472          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02473       /* Trim trailing pipe */
02474       if (!ast_strlen_zero(tmp))
02475          tmp[strlen(tmp) - 1] = '\0';
02476       else
02477          ast_copy_string(tmp, "(none)", sizeof(tmp));
02478       y=0;
02479       pc = strchr(dp->peercontext, '@');
02480       if (!pc)
02481          pc = dp->peercontext;
02482       else
02483          pc++;
02484       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02485          if (dp->waiters[x] > -1)
02486             y++;
02487       if (s > 0)
02488          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02489       else
02490          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02491       dp = dp->next;
02492    }
02493    ast_mutex_unlock(&dpcache_lock);
02494    return RESULT_SUCCESS;
02495 }
02496 
02497 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02498 
02499 static void unwrap_timestamp(struct iax_frame *fr)
02500 {
02501    int x;
02502 
02503    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02504       x = fr->ts - iaxs[fr->callno]->last;
02505       if (x < -50000) {
02506          /* Sudden big jump backwards in timestamp:
02507             What likely happened here is that miniframe timestamp has circled but we haven't
02508             gotten the update from the main packet.  We'll just pretend that we did, and
02509             update the timestamp appropriately. */
02510          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02511          if (option_debug && iaxdebug)
02512             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02513       }
02514       if (x > 50000) {
02515          /* Sudden apparent big jump forwards in timestamp:
02516             What's likely happened is this is an old miniframe belonging to the previous
02517             top-16-bit timestamp that has turned up out of order.
02518             Adjust the timestamp appropriately. */
02519          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02520          if (option_debug && iaxdebug)
02521             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02522       }
02523    }
02524 }
02525 
02526 static int get_from_jb(const void *p);
02527 
02528 static void update_jbsched(struct chan_iax2_pvt *pvt)
02529 {
02530    int when;
02531    
02532    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02533    
02534    when = jb_next(pvt->jb) - when;
02535 
02536    AST_SCHED_DEL(sched, pvt->jbid);
02537 
02538    if(when <= 0) {
02539       /* XXX should really just empty until when > 0.. */
02540       when = 1;
02541    }
02542    
02543    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02544 }
02545 
02546 static void __get_from_jb(const void *p) 
02547 {
02548    int callno = PTR_TO_CALLNO(p);
02549    struct chan_iax2_pvt *pvt = NULL;
02550    struct iax_frame *fr;
02551    jb_frame frame;
02552    int ret;
02553    long now;
02554    long next;
02555    struct timeval tv;
02556    
02557    /* Make sure we have a valid private structure before going on */
02558    ast_mutex_lock(&iaxsl[callno]);
02559    pvt = iaxs[callno];
02560    if (!pvt) {
02561       /* No go! */
02562       ast_mutex_unlock(&iaxsl[callno]);
02563       return;
02564    }
02565 
02566    pvt->jbid = -1;
02567    
02568    gettimeofday(&tv,NULL);
02569    /* round up a millisecond since ast_sched_runq does; */
02570    /* prevents us from spinning while waiting for our now */
02571    /* to catch up with runq's now */
02572    tv.tv_usec += 1000;
02573    
02574    now = ast_tvdiff_ms(tv, pvt->rxcore);
02575    
02576    if(now >= (next = jb_next(pvt->jb))) {
02577       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02578       switch(ret) {
02579       case JB_OK:
02580          fr = frame.data;
02581          __do_deliver(fr);
02582          /* __do_deliver() can cause the call to disappear */
02583          pvt = iaxs[callno];
02584          break;
02585       case JB_INTERP:
02586       {
02587          struct ast_frame af = { 0, };
02588          
02589          /* create an interpolation frame */
02590          af.frametype = AST_FRAME_VOICE;
02591          af.subclass = pvt->voiceformat;
02592          af.samples  = frame.ms * 8;
02593          af.src  = "IAX2 JB interpolation";
02594          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02595          af.offset = AST_FRIENDLY_OFFSET;
02596          
02597          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02598           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02599          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02600             iax2_queue_frame(callno, &af);
02601             /* iax2_queue_frame() could cause the call to disappear */
02602             pvt = iaxs[callno];
02603          }
02604       }
02605          break;
02606       case JB_DROP:
02607          iax2_frame_free(frame.data);
02608          break;
02609       case JB_NOFRAME:
02610       case JB_EMPTY:
02611          /* do nothing */
02612          break;
02613       default:
02614          /* shouldn't happen */
02615          break;
02616       }
02617    }
02618    if (pvt)
02619       update_jbsched(pvt);
02620    ast_mutex_unlock(&iaxsl[callno]);
02621 }
02622 
02623 static int get_from_jb(const void *data)
02624 {
02625 #ifdef SCHED_MULTITHREADED
02626    if (schedule_action(__get_from_jb, data))
02627 #endif      
02628       __get_from_jb(data);
02629    return 0;
02630 }
02631 
02632 /*!
02633  * \note This function assumes fr->callno is locked
02634  *
02635  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02636  * was valid before calling it, it may no longer be valid after calling it.
02637  */
02638 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02639 {
02640    int type, len;
02641    int ret;
02642    int needfree = 0;
02643    struct ast_channel *owner = NULL;
02644    struct ast_channel *bridge = NULL;
02645    
02646    /* Attempt to recover wrapped timestamps */
02647    unwrap_timestamp(fr);
02648 
02649    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02650    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02651       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02652    else {
02653 #if 0
02654       if (option_debug)
02655          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02656 #endif
02657       fr->af.delivery = ast_tv(0,0);
02658    }
02659 
02660    type = JB_TYPE_CONTROL;
02661    len = 0;
02662 
02663    if(fr->af.frametype == AST_FRAME_VOICE) {
02664       type = JB_TYPE_VOICE;
02665       len = ast_codec_get_samples(&fr->af) / 8;
02666    } else if(fr->af.frametype == AST_FRAME_CNG) {
02667       type = JB_TYPE_SILENCE;
02668    }
02669 
02670    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02671       if (tsout)
02672          *tsout = fr->ts;
02673       __do_deliver(fr);
02674       return -1;
02675    }
02676 
02677    if ((owner = iaxs[fr->callno]->owner))
02678       bridge = ast_bridged_channel(owner);
02679 
02680    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02681     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02682    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02683       jb_frame frame;
02684 
02685       /* deliver any frames in the jb */
02686       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02687          __do_deliver(frame.data);
02688          /* __do_deliver() can make the call disappear */
02689          if (!iaxs[fr->callno])
02690             return -1;
02691       }
02692 
02693       jb_reset(iaxs[fr->callno]->jb);
02694 
02695       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02696 
02697       /* deliver this frame now */
02698       if (tsout)
02699          *tsout = fr->ts;
02700       __do_deliver(fr);
02701       return -1;
02702    }
02703 
02704    /* insert into jitterbuffer */
02705    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02706    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02707          calc_rxstamp(iaxs[fr->callno],fr->ts));
02708    if (ret == JB_DROP) {
02709       needfree++;
02710    } else if (ret == JB_SCHED) {
02711       update_jbsched(iaxs[fr->callno]);
02712    }
02713    if (tsout)
02714       *tsout = fr->ts;
02715    if (needfree) {
02716       /* Free our iax frame */
02717       iax2_frame_free(fr);
02718       return -1;
02719    }
02720    return 0;
02721 }
02722 
02723 static int iax2_transmit(struct iax_frame *fr)
02724 {
02725    /* Lock the queue and place this packet at the end */
02726    /* By setting this to 0, the network thread will send it for us, and
02727       queue retransmission if necessary */
02728    fr->sentyet = 0;
02729    AST_LIST_LOCK(&iaxq.queue);
02730    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02731    iaxq.count++;
02732    AST_LIST_UNLOCK(&iaxq.queue);
02733    /* Wake up the network and scheduler thread */
02734    if (netthreadid != AST_PTHREADT_NULL)
02735       pthread_kill(netthreadid, SIGURG);
02736    signal_condition(&sched_lock, &sched_cond);
02737    return 0;
02738 }
02739 
02740 
02741 
02742 static int iax2_digit_begin(struct ast_channel *c, char digit)
02743 {
02744    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02745 }
02746 
02747 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02748 {
02749    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02750 }
02751 
02752 static int iax2_sendtext(struct ast_channel *c, const char *text)
02753 {
02754    
02755    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02756       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02757 }
02758 
02759 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02760 {
02761    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02762 }
02763 
02764 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02765 {
02766    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02767 }
02768 
02769 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02770 {
02771    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02772    ast_mutex_lock(&iaxsl[callno]);
02773    if (iaxs[callno])
02774       iaxs[callno]->owner = newchan;
02775    else
02776       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02777    ast_mutex_unlock(&iaxsl[callno]);
02778    return 0;
02779 }
02780 
02781 /*!
02782  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02783  *       so do not call this with a pvt lock held.
02784  */
02785 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02786 {
02787    struct ast_variable *var = NULL;
02788    struct ast_variable *tmp;
02789    struct iax2_peer *peer=NULL;
02790    time_t regseconds = 0, nowtime;
02791    int dynamic=0;
02792 
02793    if (peername) {
02794       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02795       if (!var && sin)
02796          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02797    } else if (sin) {
02798       char porta[25];
02799       sprintf(porta, "%d", ntohs(sin->sin_port));
02800       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02801       if (var) {
02802          /* We'll need the peer name in order to build the structure! */
02803          for (tmp = var; tmp; tmp = tmp->next) {
02804             if (!strcasecmp(tmp->name, "name"))
02805                peername = tmp->value;
02806          }
02807       }
02808    }
02809    if (!var && peername) { /* Last ditch effort */
02810       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02811       /*!\note
02812        * If this one loaded something, then we need to ensure that the host
02813        * field matched.  The only reason why we can't have this as a criteria
02814        * is because we only have the IP address and the host field might be
02815        * set as a name (and the reverse PTR might not match).
02816        */
02817       if (var && sin) {
02818          for (tmp = var; tmp; tmp = tmp->next) {
02819             if (!strcasecmp(tmp->name, "host")) {
02820                struct ast_hostent ahp;
02821                struct hostent *hp;
02822                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02823                   /* No match */
02824                   ast_variables_destroy(var);
02825                   var = NULL;
02826                }
02827                break;
02828             }
02829          }
02830       }
02831    }
02832    if (!var)
02833       return NULL;
02834 
02835    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02836    
02837    if (!peer) {
02838       ast_variables_destroy(var);
02839       return NULL;
02840    }
02841 
02842    for (tmp = var; tmp; tmp = tmp->next) {
02843       /* Make sure it's not a user only... */
02844       if (!strcasecmp(tmp->name, "type")) {
02845          if (strcasecmp(tmp->value, "friend") &&
02846              strcasecmp(tmp->value, "peer")) {
02847             /* Whoops, we weren't supposed to exist! */
02848             peer = peer_unref(peer);
02849             break;
02850          } 
02851       } else if (!strcasecmp(tmp->name, "regseconds")) {
02852          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02853       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02854          inet_aton(tmp->value, &(peer->addr.sin_addr));
02855       } else if (!strcasecmp(tmp->name, "port")) {
02856          peer->addr.sin_port = htons(atoi(tmp->value));
02857       } else if (!strcasecmp(tmp->name, "host")) {
02858          if (!strcasecmp(tmp->value, "dynamic"))
02859             dynamic = 1;
02860       }
02861    }
02862 
02863    ast_variables_destroy(var);
02864 
02865    if (!peer)
02866       return NULL;
02867 
02868    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02869       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02870       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02871          if (peer->expire > -1) {
02872             if (!ast_sched_del(sched, peer->expire)) {
02873                peer->expire = -1;
02874                peer_unref(peer);
02875             }
02876          }
02877          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02878          if (peer->expire == -1)
02879             peer_unref(peer);
02880       }
02881       ao2_link(peers, peer);
02882       if (ast_test_flag(peer, IAX_DYNAMIC))
02883          reg_source_db(peer);
02884    } else {
02885       ast_set_flag(peer, IAX_TEMPONLY);   
02886    }
02887 
02888    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02889       time(&nowtime);
02890       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02891          memset(&peer->addr, 0, sizeof(peer->addr));
02892          realtime_update_peer(peer->name, &peer->addr, 0);
02893          if (option_debug)
02894             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02895                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02896       }
02897       else {
02898          if (option_debug)
02899             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02900                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02901       }
02902    }
02903 
02904    return peer;
02905 }
02906 
02907 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02908 {
02909    struct ast_variable *var;
02910    struct ast_variable *tmp;
02911    struct iax2_user *user=NULL;
02912 
02913    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02914    if (!var)
02915       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02916    if (!var && sin) {
02917       char porta[6];
02918       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02919       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02920       if (!var)
02921          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02922    }
02923    if (!var) { /* Last ditch effort */
02924       var = ast_load_realtime("iaxusers", "name", username, NULL);
02925       /*!\note
02926        * If this one loaded something, then we need to ensure that the host
02927        * field matched.  The only reason why we can't have this as a criteria
02928        * is because we only have the IP address and the host field might be
02929        * set as a name (and the reverse PTR might not match).
02930        */
02931       if (var) {
02932          for (tmp = var; tmp; tmp = tmp->next) {
02933             if (!strcasecmp(tmp->name, "host")) {
02934                struct ast_hostent ahp;
02935                struct hostent *hp;
02936                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02937                   /* No match */
02938                   ast_variables_destroy(var);
02939                   var = NULL;
02940                }
02941                break;
02942             }
02943          }
02944       }
02945    }
02946    if (!var)
02947       return NULL;
02948 
02949    tmp = var;
02950    while(tmp) {
02951       /* Make sure it's not a peer only... */
02952       if (!strcasecmp(tmp->name, "type")) {
02953          if (strcasecmp(tmp->value, "friend") &&
02954              strcasecmp(tmp->value, "user")) {
02955             return NULL;
02956          } 
02957       }
02958       tmp = tmp->next;
02959    }
02960 
02961    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02962 
02963    ast_variables_destroy(var);
02964 
02965    if (!user)
02966       return NULL;
02967 
02968    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02969       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02970       ao2_link(users, user);
02971    } else {
02972       ast_set_flag(user, IAX_TEMPONLY);   
02973    }
02974 
02975    return user;
02976 }
02977 
02978 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02979 {
02980    char port[10];
02981    char regseconds[20];
02982    
02983    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02984    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02985    ast_update_realtime("iaxpeers", "name", peername, 
02986       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02987       "regseconds", regseconds, NULL);
02988 }
02989 
02990 struct create_addr_info {
02991    int capability;
02992    unsigned int flags;
02993    int maxtime;
02994    int encmethods;
02995    int found;
02996    int sockfd;
02997    int adsi;
02998    char username[80];
02999    char secret[80];
03000    char outkey[80];
03001    char timezone[80];
03002    char prefs[32];
03003    char context[AST_MAX_CONTEXT];
03004    char peercontext[AST_MAX_CONTEXT];
03005    char mohinterpret[MAX_MUSICCLASS];
03006    char mohsuggest[MAX_MUSICCLASS];
03007 };
03008 
03009 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03010 {
03011    struct ast_hostent ahp;
03012    struct hostent *hp;
03013    struct iax2_peer *peer;
03014    int res = -1;
03015    struct ast_codec_pref ourprefs;
03016 
03017    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03018    cai->sockfd = defaultsockfd;
03019    cai->maxtime = 0;
03020    sin->sin_family = AF_INET;
03021 
03022    if (!(peer = find_peer(peername, 1))) {
03023       cai->found = 0;
03024 
03025       hp = ast_gethostbyname(peername, &ahp);
03026       if (hp) {
03027          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03028          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03029          /* use global iax prefs for unknown peer/user */
03030          /* But move the calling channel's native codec to the top of the preference list */
03031          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03032          if (c)
03033             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03034          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03035          return 0;
03036       } else {
03037          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03038          return -1;
03039       }
03040    }
03041 
03042    cai->found = 1;
03043    
03044    /* if the peer has no address (current or default), return failure */
03045    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03046       goto return_unref;
03047 
03048    /* if the peer is being monitored and is currently unreachable, return failure */
03049    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03050       goto return_unref;
03051 
03052    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03053    cai->maxtime = peer->maxms;
03054    cai->capability = peer->capability;
03055    cai->encmethods = peer->encmethods;
03056    cai->sockfd = peer->sockfd;
03057    cai->adsi = peer->adsi;
03058    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03059    /* Move the calling channel's native codec to the top of the preference list */
03060    if (c) {
03061       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03062       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03063    }
03064    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03065    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03066    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03067    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03068    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03069    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03070    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03071    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03072    if (ast_strlen_zero(peer->dbsecret)) {
03073       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03074    } else {
03075       char *family;
03076       char *key = NULL;
03077 
03078       family = ast_strdupa(peer->dbsecret);
03079       key = strchr(family, '/');
03080       if (key)
03081          *key++ = '\0';
03082       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03083          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03084          goto return_unref;
03085       }
03086    }
03087 
03088    if (peer->addr.sin_addr.s_addr) {
03089       sin->sin_addr = peer->addr.sin_addr;
03090       sin->sin_port = peer->addr.sin_port;
03091    } else {
03092       sin->sin_addr = peer->defaddr.sin_addr;
03093       sin->sin_port = peer->defaddr.sin_port;
03094    }
03095 
03096    res = 0;
03097 
03098 return_unref:
03099    peer_unref(peer);
03100 
03101    return res;
03102 }
03103 
03104 static void __auto_congest(const void *nothing)
03105 {
03106    int callno = PTR_TO_CALLNO(nothing);
03107    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03108    ast_mutex_lock(&iaxsl[callno]);
03109    if (iaxs[callno]) {
03110       iaxs[callno]->initid = -1;
03111       iax2_queue_frame(callno, &f);
03112       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03113    }
03114    ast_mutex_unlock(&iaxsl[callno]);
03115 }
03116 
03117 static int auto_congest(const void *data)
03118 {
03119 #ifdef SCHED_MULTITHREADED
03120    if (schedule_action(__auto_congest, data))
03121 #endif      
03122       __auto_congest(data);
03123    return 0;
03124 }
03125 
03126 static unsigned int iax2_datetime(const char *tz)
03127 {
03128    time_t t;
03129    struct tm tm;
03130    unsigned int tmp;
03131    time(&t);
03132    if (!ast_strlen_zero(tz))
03133       ast_localtime(&t, &tm, tz);
03134    else
03135       ast_localtime(&t, &tm, NULL);
03136    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03137    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03138    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03139    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03140    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03141    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03142    return tmp;
03143 }
03144 
03145 struct parsed_dial_string {
03146    char *username;
03147    char *password;
03148    char *key;
03149    char *peer;
03150    char *port;
03151    char *exten;
03152    char *context;
03153    char *options;
03154 };
03155 
03156 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03157 {
03158    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03159       .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03160       .csub = compress_subclass(command) };
03161 
03162    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03163 }
03164 
03165 /*!
03166  * \brief Parses an IAX dial string into its component parts.
03167  * \param data the string to be parsed
03168  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03169  * \return nothing
03170  *
03171  * This function parses the string and fills the structure
03172  * with pointers to its component parts. The input string
03173  * will be modified.
03174  *
03175  * \note This function supports both plaintext passwords and RSA
03176  * key names; if the password string is formatted as '[keyname]',
03177  * then the keyname will be placed into the key field, and the
03178  * password field will be set to NULL.
03179  *
03180  * \note The dial string format is:
03181  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03182  */
03183 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03184 {
03185    if (ast_strlen_zero(data))
03186       return;
03187 
03188    pds->peer = strsep(&data, "/");
03189    pds->exten = strsep(&data, "/");
03190    pds->options = data;
03191 
03192    if (pds->exten) {
03193       data = pds->exten;
03194       pds->exten = strsep(&data, "@");
03195       pds->context = data;
03196    }
03197 
03198    if (strchr(pds->peer, '@')) {
03199       data = pds->peer;
03200       pds->username = strsep(&data, "@");
03201       pds->peer = data;
03202    }
03203 
03204    if (pds->username) {
03205       data = pds->username;
03206       pds->username = strsep(&data, ":");
03207       pds->password = data;
03208    }
03209 
03210    data = pds->peer;
03211    pds->peer = strsep(&data, ":");
03212    pds->port = data;
03213 
03214    /* check for a key name wrapped in [] in the secret position, if found,
03215       move it to the key field instead
03216    */
03217    if (pds->password && (pds->password[0] == '[')) {
03218       pds->key = ast_strip_quoted(pds->password, "[", "]");
03219       pds->password = NULL;
03220    }
03221 }
03222 
03223 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03224 {
03225    struct sockaddr_in sin;
03226    char *l=NULL, *n=NULL, *tmpstr;
03227    struct iax_ie_data ied;
03228    char *defaultrdest = "s";
03229    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03230    struct parsed_dial_string pds;
03231    struct create_addr_info cai;
03232 
03233    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03234       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03235       return -1;
03236    }
03237 
03238    memset(&cai, 0, sizeof(cai));
03239    cai.encmethods = iax2_encryption;
03240 
03241    memset(&pds, 0, sizeof(pds));
03242    tmpstr = ast_strdupa(dest);
03243    parse_dial_string(tmpstr, &pds);
03244 
03245    if (ast_strlen_zero(pds.peer)) {
03246       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03247       return -1;
03248    }
03249 
03250    if (!pds.exten) {
03251       pds.exten = defaultrdest;
03252    }
03253 
03254    if (create_addr(pds.peer, c, &sin, &cai)) {
03255       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03256       return -1;
03257    }
03258 
03259    if (!pds.username && !ast_strlen_zero(cai.username))
03260       pds.username = cai.username;
03261    if (!pds.password && !ast_strlen_zero(cai.secret))
03262       pds.password = cai.secret;
03263    if (!pds.key && !ast_strlen_zero(cai.outkey))
03264       pds.key = cai.outkey;
03265    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03266       pds.context = cai.peercontext;
03267 
03268    /* Keep track of the context for outgoing calls too */
03269    ast_copy_string(c->context, cai.context, sizeof(c->context));
03270 
03271    if (pds.port)
03272       sin.sin_port = htons(atoi(pds.port));
03273 
03274    l = c->cid.cid_num;
03275    n = c->cid.cid_name;
03276 
03277    /* Now build request */ 
03278    memset(&ied, 0, sizeof(ied));
03279 
03280    /* On new call, first IE MUST be IAX version of caller */
03281    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03282    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03283    if (pds.options && strchr(pds.options, 'a')) {
03284       /* Request auto answer */
03285       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03286    }
03287 
03288    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03289 
03290    if (l) {
03291       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03292       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03293    } else {
03294       if (n)
03295          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03296       else
03297          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03298    }
03299 
03300    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03301    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03302 
03303    if (n)
03304       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03305    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03306       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03307 
03308    if (!ast_strlen_zero(c->language))
03309       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03310    if (!ast_strlen_zero(c->cid.cid_dnid))
03311       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03312    if (!ast_strlen_zero(c->cid.cid_rdnis))
03313       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03314 
03315    if (pds.context)
03316       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03317 
03318    if (pds.username)
03319       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03320 
03321    if (cai.encmethods)
03322       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03323 
03324    ast_mutex_lock(&iaxsl[callno]);
03325 
03326    if (!ast_strlen_zero(c->context))
03327       ast_string_field_set(iaxs[callno], context, c->context);
03328 
03329    if (pds.username)
03330       ast_string_field_set(iaxs[callno], username, pds.username);
03331 
03332    iaxs[callno]->encmethods = cai.encmethods;
03333 
03334    iaxs[callno]->adsi = cai.adsi;
03335    
03336    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03337    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03338 
03339    if (pds.key)
03340       ast_string_field_set(iaxs[callno], outkey, pds.key);
03341    if (pds.password)
03342       ast_string_field_set(iaxs[callno], secret, pds.password);
03343 
03344    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03345    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03346    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03347    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03348 
03349    if (iaxs[callno]->maxtime) {
03350       /* Initialize pingtime and auto-congest time */
03351       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03352       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03353    } else if (autokill) {
03354       iaxs[callno]->pingtime = autokill / 2;
03355       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03356    }
03357 
03358    /* send the command using the appropriate socket for this peer */
03359    iaxs[callno]->sockfd = cai.sockfd;
03360 
03361    /* Transmit the string in a "NEW" request */
03362    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03363 
03364    ast_mutex_unlock(&iaxsl[callno]);
03365    ast_setstate(c, AST_STATE_RINGING);
03366    
03367    return 0;
03368 }
03369 
03370 static int iax2_hangup(struct ast_channel *c) 
03371 {
03372    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03373    int alreadygone;
03374    struct iax_ie_data ied;
03375    memset(&ied, 0, sizeof(ied));
03376    ast_mutex_lock(&iaxsl[callno]);
03377    if (callno && iaxs[callno]) {
03378       if (option_debug)
03379          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03380       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03381       /* Send the hangup unless we have had a transmission error or are already gone */
03382       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03383       if (!iaxs[callno]->error && !alreadygone) {
03384          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03385          if (!iaxs[callno]) {
03386             ast_mutex_unlock(&iaxsl[callno]);
03387             return 0;
03388          }
03389       }
03390       /* Explicitly predestroy it */
03391       iax2_predestroy(callno);
03392       /* If we were already gone to begin with, destroy us now */
03393       if (alreadygone && iaxs[callno]) {
03394          if (option_debug)
03395             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03396          iax2_destroy(callno);
03397       }
03398    }
03399    ast_mutex_unlock(&iaxsl[callno]);
03400    if (option_verbose > 2) 
03401       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03402    return 0;
03403 }
03404 
03405 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03406 {
03407    struct ast_option_header *h;
03408    int res;
03409 
03410    switch (option) {
03411    case AST_OPTION_TXGAIN:
03412    case AST_OPTION_RXGAIN:
03413       /* these two cannot be sent, because they require a result */
03414       errno = ENOSYS;
03415       return -1;
03416    default:
03417       if (!(h = ast_malloc(datalen + sizeof(*h))))
03418          return -1;
03419 
03420       h->flag = AST_OPTION_FLAG_REQUEST;
03421       h->option = htons(option);
03422       memcpy(h->data, data, datalen);
03423       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03424                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03425                  datalen + sizeof(*h), -1);
03426       free(h);
03427       return res;
03428    }
03429 }
03430 
03431 static struct ast_frame *iax2_read(struct ast_channel *c) 
03432 {
03433    if (option_verbose > 3)
03434        ast_log(LOG_NOTICE, "I should never be called!\n");
03435    return &ast_null_frame;
03436 }
03437 
03438 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03439 {
03440    int res;
03441    struct iax_ie_data ied0;
03442    struct iax_ie_data ied1;
03443    unsigned int transferid = (unsigned int)ast_random();
03444    memset(&ied0, 0, sizeof(ied0));
03445    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03446    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03447    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03448 
03449    memset(&ied1, 0, sizeof(ied1));
03450    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03451    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03452    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03453    
03454    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03455    if (res)
03456       return -1;
03457    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03458    if (res)
03459       return -1;
03460    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03461    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03462    return 0;
03463 }
03464 
03465 static void lock_both(unsigned short callno0, unsigned short callno1)
03466 {
03467    ast_mutex_lock(&iaxsl[callno0]);
03468    while (ast_mutex_trylock(&iaxsl[callno1])) {
03469       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03470    }
03471 }
03472 
03473 static void unlock_both(unsigned short callno0, unsigned short callno1)
03474 {
03475    ast_mutex_unlock(&iaxsl[callno1]);
03476    ast_mutex_unlock(&iaxsl[callno0]);
03477 }
03478 
03479 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)
03480 {
03481    struct ast_channel *cs[3];
03482    struct ast_channel *who, *other;
03483    int to = -1;
03484    int res = -1;
03485    int transferstarted=0;
03486    struct ast_frame *f;
03487    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03488    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03489    struct timeval waittimer = {0, 0}, tv;
03490 
03491    lock_both(callno0, callno1);
03492    if (!iaxs[callno0] || !iaxs[callno1]) {
03493       unlock_both(callno0, callno1);
03494       return AST_BRIDGE_FAILED;
03495    }
03496    /* Put them in native bridge mode */
03497    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03498       iaxs[callno0]->bridgecallno = callno1;
03499       iaxs[callno1]->bridgecallno = callno0;
03500    }
03501    unlock_both(callno0, callno1);
03502 
03503    /* If not, try to bridge until we can execute a transfer, if we can */
03504    cs[0] = c0;
03505    cs[1] = c1;
03506    for (/* ever */;;) {
03507       /* Check in case we got masqueraded into */
03508       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03509          if (option_verbose > 2)
03510             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03511          /* Remove from native mode */
03512          if (c0->tech == &iax2_tech) {
03513             ast_mutex_lock(&iaxsl[callno0]);
03514             iaxs[callno0]->bridgecallno = 0;
03515             ast_mutex_unlock(&iaxsl[callno0]);
03516          }
03517          if (c1->tech == &iax2_tech) {
03518             ast_mutex_lock(&iaxsl[callno1]);
03519             iaxs[callno1]->bridgecallno = 0;
03520             ast_mutex_unlock(&iaxsl[callno1]);
03521          }
03522          return AST_BRIDGE_FAILED_NOWARN;
03523       }
03524       if (c0->nativeformats != c1->nativeformats) {
03525          if (option_verbose > 2) {
03526             char buf0[255];
03527             char buf1[255];
03528             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03529             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03530             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03531          }
03532          /* Remove from native mode */
03533          lock_both(callno0, callno1);
03534          if (iaxs[callno0])
03535             iaxs[callno0]->bridgecallno = 0;
03536          if (iaxs[callno1])
03537             iaxs[callno1]->bridgecallno = 0;
03538          unlock_both(callno0, callno1);
03539          return AST_BRIDGE_FAILED_NOWARN;
03540       }
03541       /* check if transfered and if we really want native bridging */
03542       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03543          /* Try the transfer */
03544          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03545                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03546             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03547          transferstarted = 1;
03548       }
03549       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03550          /* Call has been transferred.  We're no longer involved */
03551          gettimeofday(&tv, NULL);
03552          if (ast_tvzero(waittimer)) {
03553             waittimer = tv;
03554          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03555             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03556             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03557             *fo = NULL;
03558             *rc = c0;
03559             res = AST_BRIDGE_COMPLETE;
03560             break;
03561          }
03562       }
03563       to = 1000;
03564       who = ast_waitfor_n(cs, 2, &to);
03565       if (timeoutms > -1) {
03566          timeoutms -= (1000 - to);
03567          if (timeoutms < 0)
03568             timeoutms = 0;
03569       }
03570       if (!who) {
03571          if (!timeoutms) {
03572             res = AST_BRIDGE_RETRY;
03573             break;
03574          }
03575          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03576             res = AST_BRIDGE_FAILED;
03577             break;
03578          }
03579          continue;
03580       }
03581       f = ast_read(who);
03582       if (!f) {
03583          *fo = NULL;
03584          *rc = who;
03585          res = AST_BRIDGE_COMPLETE;
03586          break;
03587       }
03588       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03589          *fo = f;
03590          *rc = who;
03591          res =  AST_BRIDGE_COMPLETE;
03592          break;
03593       }
03594       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03595       if ((f->frametype == AST_FRAME_VOICE) ||
03596           (f->frametype == AST_FRAME_TEXT) ||
03597           (f->frametype == AST_FRAME_VIDEO) || 
03598           (f->frametype == AST_FRAME_IMAGE) ||
03599           (f->frametype == AST_FRAME_DTMF)) {
03600          /* monitored dtmf take out of the bridge.
03601           * check if we monitor the specific source.
03602           */
03603          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03604          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03605             *rc = who;
03606             *fo = f;
03607             res = AST_BRIDGE_COMPLETE;
03608             /* Remove from native mode */
03609             break;
03610          }
03611          /* everything else goes to the other side */
03612          ast_write(other, f);
03613       }
03614       ast_frfree(f);
03615       /* Swap who gets priority */
03616       cs[2] = cs[0];
03617       cs[0] = cs[1];
03618       cs[1] = cs[2];
03619    }
03620    lock_both(callno0, callno1);
03621    if(iaxs[callno0])
03622       iaxs[callno0]->bridgecallno = 0;
03623    if(iaxs[callno1])
03624       iaxs[callno1]->bridgecallno = 0;
03625    unlock_both(callno0, callno1);
03626    return res;
03627 }
03628 
03629 static int iax2_answer(struct ast_channel *c)
03630 {
03631    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03632    if (option_debug)
03633       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03634    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03635 }
03636 
03637 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03638 {
03639    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03640    struct chan_iax2_pvt *pvt;
03641    int res = 0;
03642 
03643    if (option_debug && iaxdebug)
03644       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03645 
03646    ast_mutex_lock(&iaxsl[callno]);
03647    pvt = iaxs[callno];
03648 
03649    if (!pvt->peercallno) {
03650       /* We don't know the remote side's call number, yet.  :( */
03651       int count = 10;
03652       while (count-- && pvt && !pvt->peercallno) {
03653          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03654          pvt = iaxs[callno];
03655       }
03656       if (!pvt->peercallno) {
03657          res = -1;
03658          goto done;
03659       }
03660    }
03661 
03662    switch (condition) {
03663    case AST_CONTROL_HOLD:
03664       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03665          ast_moh_start(c, data, pvt->mohinterpret);
03666          goto done;
03667       }
03668       break;
03669    case AST_CONTROL_UNHOLD:
03670       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03671          ast_moh_stop(c);
03672          goto done;
03673       }
03674    }
03675 
03676    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03677 
03678 done:
03679    ast_mutex_unlock(&iaxsl[callno]);
03680 
03681    return res;
03682 }
03683    
03684 static int iax2_transfer(struct ast_channel *c, const char *dest)
03685 {
03686    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03687    struct iax_ie_data ied;
03688    char tmp[256], *context;
03689    ast_copy_string(tmp, dest, sizeof(tmp));
03690    context = strchr(tmp, '@');
03691    if (context) {
03692       *context = '\0';
03693       context++;
03694    }
03695    memset(&ied, 0, sizeof(ied));
03696    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03697    if (context)
03698       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03699    if (option_debug)
03700       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03701    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03702 }
03703    
03704 static int iax2_getpeertrunk(struct sockaddr_in sin)
03705 {
03706    struct iax2_peer *peer;
03707    int res = 0;
03708    struct ao2_iterator i;
03709 
03710    i = ao2_iterator_init(peers, 0);
03711    while ((peer = ao2_iterator_next(&i))) {
03712       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03713           (peer->addr.sin_port == sin.sin_port)) {
03714          res = ast_test_flag(peer, IAX_TRUNK);
03715          peer_unref(peer);
03716          break;
03717       }
03718       peer_unref(peer);
03719    }
03720 
03721    return res;
03722 }
03723 
03724 /*! \brief  Create new call, interface with the PBX core */
03725 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03726 {
03727    struct ast_channel *tmp;
03728    struct chan_iax2_pvt *i;
03729    struct ast_variable *v = NULL;
03730 
03731    if (!(i = iaxs[callno])) {
03732       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03733       return NULL;
03734    }
03735 
03736    /* Don't hold call lock */
03737    ast_mutex_unlock(&iaxsl[callno]);
03738    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);
03739    ast_mutex_lock(&iaxsl[callno]);
03740    if (!iaxs[callno]) {
03741       if (tmp) {
03742          ast_channel_free(tmp);
03743       }
03744       ast_mutex_unlock(&iaxsl[callno]);
03745       return NULL;
03746    }
03747 
03748    if (!tmp)
03749       return NULL;
03750    tmp->tech = &iax2_tech;
03751    /* We can support any format by default, until we get restricted */
03752    tmp->nativeformats = capability;
03753    tmp->readformat = ast_best_codec(capability);
03754    tmp->writeformat = ast_best_codec(capability);
03755    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03756 
03757    /* Don't use ast_set_callerid() here because it will
03758     * generate a NewCallerID event before the NewChannel event */
03759    if (!ast_strlen_zero(i->ani))
03760       tmp->cid.cid_ani = ast_strdup(i->ani);
03761    else
03762       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03763    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03764    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03765    tmp->cid.cid_pres = i->calling_pres;
03766    tmp->cid.cid_ton = i->calling_ton;
03767    tmp->cid.cid_tns = i->calling_tns;
03768    if (!ast_strlen_zero(i->language))
03769       ast_string_field_set(tmp, language, i->language);
03770    if (!ast_strlen_zero(i->accountcode))
03771       ast_string_field_set(tmp, accountcode, i->accountcode);
03772    if (i->amaflags)
03773       tmp->amaflags = i->amaflags;
03774    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03775    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03776    if (i->adsi)
03777       tmp->adsicpe = i->peeradsicpe;
03778    else
03779       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03780    i->owner = tmp;
03781    i->capability = capability;
03782 
03783    for (v = i->vars ; v ; v = v->next)
03784       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03785 
03786    if (state != AST_STATE_DOWN) {
03787       if (ast_pbx_start(tmp)) {
03788          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03789          ast_hangup(tmp);
03790          i->owner = NULL;
03791          return NULL;
03792       }
03793    }
03794 
03795    ast_module_ref(ast_module_info->self);
03796    
03797    return tmp;
03798 }
03799 
03800 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03801 {
03802    unsigned long int mssincetx; /* unsigned to handle overflows */
03803    long int ms, pred;
03804 
03805    tpeer->trunkact = *tv;
03806    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03807    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03808       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03809       tpeer->txtrunktime = *tv;
03810       tpeer->lastsent = 999999;
03811    }
03812    /* Update last transmit time now */
03813    tpeer->lasttxtime = *tv;
03814    
03815    /* Calculate ms offset */
03816    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03817    /* Predict from last value */
03818    pred = tpeer->lastsent + sampms;
03819    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03820       ms = pred;
03821    
03822    /* We never send the same timestamp twice, so fudge a little if we must */
03823    if (ms == tpeer->lastsent)
03824       ms = tpeer->lastsent + 1;
03825    tpeer->lastsent = ms;
03826    return ms;
03827 }
03828 
03829 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03830 {
03831    long ms; /* NOT unsigned */
03832    if (ast_tvzero(iaxs[callno]->rxcore)) {
03833       /* Initialize rxcore time if appropriate */
03834       gettimeofday(&iaxs[callno]->rxcore, NULL);
03835       /* Round to nearest 20ms so traces look pretty */
03836       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03837    }
03838    /* Calculate difference between trunk and channel */
03839    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03840    /* Return as the sum of trunk time and the difference between trunk and real time */
03841    return ms + ts;
03842 }
03843 
03844 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03845 {
03846    int ms;
03847    int voice = 0;
03848    int genuine = 0;
03849    int adjust;
03850    struct timeval *delivery = NULL;
03851 
03852 
03853    /* What sort of frame do we have?: voice is self-explanatory
03854       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03855       non-genuine frames are CONTROL frames [ringing etc], DTMF
03856       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03857       the others need a timestamp slaved to the voice frames so that they go in sequence
03858    */
03859    if (f) {
03860       if (f->frametype == AST_FRAME_VOICE) {
03861          voice = 1;
03862          delivery = &f->delivery;
03863       } else if (f->frametype == AST_FRAME_IAX) {
03864          genuine = 1;
03865       } else if (f->frametype == AST_FRAME_CNG) {
03866          p->notsilenttx = 0;  
03867       }
03868    }
03869    if (ast_tvzero(p->offset)) {
03870       gettimeofday(&p->offset, NULL);
03871       /* Round to nearest 20ms for nice looking traces */
03872       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03873    }
03874    /* If the timestamp is specified, just send it as is */
03875    if (ts)
03876       return ts;
03877    /* If we have a time that the frame arrived, always use it to make our timestamp */
03878    if (delivery && !ast_tvzero(*delivery)) {
03879       ms = ast_tvdiff_ms(*delivery, p->offset);
03880       if (option_debug > 2 && iaxdebug)
03881          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03882    } else {
03883       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03884       if (ms < 0)
03885          ms = 0;
03886       if (voice) {
03887          /* On a voice frame, use predicted values if appropriate */
03888          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03889             /* Adjust our txcore, keeping voice and non-voice synchronized */
03890             /* AN EXPLANATION:
03891                When we send voice, we usually send "calculated" timestamps worked out
03892                on the basis of the number of samples sent. When we send other frames,
03893                we usually send timestamps worked out from the real clock.
03894                The problem is that they can tend to drift out of step because the 
03895                   source channel's clock and our clock may not be exactly at the same rate.
03896                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03897                for this call.  Moving it adjusts timestamps for non-voice frames.
03898                We make the adjustment in the style of a moving average.  Each time we
03899                adjust p->offset by 10% of the difference between our clock-derived
03900                timestamp and the predicted timestamp.  That's why you see "10000"
03901                below even though IAX2 timestamps are in milliseconds.
03902                The use of a moving average avoids offset moving too radically.
03903                Generally, "adjust" roams back and forth around 0, with offset hardly
03904                changing at all.  But if a consistent different starts to develop it
03905                will be eliminated over the course of 10 frames (200-300msecs) 
03906             */
03907             adjust = (ms - p->nextpred);
03908             if (adjust < 0)
03909                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03910             else if (adjust > 0)
03911                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03912 
03913             if (!p->nextpred) {
03914                p->nextpred = ms; /*f->samples / 8;*/
03915                if (p->nextpred <= p->lastsent)
03916                   p->nextpred = p->lastsent + 3;
03917             }
03918             ms = p->nextpred;
03919          } else {
03920                 /* in this case, just use the actual
03921             * time, since we're either way off
03922             * (shouldn't happen), or we're  ending a
03923             * silent period -- and seed the next
03924             * predicted time.  Also, round ms to the
03925             * next multiple of frame size (so our
03926             * silent periods are multiples of
03927             * frame size too) */
03928 
03929             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03930                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03931                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03932 
03933             if (f->samples >= 8) /* check to make sure we dont core dump */
03934             {
03935                int diff = ms % (f->samples / 8);
03936                if (diff)
03937                    ms += f->samples/8 - diff;
03938             }
03939 
03940             p->nextpred = ms;
03941             p->notsilenttx = 1;
03942          }
03943       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03944          /*
03945          * IAX2 draft 03 says that timestamps MUST be in order.
03946          * It does not say anything about several frames having the same timestamp
03947          * When transporting video, we can have a frame that spans multiple iax packets
03948          * (so called slices), so it would make sense to use the same timestamp for all of
03949          * them
03950          * We do want to make sure that frames don't go backwards though
03951          */
03952          if ( (unsigned int)ms < p->lastsent )
03953             ms = p->lastsent;
03954       } else {
03955          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03956             it's a genuine frame */
03957          if (genuine) {
03958             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03959             if (ms <= p->lastsent)
03960                ms = p->lastsent + 3;
03961          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03962             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03963             ms = p->lastsent + 3;
03964          }
03965       }
03966    }
03967    p->lastsent = ms;
03968    if (voice)
03969       p->nextpred = p->nextpred + f->samples / 8;
03970    return ms;
03971 }
03972 
03973 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03974 {
03975    /* Returns where in "receive time" we are.  That is, how many ms
03976       since we received (or would have received) the frame with timestamp 0 */
03977    int ms;
03978 #ifdef IAXTESTS
03979    int jit;
03980 #endif /* IAXTESTS */
03981    /* Setup rxcore if necessary */
03982    if (ast_tvzero(p->rxcore)) {
03983       p->rxcore = ast_tvnow();
03984       if (option_debug && iaxdebug)
03985          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03986                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03987       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03988 #if 1
03989       if (option_debug && iaxdebug)
03990          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03991                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03992 #endif
03993    }
03994 
03995    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03996 #ifdef IAXTESTS
03997    if (test_jit) {
03998       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03999          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04000          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04001             jit = -jit;
04002          ms += jit;
04003       }
04004    }
04005    if (test_late) {
04006       ms += test_late;
04007       test_late = 0;
04008    }
04009 #endif /* IAXTESTS */
04010    return ms;
04011 }
04012 
04013 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04014 {
04015    struct iax2_trunk_peer *tpeer;
04016    
04017    /* Finds and locks trunk peer */
04018    ast_mutex_lock(&tpeerlock);
04019    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04020       /* We don't lock here because tpeer->addr *never* changes */
04021       if (!inaddrcmp(&tpeer->addr, sin)) {
04022          ast_mutex_lock(&tpeer->lock);
04023          break;
04024       }
04025    }
04026    if (!tpeer) {
04027       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04028          ast_mutex_init(&tpeer->lock);
04029          tpeer->lastsent = 9999;
04030          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04031          tpeer->trunkact = ast_tvnow();
04032          ast_mutex_lock(&tpeer->lock);
04033          tpeer->next = tpeers;
04034          tpeer->sockfd = fd;
04035          tpeers = tpeer;
04036 #ifdef SO_NO_CHECK
04037          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04038 #endif
04039          if (option_debug)
04040             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04041       }
04042    }
04043    ast_mutex_unlock(&tpeerlock);
04044    return tpeer;
04045 }
04046 
04047 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04048 {
04049    struct ast_frame *f;
04050    struct iax2_trunk_peer *tpeer;
04051    void *tmp, *ptr;
04052    struct ast_iax2_meta_trunk_entry *met;
04053    struct ast_iax2_meta_trunk_mini *mtm;
04054 
04055    f = &fr->af;
04056    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04057    if (tpeer) {
04058       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04059          /* Need to reallocate space */
04060          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04061             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04062                ast_mutex_unlock(&tpeer->lock);
04063                return -1;
04064             }
04065             
04066             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04067             tpeer->trunkdata = tmp;
04068             if (option_debug)
04069                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);
04070          } else {
04071             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));
04072             ast_mutex_unlock(&tpeer->lock);
04073             return -1;
04074          }
04075       }
04076 
04077       /* Append to meta frame */
04078       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04079       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04080          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04081          mtm->len = htons(f->datalen);
04082          mtm->mini.callno = htons(pvt->callno);
04083          mtm->mini.ts = htons(0xffff & fr->ts);
04084          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04085          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04086       } else {
04087          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04088          /* Store call number and length in meta header */
04089          met->callno = htons(pvt->callno);
04090          met->len = htons(f->datalen);
04091          /* Advance pointers/decrease length past trunk entry header */
04092          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04093          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04094       }
04095       /* Copy actual trunk data */
04096       memcpy(ptr, f->data, f->datalen);
04097       tpeer->trunkdatalen += f->datalen;
04098 
04099       tpeer->calls++;
04100       ast_mutex_unlock(&tpeer->lock);
04101    }
04102    return 0;
04103 }
04104 
04105 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04106 {
04107    aes_encrypt_key128(digest, ecx);
04108    aes_decrypt_key128(digest, dcx);
04109 }
04110 
04111 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04112 {
04113 #if 0
04114    /* Debug with "fake encryption" */
04115    int x;
04116    if (len % 16)
04117       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04118    for (x=0;x<len;x++)
04119       dst[x] = src[x] ^ 0xff;
04120 #else 
04121    unsigned char lastblock[16] = { 0 };
04122    int x;
04123    while(len > 0) {
04124       aes_decrypt(src, dst, dcx);
04125       for (x=0;x<16;x++)
04126          dst[x] ^= lastblock[x];
04127       memcpy(lastblock, src, sizeof(lastblock));
04128       dst += 16;
04129       src += 16;
04130       len -= 16;
04131    }
04132 #endif
04133 }
04134 
04135 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04136 {
04137 #if 0
04138    /* Debug with "fake encryption" */
04139    int x;
04140    if (len % 16)
04141       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04142    for (x=0;x<len;x++)
04143       dst[x] = src[x] ^ 0xff;
04144 #else
04145    unsigned char curblock[16] = { 0 };
04146    int x;
04147    while(len > 0) {
04148       for (x=0;x<16;x++)
04149          curblock[x] ^= src[x];
04150       aes_encrypt(curblock, dst, ecx);
04151       memcpy(curblock, dst, sizeof(curblock)); 
04152       dst += 16;
04153       src += 16;
04154       len -= 16;
04155    }
04156 #endif
04157 }
04158 
04159 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04160 {
04161    int padding;
04162    unsigned char *workspace;
04163 
04164    workspace = alloca(*datalen);
04165    memset(f, 0, sizeof(*f));
04166    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04167       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04168       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04169          return -1;
04170       /* Decrypt */
04171       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04172 
04173       padding = 16 + (workspace[15] & 0xf);
04174       if (option_debug && iaxdebug)
04175          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04176       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04177          return -1;
04178 
04179       *datalen -= padding;
04180       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04181       f->frametype = fh->type;
04182       if (f->frametype == AST_FRAME_VIDEO) {
04183          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04184       } else {
04185          f->subclass = uncompress_subclass(fh->csub);
04186       }
04187    } else {
04188       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04189       if (option_debug && iaxdebug)
04190          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04191       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04192          return -1;
04193       /* Decrypt */
04194       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04195       padding = 16 + (workspace[15] & 0x0f);
04196       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04197          return -1;
04198       *datalen -= padding;
04199       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04200    }
04201    return 0;
04202 }
04203 
04204 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04205 {
04206    int padding;
04207    unsigned char *workspace;
04208    workspace = alloca(*datalen + 32);
04209    if (!workspace)
04210       return -1;
04211    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04212       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04213       if (option_debug && iaxdebug)
04214          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04215       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04216       padding = 16 + (padding & 0xf);
04217       memcpy(workspace, poo, padding);
04218       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04219       workspace[15] &= 0xf0;
04220       workspace[15] |= (padding & 0xf);
04221       if (option_debug && iaxdebug)
04222          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]);
04223       *datalen += padding;
04224       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04225       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04226          memcpy(poo, workspace + *datalen - 32, 32);
04227    } else {
04228       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04229       if (option_debug && iaxdebug)
04230          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04231       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04232       padding = 16 + (padding & 0xf);
04233       memcpy(workspace, poo, padding);
04234       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04235       workspace[15] &= 0xf0;
04236       workspace[15] |= (padding & 0x0f);
04237       *datalen += padding;
04238       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04239       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04240          memcpy(poo, workspace + *datalen - 32, 32);
04241    }
04242    return 0;
04243 }
04244 
04245 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04246 {
04247    int res=-1;
04248    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04249       /* Search for possible keys, given secrets */
04250       struct MD5Context md5;
04251       unsigned char digest[16];
04252       char *tmppw, *stringp;
04253       
04254       tmppw = ast_strdupa(iaxs[callno]->secret);
04255       stringp = tmppw;
04256       while ((tmppw = strsep(&stringp, ";"))) {
04257          MD5Init(&md5);
04258          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04259          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04260          MD5Final(digest, &md5);
04261          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04262          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04263          if (!res) {
04264             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04265             break;
04266          }
04267       }
04268    } else 
04269       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04270    return res;
04271 }
04272 
04273 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04274 {
04275    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04276       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04277       or delayed, with retransmission */
04278    struct ast_iax2_full_hdr *fh;
04279    struct ast_iax2_mini_hdr *mh;
04280    struct ast_iax2_video_hdr *vh;
04281    struct {
04282       struct iax_frame fr2;
04283       unsigned char buffer[4096];
04284    } frb;
04285    struct iax_frame *fr;
04286    int res;
04287    int sendmini=0;
04288    unsigned int lastsent;
04289    unsigned int fts;
04290 
04291    frb.fr2.afdatalen = sizeof(frb.buffer);
04292 
04293    if (!pvt) {
04294       ast_log(LOG_WARNING, "No private structure for packet?\n");
04295       return -1;
04296    }
04297    
04298    lastsent = pvt->lastsent;
04299 
04300    /* Calculate actual timestamp */
04301    fts = calc_timestamp(pvt, ts, f);
04302 
04303    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04304     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04305     * increment the "predicted timestamps" for voice, if we're predecting */
04306    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04307        return 0;
04308 
04309 
04310    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04311          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04312          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04313       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04314        (f->frametype == AST_FRAME_VOICE) 
04315       /* is a voice frame */ &&
04316       (f->subclass == pvt->svoiceformat) 
04317       /* is the same type */ ) {
04318          /* Force immediate rather than delayed transmission */
04319          now = 1;
04320          /* Mark that mini-style frame is appropriate */
04321          sendmini = 1;
04322    }
04323    if ( f->frametype == AST_FRAME_VIDEO ) {
04324       /*
04325        * If the lower 15 bits of the timestamp roll over, or if
04326        * the video format changed then send a full frame.
04327        * Otherwise send a mini video frame
04328        */
04329       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04330           ((f->subclass & ~0x1) == pvt->svideoformat)
04331          ) {
04332          now = 1;
04333          sendmini = 1;
04334       } else {
04335          now = 0;
04336          sendmini = 0;
04337       }
04338       pvt->lastvsent = fts;
04339    }
04340    /* Allocate an iax_frame */
04341    if (now) {
04342       fr = &frb.fr2;
04343    } else
04344       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));
04345    if (!fr) {
04346       ast_log(LOG_WARNING, "Out of memory\n");
04347       return -1;
04348    }
04349    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04350    iax_frame_wrap(fr, f);
04351 
04352    fr->ts = fts;
04353    fr->callno = pvt->callno;
04354    fr->transfer = transfer;
04355    fr->final = final;
04356    if (!sendmini) {
04357       /* We need a full frame */
04358       if (seqno > -1)
04359          fr->oseqno = seqno;
04360       else
04361          fr->oseqno = pvt->oseqno++;
04362       fr->iseqno = pvt->iseqno;
04363       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04364       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04365       fh->ts = htonl(fr->ts);
04366       fh->oseqno = fr->oseqno;
04367       if (transfer) {
04368          fh->iseqno = 0;
04369       } else
04370          fh->iseqno = fr->iseqno;
04371       /* Keep track of the last thing we've acknowledged */
04372       if (!transfer)
04373          pvt->aseqno = fr->iseqno;
04374       fh->type = fr->af.frametype & 0xFF;
04375       if (fr->af.frametype == AST_FRAME_VIDEO)
04376          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04377       else
04378          fh->csub = compress_subclass(fr->af.subclass);
04379       if (transfer) {
04380          fr->dcallno = pvt->transfercallno;
04381       } else
04382          fr->dcallno = pvt->peercallno;
04383       fh->dcallno = htons(fr->dcallno);
04384       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04385       fr->data = fh;
04386       fr->retries = 0;
04387       /* Retry after 2x the ping time has passed */
04388       fr->retrytime = pvt->pingtime * 2;
04389       if (fr->retrytime < MIN_RETRY_TIME)
04390          fr->retrytime = MIN_RETRY_TIME;
04391       if (fr->retrytime > MAX_RETRY_TIME)
04392          fr->retrytime = MAX_RETRY_TIME;
04393       /* Acks' don't get retried */
04394       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04395          fr->retries = -1;
04396       else if (f->frametype == AST_FRAME_VOICE)
04397          pvt->svoiceformat = f->subclass;
04398       else if (f->frametype == AST_FRAME_VIDEO)
04399          pvt->svideoformat = f->subclass & ~0x1;
04400       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04401          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04402             if (iaxdebug) {
04403                if (fr->transfer)
04404                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04405                else
04406                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04407             }
04408             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04409          } else
04410             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04411       }
04412    
04413       if (now) {
04414          res = send_packet(fr);
04415       } else
04416          res = iax2_transmit(fr);
04417    } else {
04418       if (ast_test_flag(pvt, IAX_TRUNK)) {
04419          iax2_trunk_queue(pvt, fr);
04420          res = 0;
04421       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04422          /* Video frame have no sequence number */
04423          fr->oseqno = -1;
04424          fr->iseqno = -1;
04425          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04426          vh->zeros = 0;
04427          vh->callno = htons(0x8000 | fr->callno);
04428          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04429          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04430          fr->data = vh;
04431          fr->retries = -1;
04432          res = send_packet(fr);        
04433       } else {
04434          /* Mini-frames have no sequence number */
04435          fr->oseqno = -1;
04436          fr->iseqno = -1;
04437          /* Mini frame will do */
04438          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04439          mh->callno = htons(fr->callno);
04440          mh->ts = htons(fr->ts & 0xFFFF);
04441          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04442          fr->data = mh;
04443          fr->retries = -1;
04444          if (pvt->transferring == TRANSFER_MEDIAPASS)
04445             fr->transfer = 1;
04446          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04447             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04448                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04449             } else
04450                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04451          }
04452          res = send_packet(fr);
04453       }
04454    }
04455    return res;
04456 }
04457 
04458 static int iax2_show_users(int fd, int argc, char *argv[])
04459 {
04460    regex_t regexbuf;
04461    int havepattern = 0;
04462 
04463 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04464 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04465 
04466    struct iax2_user *user = NULL;
04467    char auth[90];
04468    char *pstr = "";
04469    struct ao2_iterator i;
04470 
04471    switch (argc) {
04472    case 5:
04473       if (!strcasecmp(argv[3], "like")) {
04474          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04475             return RESULT_SHOWUSAGE;
04476          havepattern = 1;
04477       } else
04478          return RESULT_SHOWUSAGE;
04479    case 3:
04480       break;
04481    default:
04482       return RESULT_SHOWUSAGE;
04483    }
04484 
04485    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04486    i = ao2_iterator_init(users, 0);
04487    for (user = ao2_iterator_next(&i); user; 
04488       user_unref(user), user = ao2_iterator_next(&i)) {
04489       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04490          continue;
04491       
04492       if (!ast_strlen_zero(user->secret)) {
04493          ast_copy_string(auth,user->secret,sizeof(auth));
04494       } else if (!ast_strlen_zero(user->inkeys)) {
04495          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04496       } else
04497          ast_copy_string(auth, "-no secret-", sizeof(auth));
04498       
04499       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04500          pstr = "REQ Only";
04501       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04502          pstr = "Disabled";
04503       else
04504          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04505       
04506       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04507          user->contexts ? user->contexts->context : context,
04508          user->ha ? "Yes" : "No", pstr);
04509    }
04510 
04511    if (havepattern)
04512       regfree(&regexbuf);
04513 
04514    return RESULT_SUCCESS;
04515 #undef FORMAT
04516 #undef FORMAT2
04517 }
04518 
04519 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04520 {
04521    regex_t regexbuf;
04522    int havepattern = 0;
04523    int total_peers = 0;
04524    int online_peers = 0;
04525    int offline_peers = 0;
04526    int unmonitored_peers = 0;
04527    struct ao2_iterator i;
04528 
04529 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04530 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04531 
04532    struct iax2_peer *peer = NULL;
04533    char name[256];
04534    int registeredonly=0;
04535    char *term = manager ? "\r\n" : "\n";
04536 
04537    switch (argc) {
04538    case 6:
04539       if (!strcasecmp(argv[3], "registered"))
04540          registeredonly = 1;
04541       else
04542          return RESULT_SHOWUSAGE;
04543       if (!strcasecmp(argv[4], "like")) {
04544          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04545             return RESULT_SHOWUSAGE;
04546          havepattern = 1;
04547       } else
04548          return RESULT_SHOWUSAGE;
04549       break;
04550    case 5:
04551       if (!strcasecmp(argv[3], "like")) {
04552          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04553             return RESULT_SHOWUSAGE;
04554          havepattern = 1;
04555       } else
04556          return RESULT_SHOWUSAGE;
04557       break;
04558    case 4:
04559       if (!strcasecmp(argv[3], "registered"))
04560          registeredonly = 1;
04561       else
04562          return RESULT_SHOWUSAGE;
04563       break;
04564    case 3:
04565       break;
04566    default:
04567       return RESULT_SHOWUSAGE;
04568    }
04569 
04570 
04571    if (s)
04572       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04573    else
04574       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04575 
04576    i = ao2_iterator_init(peers, 0);
04577    for (peer = ao2_iterator_next(&i); peer; 
04578       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04579       char nm[20];
04580       char status[20];
04581       char srch[2000];
04582       int retstatus;
04583 
04584       if (registeredonly && !peer->addr.sin_addr.s_addr)
04585          continue;
04586       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04587          continue;
04588 
04589       if (!ast_strlen_zero(peer->username))
04590          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04591       else
04592          ast_copy_string(name, peer->name, sizeof(name));
04593       
04594       retstatus = peer_status(peer, status, sizeof(status));
04595       if (retstatus > 0)
04596          online_peers++;
04597       else if (!retstatus)
04598          offline_peers++;
04599       else
04600          unmonitored_peers++;
04601       
04602       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04603       
04604       snprintf(srch, sizeof(srch), FORMAT, name, 
04605           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04606           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04607           nm,
04608           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04609           peer->encmethods ? "(E)" : "   ", status, term);
04610       
04611       if (s)
04612          astman_append(s, FORMAT, name, 
04613                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04614                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04615                   nm,
04616                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04617                   peer->encmethods ? "(E)" : "   ", status, term);
04618       else
04619          ast_cli(fd, FORMAT, name, 
04620             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04621             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04622             nm,
04623             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04624             peer->encmethods ? "(E)" : "   ", status, term);
04625       total_peers++;
04626    }
04627 
04628    if (s)
04629       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04630    else
04631       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04632 
04633    if (havepattern)
04634       regfree(&regexbuf);
04635 
04636    return RESULT_SUCCESS;
04637 #undef FORMAT
04638 #undef FORMAT2
04639 }
04640 
04641 static int iax2_show_threads(int fd, int argc, char *argv[])
04642 {
04643    struct iax2_thread *thread = NULL;
04644    time_t t;
04645    int threadcount = 0, dynamiccount = 0;
04646    char type;
04647 
04648    if (argc != 3)
04649       return RESULT_SHOWUSAGE;
04650       
04651    ast_cli(fd, "IAX2 Thread Information\n");
04652    time(&t);
04653    ast_cli(fd, "Idle Threads:\n");
04654    AST_LIST_LOCK(&idle_list);
04655    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04656 #ifdef DEBUG_SCHED_MULTITHREAD
04657       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04658          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04659 #else
04660       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04661          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04662 #endif
04663       threadcount++;
04664    }
04665    AST_LIST_UNLOCK(&idle_list);
04666    ast_cli(fd, "Active Threads:\n");
04667    AST_LIST_LOCK(&active_list);
04668    AST_LIST_TRAVERSE(&active_list, thread, list) {
04669       if (thread->type == IAX_TYPE_DYNAMIC)
04670          type = 'D';
04671       else
04672          type = 'P';
04673 #ifdef DEBUG_SCHED_MULTITHREAD
04674       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04675          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04676 #else
04677       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04678          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04679 #endif
04680       threadcount++;
04681    }
04682    AST_LIST_UNLOCK(&active_list);
04683    ast_cli(fd, "Dynamic Threads:\n");
04684         AST_LIST_LOCK(&dynamic_list);
04685         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04686 #ifdef DEBUG_SCHED_MULTITHREAD
04687                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04688                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04689 #else
04690                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04691                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04692 #endif
04693       dynamiccount++;
04694         }
04695         AST_LIST_UNLOCK(&dynamic_list);
04696    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04697    return RESULT_SUCCESS;
04698 }
04699 
04700 static int iax2_show_peers(int fd, int argc, char *argv[])
04701 {
04702    return __iax2_show_peers(0, fd, NULL, argc, argv);
04703 }
04704 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04705 {
04706    ast_cli_netstats(s, -1, 0);
04707    astman_append(s, "\r\n");
04708    return RESULT_SUCCESS;
04709 }
04710 
04711 static int iax2_show_firmware(int fd, int argc, char *argv[])
04712 {
04713 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04714 #if !defined(__FreeBSD__)
04715 #define FORMAT "%-15.15s  %-15d %-15d\n"
04716 #else /* __FreeBSD__ */
04717 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04718 #endif /* __FreeBSD__ */
04719    struct iax_firmware *cur;
04720    if ((argc != 3) && (argc != 4))
04721       return RESULT_SHOWUSAGE;
04722    ast_mutex_lock(&waresl.lock);
04723    
04724    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04725    for (cur = waresl.wares;cur;cur = cur->next) {
04726       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04727          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04728             (int)ntohl(cur->fwh->datalen));
04729    }
04730    ast_mutex_unlock(&waresl.lock);
04731    return RESULT_SUCCESS;
04732 #undef FORMAT
04733 #undef FORMAT2
04734 }
04735 
04736 /* JDG: callback to display iax peers in manager */
04737 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04738 {
04739    char *a[] = { "iax2", "show", "users" };
04740    int ret;
04741    const char *id = astman_get_header(m,"ActionID");
04742 
04743    if (!ast_strlen_zero(id))
04744       astman_append(s, "ActionID: %s\r\n",id);
04745    ret = __iax2_show_peers(1, -1, s, 3, a );
04746    astman_append(s, "\r\n\r\n" );
04747    return ret;
04748 } /* /JDG */
04749 
04750 static char *regstate2str(int regstate)
04751 {
04752    switch(regstate) {
04753    case REG_STATE_UNREGISTERED:
04754       return "Unregistered";
04755    case REG_STATE_REGSENT:
04756       return "Request Sent";
04757    case REG_STATE_AUTHSENT:
04758       return "Auth. Sent";
04759    case REG_STATE_REGISTERED:
04760       return "Registered";
04761    case REG_STATE_REJECTED:
04762       return "Rejected";
04763    case REG_STATE_TIMEOUT:
04764       return "Timeout";
04765    case REG_STATE_NOAUTH:
04766       return "No Authentication";
04767    default:
04768       return "Unknown";
04769    }
04770 }
04771 
04772 static int iax2_show_registry(int fd, int argc, char *argv[])
04773 {
04774 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04775 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04776    struct iax2_registry *reg = NULL;
04777 
04778    char host[80];
04779    char perceived[80];
04780    if (argc != 3)
04781       return RESULT_SHOWUSAGE;
04782    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04783    AST_LIST_LOCK(&registrations);
04784    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04785       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04786       if (reg->us.sin_addr.s_addr) 
04787          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04788       else
04789          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04790       ast_cli(fd, FORMAT, host, 
04791                (reg->dnsmgr) ? "Y" : "N", 
04792                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04793    }
04794    AST_LIST_UNLOCK(&registrations);
04795    return RESULT_SUCCESS;
04796 #undef FORMAT
04797 #undef FORMAT2
04798 }
04799 
04800 static int iax2_show_channels(int fd, int argc, char *argv[])
04801 {
04802 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04803 #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"
04804 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04805    int x;
04806    int numchans = 0;
04807 
04808    if (argc != 3)
04809       return RESULT_SHOWUSAGE;
04810    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04811    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04812       ast_mutex_lock(&iaxsl[x]);
04813       if (iaxs[x]) {
04814          int lag, jitter, localdelay;
04815          jb_info jbinfo;
04816          
04817          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04818             jb_getinfo(iaxs[x]->jb, &jbinfo);
04819             jitter = jbinfo.jitter;
04820             localdelay = jbinfo.current - jbinfo.min;
04821          } else {
04822             jitter = -1;
04823             localdelay = 0;
04824          }
04825          lag = iaxs[x]->remote_rr.delay;
04826          ast_cli(fd, FORMAT,
04827             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04828             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04829             S_OR(iaxs[x]->username, "(None)"),
04830             iaxs[x]->callno, iaxs[x]->peercallno,
04831             iaxs[x]->oseqno, iaxs[x]->iseqno,
04832             lag,
04833             jitter,
04834             localdelay,
04835             ast_getformatname(iaxs[x]->voiceformat) );
04836          numchans++;
04837       }
04838       ast_mutex_unlock(&iaxsl[x]);
04839    }
04840    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04841    return RESULT_SUCCESS;
04842 #undef FORMAT
04843 #undef FORMAT2
04844 #undef FORMATB
04845 }
04846 
04847 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04848 {
04849    int x;
04850    int numchans = 0;
04851    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04852       ast_mutex_lock(&iaxsl[x]);
04853       if (iaxs[x]) {
04854          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04855          char *fmt;
04856          jb_info jbinfo;
04857          
04858          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04859             jb_getinfo(iaxs[x]->jb, &jbinfo);
04860             localjitter = jbinfo.jitter;
04861             localdelay = jbinfo.current - jbinfo.min;
04862             locallost = jbinfo.frames_lost;
04863             locallosspct = jbinfo.losspct/1000;
04864             localdropped = jbinfo.frames_dropped;
04865             localooo = jbinfo.frames_ooo;
04866          } else {
04867             localjitter = -1;
04868             localdelay = 0;
04869             locallost = -1;
04870             locallosspct = -1;
04871             localdropped = 0;
04872             localooo = -1;
04873          }
04874          if (limit_fmt)
04875             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04876          else
04877             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04878          if (s)
04879             
04880             astman_append(s, fmt,
04881                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04882                      iaxs[x]->pingtime,
04883                      localjitter, 
04884                      localdelay,
04885                      locallost,
04886                      locallosspct,
04887                      localdropped,
04888                      localooo,
04889                      iaxs[x]->frames_received/1000,
04890                      iaxs[x]->remote_rr.jitter,
04891                      iaxs[x]->remote_rr.delay,
04892                      iaxs[x]->remote_rr.losscnt,
04893                      iaxs[x]->remote_rr.losspct,
04894                      iaxs[x]->remote_rr.dropped,
04895                      iaxs[x]->remote_rr.ooo,
04896                      iaxs[x]->remote_rr.packets/1000);
04897          else
04898             ast_cli(fd, fmt,
04899                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04900                iaxs[x]->pingtime,
04901                localjitter, 
04902                localdelay,
04903                locallost,
04904                locallosspct,
04905                localdropped,
04906                localooo,
04907                iaxs[x]->frames_received/1000,
04908                iaxs[x]->remote_rr.jitter,
04909                iaxs[x]->remote_rr.delay,
04910                iaxs[x]->remote_rr.losscnt,
04911                iaxs[x]->remote_rr.losspct,
04912                iaxs[x]->remote_rr.dropped,
04913                iaxs[x]->remote_rr.ooo,
04914                iaxs[x]->remote_rr.packets/1000
04915                );
04916          numchans++;
04917       }
04918       ast_mutex_unlock(&iaxsl[x]);
04919    }
04920    return numchans;
04921 }
04922 
04923 static int iax2_show_netstats(int fd, int argc, char *argv[])
04924 {
04925    int numchans = 0;
04926    if (argc != 3)
04927       return RESULT_SHOWUSAGE;
04928    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04929    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04930    numchans = ast_cli_netstats(NULL, fd, 1);
04931    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04932    return RESULT_SUCCESS;
04933 }
04934 
04935 static int iax2_do_debug(int fd, int argc, char *argv[])
04936 {
04937    if (argc < 2 || argc > 3)
04938       return RESULT_SHOWUSAGE;
04939    iaxdebug = 1;
04940    ast_cli(fd, "IAX2 Debugging Enabled\n");
04941    return RESULT_SUCCESS;
04942 }
04943 
04944 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04945 {
04946    if (argc < 3 || argc > 4)
04947       return RESULT_SHOWUSAGE;
04948    iaxtrunkdebug = 1;
04949    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04950    return RESULT_SUCCESS;
04951 }
04952 
04953 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04954 {
04955    if (argc < 3 || argc > 4)
04956       return RESULT_SHOWUSAGE;
04957    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04958    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04959    return RESULT_SUCCESS;
04960 }
04961 
04962 static int iax2_no_debug(int fd, int argc, char *argv[])
04963 {
04964    if (argc < 3 || argc > 4)
04965       return RESULT_SHOWUSAGE;
04966    iaxdebug = 0;
04967    ast_cli(fd, "IAX2 Debugging Disabled\n");
04968    return RESULT_SUCCESS;
04969 }
04970 
04971 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04972 {
04973    if (argc < 4 || argc > 5)
04974       return RESULT_SHOWUSAGE;
04975    iaxtrunkdebug = 0;
04976    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04977    return RESULT_SUCCESS;
04978 }
04979 
04980 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04981 {
04982    if (argc < 4 || argc > 5)
04983       return RESULT_SHOWUSAGE;
04984    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04985    jb_debug_output("\n");
04986    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04987    return RESULT_SUCCESS;
04988 }
04989 
04990 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04991 {
04992    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04993    int res = -1;
04994    ast_mutex_lock(&iaxsl[callno]);
04995    if (iaxs[callno]) {
04996    /* If there's an outstanding error, return failure now */
04997       if (!iaxs[callno]->error) {
04998          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04999             res = 0;
05000             /* Don't waste bandwidth sending null frames */
05001          else if (f->frametype == AST_FRAME_NULL)
05002             res = 0;
05003          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05004             res = 0;
05005          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05006             res = 0;
05007          else
05008          /* Simple, just queue for transmission */
05009             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05010       } else {
05011          if (option_debug)
05012             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05013       }
05014    }
05015    /* If it's already gone, just return */
05016    ast_mutex_unlock(&iaxsl[callno]);
05017    return res;
05018 }
05019 
05020 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05021       int now, int transfer, int final)
05022 {
05023    struct ast_frame f = { 0, };
05024 
05025    f.frametype = type;
05026    f.subclass = command;
05027    f.datalen = datalen;
05028    f.src = __FUNCTION__;
05029    f.data = (void *) data;
05030 
05031    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05032 }
05033 
05034 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05035 {
05036    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05037 }
05038 
05039 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05040 {
05041    int res;
05042    ast_mutex_lock(&iaxsl[callno]);
05043    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05044    ast_mutex_unlock(&iaxsl[callno]);
05045    return res;
05046 }
05047 
05048 /*!
05049  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05050  *       the pvt struct for the given call number may disappear during its 
05051  *       execution.
05052  */
05053 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)
05054 {
05055    int call_num = i->callno;
05056    /* It is assumed that the callno has already been locked */
05057    iax2_predestroy(i->callno);
05058    if (!iaxs[call_num])
05059       return -1;
05060    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05061 }
05062 
05063 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)
05064 {
05065    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05066 }
05067 
05068 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05069 {
05070    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05071 }
05072 
05073 static int apply_context(struct iax2_context *con, const char *context)
05074 {
05075    while(con) {
05076       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05077          return -1;
05078       con = con->next;
05079    }
05080    return 0;
05081 }
05082 
05083 
05084 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05085 {
05086    /* Start pessimistic */
05087    int res = -1;
05088    int version = 2;
05089    struct iax2_user *user = NULL, *best = NULL;
05090    int bestscore = 0;
05091    int gotcapability = 0;
05092    struct ast_variable *v = NULL, *tmpvar = NULL;
05093    struct ao2_iterator i;
05094 
05095    if (!iaxs[callno])
05096       return res;
05097    if (ies->called_number)
05098       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05099    if (ies->calling_number) {
05100       ast_shrink_phone_number(ies->calling_number);
05101       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05102    }
05103    if (ies->calling_name)
05104       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05105    if (ies->calling_ani)
05106       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05107    if (ies->dnid)
05108       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05109    if (ies->rdnis)
05110       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05111    if (ies->called_context)
05112       ast_string_field_set(iaxs[callno], context, ies->called_context);
05113    if (ies->language)
05114       ast_string_field_set(iaxs[callno], language, ies->language);
05115    if (ies->username)
05116       ast_string_field_set(iaxs[callno], username, ies->username);
05117    if (ies->calling_ton > -1)
05118       iaxs[callno]->calling_ton = ies->calling_ton;
05119    if (ies->calling_tns > -1)
05120       iaxs[callno]->calling_tns = ies->calling_tns;
05121    if (ies->calling_pres > -1)
05122       iaxs[callno]->calling_pres = ies->calling_pres;
05123    if (ies->format)
05124       iaxs[callno]->peerformat = ies->format;
05125    if (ies->adsicpe)
05126       iaxs[callno]->peeradsicpe = ies->adsicpe;
05127    if (ies->capability) {
05128       gotcapability = 1;
05129       iaxs[callno]->peercapability = ies->capability;
05130    } 
05131    if (ies->version)
05132       version = ies->version;
05133 
05134    /* Use provided preferences until told otherwise for actual preferences */
05135    if(ies->codec_prefs) {
05136       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05137       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05138    }
05139 
05140    if (!gotcapability) 
05141       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05142    if (version > IAX_PROTO_VERSION) {
05143       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05144          ast_inet_ntoa(sin->sin_addr), version);
05145       return res;
05146    }
05147    /* Search the userlist for a compatible entry, and fill in the rest */
05148    i = ao2_iterator_init(users, 0);
05149    while ((user = ao2_iterator_next(&i))) {
05150       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05151          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05152          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05153          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05154               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05155          if (!ast_strlen_zero(iaxs[callno]->username)) {
05156             /* Exact match, stop right now. */
05157             if (best)
05158                user_unref(best);
05159             best = user;
05160             break;
05161          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05162             /* No required authentication */
05163             if (user->ha) {
05164                /* There was host authentication and we passed, bonus! */
05165                if (bestscore < 4) {
05166                   bestscore = 4;
05167                   if (best)
05168                      user_unref(best);
05169                   best = user;
05170                   continue;
05171                }
05172             } else {
05173                /* No host access, but no secret, either, not bad */
05174                if (bestscore < 3) {
05175                   bestscore = 3;
05176                   if (best)
05177                      user_unref(best);
05178                   best = user;
05179                   continue;
05180                }
05181             }
05182          } else {
05183             if (user->ha) {
05184                /* Authentication, but host access too, eh, it's something.. */
05185                if (bestscore < 2) {
05186                   bestscore = 2;
05187                   if (best)
05188                      user_unref(best);
05189                   best = user;
05190                   continue;
05191                }
05192             } else {
05193                /* Authentication and no host access...  This is our baseline */
05194                if (bestscore < 1) {
05195                   bestscore = 1;
05196                   if (best)
05197                      user_unref(best);
05198                   best = user;
05199                   continue;
05200                }
05201             }
05202          }
05203       }
05204       user_unref(user);
05205    }
05206    user = best;
05207    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05208       user = realtime_user(iaxs[callno]->username, sin);
05209       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05210           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05211          user = user_unref(user);
05212       }
05213    }
05214    if (user) {
05215       /* We found our match (use the first) */
05216       /* copy vars */
05217       for (v = user->vars ; v ; v = v->next) {
05218          if((tmpvar = ast_variable_new(v->name, v->value))) {
05219             tmpvar->next = iaxs[callno]->vars; 
05220             iaxs[callno]->vars = tmpvar;
05221          }
05222       }
05223       /* If a max AUTHREQ restriction is in place, activate it */
05224       if (user->maxauthreq > 0)
05225          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05226       iaxs[callno]->prefs = user->prefs;
05227       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05228       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05229       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05230       iaxs[callno]->encmethods = user->encmethods;
05231       /* Store the requested username if not specified */
05232       if (ast_strlen_zero(iaxs[callno]->username))
05233          ast_string_field_set(iaxs[callno], username, user->name);
05234       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05235       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05236       iaxs[callno]->capability = user->capability;
05237       /* And use the default context */
05238       if (ast_strlen_zero(iaxs[callno]->context)) {
05239          if (user->contexts)
05240             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05241          else
05242             ast_string_field_set(iaxs[callno], context, context);
05243       }
05244       /* And any input keys */
05245       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05246       /* And the permitted authentication methods */
05247       iaxs[callno]->authmethods = user->authmethods;
05248       iaxs[callno]->adsi = user->adsi;
05249       /* If they have callerid, override the given caller id.  Always store the ANI */
05250       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05251          if (ast_test_flag(user, IAX_HASCALLERID)) {
05252             iaxs[callno]->calling_tns = 0;
05253             iaxs[callno]->calling_ton = 0;
05254             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05255             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05256             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05257          }
05258          if (ast_strlen_zero(iaxs[callno]->ani))
05259             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05260       } else {
05261          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05262       }
05263       if (!ast_strlen_zero(user->accountcode))
05264          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05265       if (!ast_strlen_zero(user->mohinterpret))
05266          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05267       if (!ast_strlen_zero(user->mohsuggest))
05268          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05269       if (user->amaflags)
05270          iaxs[callno]->amaflags = user->amaflags;
05271       if (!ast_strlen_zero(user->language))
05272          ast_string_field_set(iaxs[callno], language, user->language);
05273       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05274       /* Keep this check last */
05275       if (!ast_strlen_zero(user->dbsecret)) {
05276          char *family, *key=NULL;
05277          char buf[80];
05278          family = ast_strdupa(user->dbsecret);
05279          key = strchr(family, '/');
05280          if (key) {
05281             *key = '\0';
05282             key++;
05283          }
05284          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05285             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05286          else
05287             ast_string_field_set(iaxs[callno], secret, buf);
05288       } else
05289          ast_string_field_set(iaxs[callno], secret, user->secret);
05290       res = 0;
05291       user = user_unref(user);
05292    }
05293    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05294    return res;
05295 }
05296 
05297 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05298 {
05299    struct ast_iax2_full_hdr fh;
05300    fh.scallno = htons(src | IAX_FLAG_FULL);
05301    fh.dcallno = htons(dst);
05302    fh.ts = 0;
05303    fh.oseqno = 0;
05304    fh.iseqno = 0;
05305    fh.type = AST_FRAME_IAX;
05306    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05307    if (iaxdebug)
05308        iax_showframe(NULL, &fh, 0, sin, 0);
05309    if (option_debug)
05310       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05311          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05312    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05313 }
05314 
05315 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05316 {
05317    /* Select exactly one common encryption if there are any */
05318    p->encmethods &= enc;
05319    if (p->encmethods) {
05320       if (p->encmethods & IAX_ENCRYPT_AES128)
05321          p->encmethods = IAX_ENCRYPT_AES128;
05322       else
05323          p->encmethods = 0;
05324    }
05325 }
05326 
05327 /*!
05328  * \pre iaxsl[call_num] is locked
05329  *
05330  * \note Since this function calls send_command_final(), the pvt struct for the given
05331  *       call number may disappear while executing this function.
05332  */
05333 static int authenticate_request(int call_num)
05334 {
05335    struct iax_ie_data ied;
05336    int res = -1, authreq_restrict = 0;
05337    char challenge[10];
05338    struct chan_iax2_pvt *p = iaxs[call_num];
05339 
05340    memset(&ied, 0, sizeof(ied));
05341 
05342    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05343    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05344       struct iax2_user *user, tmp_user = {
05345          .name = p->username, 
05346       };
05347 
05348       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05349       if (user) {
05350          if (user->curauthreq == user->maxauthreq)
05351             authreq_restrict = 1;
05352          else
05353             user->curauthreq++;
05354          user = user_unref(user);
05355       }
05356    }
05357 
05358    /* If the AUTHREQ limit test failed, send back an error */
05359    if (authreq_restrict) {
05360       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05361       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05362       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05363       return 0;
05364    }
05365 
05366    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05367    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05368       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05369       ast_string_field_set(p, challenge, challenge);
05370       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05371       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05372    }
05373    if (p->encmethods)
05374       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05375 
05376    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05377 
05378    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05379 
05380    if (p->encmethods)
05381       ast_set_flag(p, IAX_ENCRYPTED);
05382 
05383    return res;
05384 }
05385 
05386 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05387 {
05388    char requeststr[256];
05389    char md5secret[256] = "";
05390    char secret[256] = "";
05391    char rsasecret[256] = "";
05392    int res = -1; 
05393    int x;
05394    struct iax2_user *user, tmp_user = {
05395       .name = p->username, 
05396    };
05397 
05398    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05399    if (user) {
05400       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05401          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05402          ast_clear_flag(p, IAX_MAXAUTHREQ);
05403       }
05404       ast_string_field_set(p, host, user->name);
05405       user = user_unref(user);
05406    }
05407 
05408    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05409       return res;
05410    if (ies->password)
05411       ast_copy_string(secret, ies->password, sizeof(secret));
05412    if (ies->md5_result)
05413       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05414    if (ies->rsa_result)
05415       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05416    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05417       struct ast_key *key;
05418       char *keyn;
05419       char tmpkey[256];
05420       char *stringp=NULL;
05421       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05422       stringp=tmpkey;
05423       keyn = strsep(&stringp, ":");
05424       while(keyn) {
05425          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05426          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05427             res = 0;
05428             break;
05429          } else if (!key)
05430             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05431          keyn = strsep(&stringp, ":");
05432       }
05433    } else if (p->authmethods & IAX_AUTH_MD5) {
05434       struct MD5Context md5;
05435       unsigned char digest[16];
05436       char *tmppw, *stringp;
05437       
05438       tmppw = ast_strdupa(p->secret);
05439       stringp = tmppw;
05440       while((tmppw = strsep(&stringp, ";"))) {
05441          MD5Init(&md5);
05442          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05443          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05444          MD5Final(digest, &md5);
05445          /* If they support md5, authenticate with it.  */
05446          for (x=0;x<16;x++)
05447             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05448          if (!strcasecmp(requeststr, md5secret)) {
05449             res = 0;
05450             break;
05451          }
05452       }
05453    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05454       if (!strcmp(secret, p->secret))
05455          res = 0;
05456    }
05457    return res;
05458 }
05459 
05460 /*! \brief Verify inbound registration */
05461 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05462 {
05463    char requeststr[256] = "";
05464    char peer[256] = "";
05465    char md5secret[256] = "";
05466    char rsasecret[256] = "";
05467    char secret[256] = "";
05468    struct iax2_peer *p = NULL;
05469    struct ast_key *key;
05470    char *keyn;
05471    int x;
05472    int expire = 0;
05473    int res = -1;
05474 
05475    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05476    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05477    if (ies->username)
05478       ast_copy_string(peer, ies->username, sizeof(peer));
05479    if (ies->password)
05480       ast_copy_string(secret, ies->password, sizeof(secret));
05481    if (ies->md5_result)
05482       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05483    if (ies->rsa_result)
05484       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05485    if (ies->refresh)
05486       expire = ies->refresh;
05487 
05488    if (ast_strlen_zero(peer)) {
05489       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05490       return -1;
05491    }
05492 
05493    /* SLD: first call to lookup peer during registration */
05494    ast_mutex_unlock(&iaxsl[callno]);
05495    p = find_peer(peer, 1);
05496    ast_mutex_lock(&iaxsl[callno]);
05497    if (!p || !iaxs[callno]) {
05498       if (authdebug && !p)
05499          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05500       goto return_unref;
05501    }
05502 
05503    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05504       if (authdebug)
05505          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05506       goto return_unref;
05507    }
05508 
05509    if (!ast_apply_ha(p->ha, sin)) {
05510       if (authdebug)
05511          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05512       goto return_unref;
05513    }
05514    if (!inaddrcmp(&p->addr, sin))
05515       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05516    ast_string_field_set(iaxs[callno], secret, p->secret);
05517    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05518    /* Check secret against what we have on file */
05519    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05520       if (!ast_strlen_zero(p->inkeys)) {
05521          char tmpkeys[256];
05522          char *stringp=NULL;
05523          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05524          stringp=tmpkeys;
05525          keyn = strsep(&stringp, ":");
05526          while(keyn) {
05527             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05528             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05529                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05530                break;
05531             } else if (!key) 
05532                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05533             keyn = strsep(&stringp, ":");
05534          }
05535          if (!keyn) {
05536             if (authdebug)
05537                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05538             goto return_unref;
05539          }
05540       } else {
05541          if (authdebug)
05542             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05543          goto return_unref;
05544       }
05545    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05546       struct MD5Context md5;
05547       unsigned char digest[16];
05548       char *tmppw, *stringp;
05549       
05550       tmppw = ast_strdupa(p->secret);
05551       stringp = tmppw;
05552       while((tmppw = strsep(&stringp, ";"))) {
05553          MD5Init(&md5);
05554          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05555          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05556          MD5Final(digest, &md5);
05557          for (x=0;x<16;x++)
05558             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05559          if (!strcasecmp(requeststr, md5secret)) 
05560             break;
05561       }
05562       if (tmppw) {
05563          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05564       } else {
05565          if (authdebug)
05566             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05567          goto return_unref;
05568       }
05569    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05570       /* They've provided a plain text password and we support that */
05571       if (strcmp(secret, p->secret)) {
05572          if (authdebug)
05573             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05574          goto return_unref;
05575       } else
05576          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05577    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05578       if (authdebug)
05579          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05580       goto return_unref;
05581    }
05582    ast_string_field_set(iaxs[callno], peer, peer);
05583    /* Choose lowest expiry number */
05584    if (expire && (expire < iaxs[callno]->expiry)) 
05585       iaxs[callno]->expiry = expire;
05586 
05587    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05588 
05589    res = 0;
05590 
05591 return_unref:
05592    if (p)
05593       peer_unref(p);
05594 
05595    return res;
05596 }
05597 
05598 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)
05599 {
05600    int res = -1;
05601    int x;
05602    if (!ast_strlen_zero(keyn)) {
05603       if (!(authmethods & IAX_AUTH_RSA)) {
05604          if (ast_strlen_zero(secret)) 
05605             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));
05606       } else if (ast_strlen_zero(challenge)) {
05607          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05608       } else {
05609          char sig[256];
05610          struct ast_key *key;
05611          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05612          if (!key) {
05613             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05614          } else {
05615             if (ast_sign(key, (char*)challenge, sig)) {
05616                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05617                res = -1;
05618             } else {
05619                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05620                res = 0;
05621             }
05622          }
05623       }
05624    } 
05625    /* Fall back */
05626    if (res && !ast_strlen_zero(secret)) {
05627       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05628          struct MD5Context md5;
05629          unsigned char digest[16];
05630          char digres[128];
05631          MD5Init(&md5);
05632          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05633          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05634          MD5Final(digest, &md5);
05635          /* If they support md5, authenticate with it.  */
05636          for (x=0;x<16;x++)
05637             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05638          if (ecx && dcx)
05639             build_enc_keys(digest, ecx, dcx);
05640          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05641          res = 0;
05642       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05643          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05644          res = 0;
05645       } else
05646          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05647    }
05648    return res;
05649 }
05650 
05651 /*!
05652  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05653  *       so do not call this function with a pvt lock held.
05654  */
05655 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05656 {
05657    struct iax2_peer *peer = NULL;
05658    /* Start pessimistic */
05659    int res = -1;
05660    int authmethods = 0;
05661    struct iax_ie_data ied;
05662    uint16_t callno = p->callno;
05663 
05664    memset(&ied, 0, sizeof(ied));
05665    
05666    if (ies->username)
05667       ast_string_field_set(p, username, ies->username);
05668    if (ies->challenge)
05669       ast_string_field_set(p, challenge, ies->challenge);
05670    if (ies->authmethods)
05671       authmethods = ies->authmethods;
05672    if (authmethods & IAX_AUTH_MD5)
05673       merge_encryption(p, ies->encmethods);
05674    else
05675       p->encmethods = 0;
05676 
05677    /* Check for override RSA authentication first */
05678    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05679       /* Normal password authentication */
05680       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05681    } else {
05682       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05683       while ((peer = ao2_iterator_next(&i))) {
05684          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05685              /* No peer specified at our end, or this is the peer */
05686              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05687              /* No username specified in peer rule, or this is the right username */
05688              && (!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)))
05689              /* No specified host, or this is our host */
05690             ) {
05691             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05692             if (!res) {
05693                peer_unref(peer);
05694                break;
05695             }
05696          }
05697          peer_unref(peer);
05698       }
05699       if (!peer) {
05700          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05701             that we're trying to authenticate *to* a realtime peer */
05702          const char *peer_name = ast_strdupa(p->peer);
05703          ast_mutex_unlock(&iaxsl[callno]);
05704          if ((peer = realtime_peer(peer_name, NULL))) {
05705             ast_mutex_lock(&iaxsl[callno]);
05706             if (!(p = iaxs[callno])) {
05707                peer_unref(peer);
05708                return -1;
05709             }
05710             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05711             peer_unref(peer);
05712          }
05713          if (!peer) {
05714             ast_mutex_lock(&iaxsl[callno]);
05715             if (!(p = iaxs[callno]))
05716                return -1;
05717          }
05718       }
05719    }
05720    if (ies->encmethods)
05721       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05722    if (!res)
05723       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05724    return res;
05725 }
05726 
05727 static int iax2_do_register(struct iax2_registry *reg);
05728 
05729 static void __iax2_do_register_s(const void *data)
05730 {
05731    struct iax2_registry *reg = (struct iax2_registry *)data;
05732    reg->expire = -1;
05733    iax2_do_register(reg);
05734 }
05735 
05736 static int iax2_do_register_s(const void *data)
05737 {
05738 #ifdef SCHED_MULTITHREADED
05739    if (schedule_action(__iax2_do_register_s, data))
05740 #endif      
05741       __iax2_do_register_s(data);
05742    return 0;
05743 }
05744 
05745 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05746 {
05747    int newcall = 0;
05748    char newip[256];
05749    struct iax_ie_data ied;
05750    struct sockaddr_in new;
05751    
05752    
05753    memset(&ied, 0, sizeof(ied));
05754    if (ies->apparent_addr)
05755       bcopy(ies->apparent_addr, &new, sizeof(new));
05756    if (ies->callno)
05757       newcall = ies->callno;
05758    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05759       ast_log(LOG_WARNING, "Invalid transfer request\n");
05760       return -1;
05761    }
05762    pvt->transfercallno = newcall;
05763    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05764    inet_aton(newip, &pvt->transfer.sin_addr);
05765    pvt->transfer.sin_family = AF_INET;
05766    pvt->transferring = TRANSFER_BEGIN;
05767    pvt->transferid = ies->transferid;
05768    if (ies->transferid)
05769       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05770    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05771    return 0; 
05772 }
05773 
05774 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05775 {
05776    char exten[256] = "";
05777    int status = CACHE_FLAG_UNKNOWN;
05778    int expiry = iaxdefaultdpcache;
05779    int x;
05780    int matchmore = 0;
05781    struct iax2_dpcache *dp, *prev;
05782    
05783    if (ies->called_number)
05784       ast_copy_string(exten, ies->called_number, sizeof(exten));
05785 
05786    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05787       status = CACHE_FLAG_EXISTS;
05788    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05789       status = CACHE_FLAG_CANEXIST;
05790    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05791       status = CACHE_FLAG_NONEXISTENT;
05792 
05793    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05794       /* Don't really do anything with this */
05795    }
05796    if (ies->refresh)
05797       expiry = ies->refresh;
05798    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05799       matchmore = CACHE_FLAG_MATCHMORE;
05800    ast_mutex_lock(&dpcache_lock);
05801    prev = NULL;
05802    dp = pvt->dpentries;
05803    while(dp) {
05804       if (!strcmp(dp->exten, exten)) {
05805          /* Let them go */
05806          if (prev)
05807             prev->peer = dp->peer;
05808          else
05809             pvt->dpentries = dp->peer;
05810          dp->peer = NULL;
05811          dp->callno = 0;
05812          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05813          if (dp->flags & CACHE_FLAG_PENDING) {
05814             dp->flags &= ~CACHE_FLAG_PENDING;
05815             dp->flags |= status;
05816             dp->flags |= matchmore;
05817          }
05818          /* Wake up waiters */
05819          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05820             if (dp->waiters[x] > -1)
05821                write(dp->waiters[x], "asdf", 4);
05822       }
05823       prev = dp;
05824       dp = dp->peer;
05825    }
05826    ast_mutex_unlock(&dpcache_lock);
05827    return 0;
05828 }
05829 
05830 static int complete_transfer(int callno, struct iax_ies *ies)
05831 {
05832    int peercallno = 0;
05833    struct chan_iax2_pvt *pvt = iaxs[callno];
05834    struct iax_frame *cur;
05835    jb_frame frame;
05836 
05837    if (ies->callno)
05838       peercallno = ies->callno;
05839 
05840    if (peercallno < 1) {
05841       ast_log(LOG_WARNING, "Invalid transfer request\n");
05842       return -1;
05843    }
05844    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05845    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05846    /* Reset sequence numbers */
05847    pvt->oseqno = 0;
05848    pvt->rseqno = 0;
05849    pvt->iseqno = 0;
05850    pvt->aseqno = 0;
05851 
05852    if (pvt->peercallno) {
05853       remove_by_peercallno(pvt);
05854    }
05855    pvt->peercallno = peercallno;
05856    store_by_peercallno(pvt);
05857 
05858    pvt->transferring = TRANSFER_NONE;
05859    pvt->svoiceformat = -1;
05860    pvt->voiceformat = 0;
05861    pvt->svideoformat = -1;
05862    pvt->videoformat = 0;
05863    pvt->transfercallno = -1;
05864    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05865    memset(&pvt->offset, 0, sizeof(pvt->offset));
05866    /* reset jitterbuffer */
05867    while(jb_getall(pvt->jb,&frame) == JB_OK)
05868       iax2_frame_free(frame.data);
05869    jb_reset(pvt->jb);
05870    pvt->lag = 0;
05871    pvt->last = 0;
05872    pvt->lastsent = 0;
05873    pvt->nextpred = 0;
05874    pvt->pingtime = DEFAULT_RETRY_TIME;
05875    AST_LIST_LOCK(&iaxq.queue);
05876    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05877       /* We must cancel any packets that would have been transmitted
05878          because now we're talking to someone new.  It's okay, they
05879          were transmitted to someone that didn't care anyway. */
05880       if (callno == cur->callno) 
05881          cur->retries = -1;
05882    }
05883    AST_LIST_UNLOCK(&iaxq.queue);
05884    return 0; 
05885 }
05886 
05887 /*! \brief Acknowledgment received for OUR registration */
05888 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05889 {
05890    struct iax2_registry *reg;
05891    /* Start pessimistic */
05892    char peer[256] = "";
05893    char msgstatus[60];
05894    int refresh = 60;
05895    char ourip[256] = "<Unspecified>";
05896    struct sockaddr_in oldus;
05897    struct sockaddr_in us;
05898    int oldmsgs;
05899 
05900    memset(&us, 0, sizeof(us));
05901    if (ies->apparent_addr)
05902       bcopy(ies->apparent_addr, &us, sizeof(us));
05903    if (ies->username)
05904       ast_copy_string(peer, ies->username, sizeof(peer));
05905    if (ies->refresh)
05906       refresh = ies->refresh;
05907    if (ies->calling_number) {
05908       /* We don't do anything with it really, but maybe we should */
05909    }
05910    reg = iaxs[callno]->reg;
05911    if (!reg) {
05912       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05913       return -1;
05914    }
05915    memcpy(&oldus, &reg->us, sizeof(oldus));
05916    oldmsgs = reg->messages;
05917    if (inaddrcmp(&reg->addr, sin)) {
05918       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05919       return -1;
05920    }
05921    memcpy(&reg->us, &us, sizeof(reg->us));
05922    if (ies->msgcount >= 0)
05923       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05924    /* always refresh the registration at the interval requested by the server
05925       we are registering to
05926    */
05927    reg->refresh = refresh;
05928    AST_SCHED_DEL(sched, reg->expire);
05929    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05930    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05931       if (option_verbose > 2) {
05932          if (reg->messages > 255)
05933             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05934          else if (reg->messages > 1)
05935             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05936          else if (reg->messages > 0)
05937             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05938          else
05939             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05940          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05941          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05942       }
05943       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05944    }
05945    reg->regstate = REG_STATE_REGISTERED;
05946    return 0;
05947 }
05948 
05949 static int iax2_register(char *value, int lineno)
05950 {
05951    struct iax2_registry *reg;
05952    char copy[256];
05953    char *username, *hostname, *secret;
05954    char *porta;
05955    char *stringp=NULL;
05956    
05957    if (!value)
05958       return -1;
05959    ast_copy_string(copy, value, sizeof(copy));
05960    stringp=copy;
05961    username = strsep(&stringp, "@");
05962    hostname = strsep(&stringp, "@");
05963    if (!hostname) {
05964       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05965       return -1;
05966    }
05967    stringp=username;
05968    username = strsep(&stringp, ":");
05969    secret = strsep(&stringp, ":");
05970    stringp=hostname;
05971    hostname = strsep(&stringp, ":");
05972    porta = strsep(&stringp, ":");
05973    
05974    if (porta && !atoi(porta)) {
05975       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05976       return -1;
05977    }
05978    if (!(reg = ast_calloc(1, sizeof(*reg))))
05979       return -1;
05980    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05981       free(reg);
05982       return -1;
05983    }
05984    ast_copy_string(reg->username, username, sizeof(reg->username));
05985    if (secret)
05986       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05987    reg->expire = -1;
05988    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05989    reg->addr.sin_family = AF_INET;
05990    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05991    AST_LIST_LOCK(&registrations);
05992    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05993    AST_LIST_UNLOCK(&registrations);
05994    
05995    return 0;
05996 }
05997 
05998 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05999 {
06000    char multi[256];
06001    char *stringp, *ext;
06002    if (!ast_strlen_zero(regcontext)) {
06003       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06004       stringp = multi;
06005       while((ext = strsep(&stringp, "&"))) {
06006          if (onoff) {
06007             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06008                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06009                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06010          } else
06011             ast_context_remove_extension(regcontext, ext, 1, NULL);
06012       }
06013    }
06014 }
06015 static void prune_peers(void);
06016 
06017 static void unlink_peer(struct iax2_peer *peer)
06018 {
06019    if (peer->expire > -1) {
06020       if (!ast_sched_del(sched, peer->expire)) {
06021          peer->expire = -1;
06022          peer_unref(peer);
06023       }
06024    }
06025 
06026    if (peer->pokeexpire > -1) {
06027       if (!ast_sched_del(sched, peer->pokeexpire)) {
06028          peer->pokeexpire = -1;
06029          peer_unref(peer);
06030       }
06031    }
06032 
06033    ao2_unlink(peers, peer);
06034 }
06035 
06036 static void __expire_registry(const void *data)
06037 {
06038    struct iax2_peer *peer = (struct iax2_peer *) data;
06039 
06040    if (!peer)
06041       return;
06042 
06043    peer->expire = -1;
06044 
06045    if (option_debug)
06046       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06047    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06048       realtime_update_peer(peer->name, &peer->addr, 0);
06049    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06050    /* Reset the address */
06051    memset(&peer->addr, 0, sizeof(peer->addr));
06052    /* Reset expiry value */
06053    peer->expiry = min_reg_expire;
06054    if (!ast_test_flag(peer, IAX_TEMPONLY))
06055       ast_db_del("IAX/Registry", peer->name);
06056    register_peer_exten(peer, 0);
06057    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06058    if (iax2_regfunk)
06059       iax2_regfunk(peer->name, 0);
06060 
06061    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06062       unlink_peer(peer);
06063 
06064    peer_unref(peer);
06065 }
06066 
06067 static int expire_registry(const void *data)
06068 {
06069 #ifdef SCHED_MULTITHREADED
06070    if (schedule_action(__expire_registry, data))
06071 #endif      
06072       __expire_registry(data);
06073    return 0;
06074 }
06075 
06076 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06077 
06078 static void reg_source_db(struct iax2_peer *p)
06079 {
06080    char data[80];
06081    struct in_addr in;
06082    char *c, *d;
06083    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06084       c = strchr(data, ':');
06085       if (c) {
06086          *c = '\0';
06087          c++;
06088          if (inet_aton(data, &in)) {
06089             d = strchr(c, ':');
06090             if (d) {
06091                *d = '\0';
06092                d++;
06093                if (option_verbose > 2)
06094                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06095                   ast_inet_ntoa(in), atoi(c), atoi(d));
06096                iax2_poke_peer(p, 0);
06097                p->expiry = atoi(d);
06098                memset(&p->addr, 0, sizeof(p->addr));
06099                p->addr.sin_family = AF_INET;
06100                p->addr.sin_addr = in;
06101                p->addr.sin_port = htons(atoi(c));
06102                if (p->expire > -1) {
06103                   if (!ast_sched_del(sched, p->expire)) {
06104                      p->expire = -1;
06105                      peer_unref(p);
06106                   }
06107                }
06108                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06109                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06110                if (p->expire == -1)
06111                   peer_unref(p);
06112                if (iax2_regfunk)
06113                   iax2_regfunk(p->name, 1);
06114                register_peer_exten(p, 1);
06115             }              
06116                
06117          }
06118       }
06119    }
06120 }
06121 
06122 /*!
06123  * \pre iaxsl[callno] is locked
06124  *
06125  * \note Since this function calls send_command_final(), the pvt struct for
06126  *       the given call number may disappear while executing this function.
06127  */
06128 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06129 {
06130    /* Called from IAX thread only, with proper iaxsl lock */
06131    struct iax_ie_data ied;
06132    struct iax2_peer *p;
06133    int msgcount;
06134    char data[80];
06135    int version;
06136    const char *peer_name;
06137    int res = -1;
06138 
06139    memset(&ied, 0, sizeof(ied));
06140 
06141    peer_name = ast_strdupa(iaxs[callno]->peer);
06142 
06143    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06144    ast_mutex_unlock(&iaxsl[callno]);
06145    if (!(p = find_peer(peer_name, 1))) {
06146       ast_mutex_lock(&iaxsl[callno]);
06147       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06148       return -1;
06149    }
06150    ast_mutex_lock(&iaxsl[callno]);
06151    if (!iaxs[callno])
06152       goto return_unref;
06153 
06154    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06155       if (sin->sin_addr.s_addr) {
06156          time_t nowtime;
06157          time(&nowtime);
06158          realtime_update_peer(peer_name, sin, nowtime);
06159       } else {
06160          realtime_update_peer(peer_name, sin, 0);
06161       }
06162    }
06163    if (inaddrcmp(&p->addr, sin)) {
06164       if (iax2_regfunk)
06165          iax2_regfunk(p->name, 1);
06166       /* Stash the IP address from which they registered */
06167       memcpy(&p->addr, sin, sizeof(p->addr));
06168       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06169       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06170          ast_db_put("IAX/Registry", p->name, data);
06171          if  (option_verbose > 2)
06172             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06173                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06174          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06175          register_peer_exten(p, 1);
06176          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06177       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06178          if  (option_verbose > 2)
06179             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06180                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06181          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06182          register_peer_exten(p, 0);
06183          ast_db_del("IAX/Registry", p->name);
06184          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06185       }
06186       /* Update the host */
06187       /* Verify that the host is really there */
06188       iax2_poke_peer(p, callno);
06189    }     
06190 
06191    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06192    if (!iaxs[callno]) {
06193       res = 0;
06194       goto return_unref;
06195    }
06196 
06197    /* Store socket fd */
06198    p->sockfd = fd;
06199    /* Setup the expiry */
06200    if (p->expire > -1) {
06201       if (!ast_sched_del(sched, p->expire)) {
06202          p->expire = -1;
06203          peer_unref(p);
06204       }
06205    }
06206    /* treat an unspecified refresh interval as the minimum */
06207    if (!refresh)
06208       refresh = min_reg_expire;
06209    if (refresh > max_reg_expire) {
06210       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06211          p->name, max_reg_expire, refresh);
06212       p->expiry = max_reg_expire;
06213    } else if (refresh < min_reg_expire) {
06214       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06215          p->name, min_reg_expire, refresh);
06216       p->expiry = min_reg_expire;
06217    } else {
06218       p->expiry = refresh;
06219    }
06220    if (p->expiry && sin->sin_addr.s_addr) {
06221       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06222       if (p->expire == -1)
06223          peer_unref(p);
06224    }
06225    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06226    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06227    if (sin->sin_addr.s_addr) {
06228       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06229       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06230       if (!ast_strlen_zero(p->mailbox)) {
06231          int new, old;
06232          ast_app_inboxcount(p->mailbox, &new, &old);
06233          if (new > 255)
06234             new = 255;
06235          if (old > 255)
06236             old = 255;
06237          msgcount = (old << 8) | new;
06238          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06239       }
06240       if (ast_test_flag(p, IAX_HASCALLERID)) {
06241          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06242          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06243       }
06244    }
06245    version = iax_check_version(devtype);
06246    if (version) 
06247       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06248 
06249    res = 0;
06250 
06251 return_unref:
06252    peer_unref(p);
06253 
06254    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06255 }
06256 
06257 static int registry_authrequest(int callno)
06258 {
06259    struct iax_ie_data ied;
06260    struct iax2_peer *p;
06261    char challenge[10];
06262    const char *peer_name;
06263    int res = -1;
06264 
06265    peer_name = ast_strdupa(iaxs[callno]->peer);
06266 
06267    /* SLD: third call to find_peer in registration */
06268    ast_mutex_unlock(&iaxsl[callno]);
06269    p = find_peer(peer_name, 1);
06270    ast_mutex_lock(&iaxsl[callno]);
06271    if (!iaxs[callno])
06272       goto return_unref;
06273    if (!p) {
06274       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06275       goto return_unref;
06276    }
06277    
06278    memset(&ied, 0, sizeof(ied));
06279    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06280    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06281       /* Build the challenge */
06282       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06283       ast_string_field_set(iaxs[callno], challenge, challenge);
06284       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06285    }
06286    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06287 
06288    res = 0;
06289 
06290 return_unref:
06291    peer_unref(p);
06292 
06293    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06294 }
06295 
06296 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06297 {
06298    struct iax2_registry *reg;
06299    /* Start pessimistic */
06300    struct iax_ie_data ied;
06301    char peer[256] = "";
06302    char challenge[256] = "";
06303    int res;
06304    int authmethods = 0;
06305    if (ies->authmethods)
06306       authmethods = ies->authmethods;
06307    if (ies->username)
06308       ast_copy_string(peer, ies->username, sizeof(peer));
06309    if (ies->challenge)
06310       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06311    memset(&ied, 0, sizeof(ied));
06312    reg = iaxs[callno]->reg;
06313    if (reg) {
06314          if (inaddrcmp(&reg->addr, sin)) {
06315             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06316             return -1;
06317          }
06318          if (ast_strlen_zero(reg->secret)) {
06319             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06320             reg->regstate = REG_STATE_NOAUTH;
06321             return -1;
06322          }
06323          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06324          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06325          if (reg->secret[0] == '[') {
06326             char tmpkey[256];
06327             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06328             tmpkey[strlen(tmpkey) - 1] = '\0';
06329             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06330          } else
06331             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06332          if (!res) {
06333             reg->regstate = REG_STATE_AUTHSENT;
06334             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06335          } else
06336             return -1;
06337          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06338    } else   
06339       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06340    return -1;
06341 }
06342 
06343 static void stop_stuff(int callno)
06344 {
06345    iax2_destroy_helper(iaxs[callno]);
06346 }
06347 
06348 static void __auth_reject(const void *nothing)
06349 {
06350    /* Called from IAX thread only, without iaxs lock */
06351    int callno = (int)(long)(nothing);
06352    struct iax_ie_data ied;
06353    ast_mutex_lock(&iaxsl[callno]);
06354    if (iaxs[callno]) {
06355       memset(&ied, 0, sizeof(ied));
06356       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06357          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06358          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06359       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06360          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06361          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06362       }
06363       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06364    }
06365    ast_mutex_unlock(&iaxsl[callno]);
06366 }
06367 
06368 static int auth_reject(const void *data)
06369 {
06370    int callno = (int)(long)(data);
06371    ast_mutex_lock(&iaxsl[callno]);
06372    if (iaxs[callno])
06373       iaxs[callno]->authid = -1;
06374    ast_mutex_unlock(&iaxsl[callno]);
06375 #ifdef SCHED_MULTITHREADED
06376    if (schedule_action(__auth_reject, data))
06377 #endif      
06378       __auth_reject(data);
06379    return 0;
06380 }
06381 
06382 static int auth_fail(int callno, int failcode)
06383 {
06384    /* Schedule sending the authentication failure in one second, to prevent
06385       guessing */
06386    if (iaxs[callno]) {
06387       iaxs[callno]->authfail = failcode;
06388       if (delayreject) {
06389          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06390          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06391       } else
06392          auth_reject((void *)(long)callno);
06393    }
06394    return 0;
06395 }
06396 
06397 static void __auto_hangup(const void *nothing)
06398 {
06399    /* Called from IAX thread only, without iaxs lock */
06400    int callno = (int)(long)(nothing);
06401    struct iax_ie_data ied;
06402    ast_mutex_lock(&iaxsl[callno]);
06403    if (iaxs[callno]) {
06404       memset(&ied, 0, sizeof(ied));
06405       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06406       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06407       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06408    }
06409    ast_mutex_unlock(&iaxsl[callno]);
06410 }
06411 
06412 static int auto_hangup(const void *data)
06413 {
06414    int callno = (int)(long)(data);
06415    ast_mutex_lock(&iaxsl[callno]);
06416    if (iaxs[callno]) {
06417       iaxs[callno]->autoid = -1;
06418    }
06419    ast_mutex_unlock(&iaxsl[callno]);
06420 #ifdef SCHED_MULTITHREADED
06421    if (schedule_action(__auto_hangup, data))
06422 #endif      
06423       __auto_hangup(data);
06424    return 0;
06425 }
06426 
06427 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06428 {
06429    struct iax_ie_data ied;
06430    /* Auto-hangup with 30 seconds of inactivity */
06431    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06432    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06433    memset(&ied, 0, sizeof(ied));
06434    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06435    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06436    dp->flags |= CACHE_FLAG_TRANSMITTED;
06437 }
06438 
06439 static int iax2_vnak(int callno)
06440 {
06441    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06442 }
06443 
06444 static void vnak_retransmit(int callno, int last)
06445 {
06446    struct iax_frame *f;
06447 
06448    AST_LIST_LOCK(&iaxq.queue);
06449    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06450       /* Send a copy immediately */
06451       if ((f->callno == callno) && iaxs[f->callno] &&
06452          ((unsigned char ) (f->oseqno - last) < 128) &&
06453          (f->retries >= 0)) {
06454          send_packet(f);
06455       }
06456    }
06457    AST_LIST_UNLOCK(&iaxq.queue);
06458 }
06459 
06460 static void __iax2_poke_peer_s(const void *data)
06461 {
06462    struct iax2_peer *peer = (struct iax2_peer *)data;
06463    iax2_poke_peer(peer, 0);
06464    peer_unref(peer);
06465 }
06466 
06467 static int iax2_poke_peer_s(const void *data)
06468 {
06469    struct iax2_peer *peer = (struct iax2_peer *)data;
06470    peer->pokeexpire = -1;
06471 #ifdef SCHED_MULTITHREADED
06472    if (schedule_action(__iax2_poke_peer_s, data))
06473 #endif      
06474       __iax2_poke_peer_s(data);
06475    return 0;
06476 }
06477 
06478 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06479 {
06480    int res = 0;
06481    struct iax_frame *fr;
06482    struct ast_iax2_meta_hdr *meta;
06483    struct ast_iax2_meta_trunk_hdr *mth;
06484    int calls = 0;
06485    
06486    /* Point to frame */
06487    fr = (struct iax_frame *)tpeer->trunkdata;
06488    /* Point to meta data */
06489    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06490    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06491    if (tpeer->trunkdatalen) {
06492       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06493       meta->zeros = 0;
06494       meta->metacmd = IAX_META_TRUNK;
06495       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06496          meta->cmddata = IAX_META_TRUNK_MINI;
06497       else
06498          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06499       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06500       /* And the rest of the ast_iax2 header */
06501       fr->direction = DIRECTION_OUTGRESS;
06502       fr->retrans = -1;
06503       fr->transfer = 0;
06504       /* Any appropriate call will do */
06505       fr->data = fr->afdata;
06506       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06507       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06508       calls = tpeer->calls;
06509 #if 0
06510       if (option_debug)
06511          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));
06512 #endif      
06513       /* Reset transmit trunk side data */
06514       tpeer->trunkdatalen = 0;
06515       tpeer->calls = 0;
06516    }
06517    if (res < 0)
06518       return res;
06519    return calls;
06520 }
06521 
06522 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06523 {
06524    /* Drop when trunk is about 5 seconds idle */
06525    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06526       return 1;
06527    return 0;
06528 }
06529 
06530 static int timing_read(int *id, int fd, short events, void *cbdata)
06531 {
06532    char buf[1024];
06533    int res;
06534    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06535    int processed = 0;
06536    int totalcalls = 0;
06537 #ifdef ZT_TIMERACK
06538    int x = 1;
06539 #endif
06540    struct timeval now;
06541    if (iaxtrunkdebug)
06542       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06543    gettimeofday(&now, NULL);
06544    if (events & AST_IO_PRI) {
06545 #ifdef ZT_TIMERACK
06546       /* Great, this is a timing interface, just call the ioctl */
06547       if (ioctl(fd, ZT_TIMERACK, &x)) {
06548          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06549          usleep(1);
06550          return -1;
06551       }
06552 #endif      
06553    } else {
06554       /* Read and ignore from the pseudo channel for timing */
06555       res = read(fd, buf, sizeof(buf));
06556       if (res < 1) {
06557          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06558          return 1;
06559       }
06560    }
06561    /* For each peer that supports trunking... */
06562    ast_mutex_lock(&tpeerlock);
06563    tpeer = tpeers;
06564    while(tpeer) {
06565       processed++;
06566       res = 0;
06567       ast_mutex_lock(&tpeer->lock);
06568       /* We can drop a single tpeer per pass.  That makes all this logic
06569          substantially easier */
06570       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06571          /* Take it out of the list, but don't free it yet, because it
06572             could be in use */
06573          if (prev)
06574             prev->next = tpeer->next;
06575          else
06576             tpeers = tpeer->next;
06577          drop = tpeer;
06578       } else {
06579          res = send_trunk(tpeer, &now);
06580          if (iaxtrunkdebug)
06581             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);
06582       }     
06583       totalcalls += res;   
06584       res = 0;
06585       ast_mutex_unlock(&tpeer->lock);
06586       prev = tpeer;
06587       tpeer = tpeer->next;
06588    }
06589    ast_mutex_unlock(&tpeerlock);
06590    if (drop) {
06591       ast_mutex_lock(&drop->lock);
06592       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06593          because by the time they could get tpeerlock, we've already grabbed it */
06594       if (option_debug)
06595          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06596       if (drop->trunkdata) {
06597          free(drop->trunkdata);
06598          drop->trunkdata = NULL;
06599       }
06600       ast_mutex_unlock(&drop->lock);
06601       ast_mutex_destroy(&drop->lock);
06602       free(drop);
06603       
06604    }
06605    if (iaxtrunkdebug)
06606       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06607    iaxtrunkdebug =0;
06608    return 1;
06609 }
06610 
06611 struct dpreq_data {
06612    int callno;
06613    char context[AST_MAX_EXTENSION];
06614    char callednum[AST_MAX_EXTENSION];
06615    char *callerid;
06616 };
06617 
06618 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06619 {
06620    unsigned short dpstatus = 0;
06621    struct iax_ie_data ied1;
06622    int mm;
06623 
06624    memset(&ied1, 0, sizeof(ied1));
06625    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06626    /* Must be started */
06627    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06628       dpstatus = IAX_DPSTATUS_EXISTS;
06629    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06630       dpstatus = IAX_DPSTATUS_CANEXIST;
06631    } else {
06632       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06633    }
06634    if (ast_ignore_pattern(context, callednum))
06635       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06636    if (mm)
06637       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06638    if (!skiplock)
06639       ast_mutex_lock(&iaxsl[callno]);
06640    if (iaxs[callno]) {
06641       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06642       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06643       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06644       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06645    }
06646    if (!skiplock)
06647       ast_mutex_unlock(&iaxsl[callno]);
06648 }
06649 
06650 static void *dp_lookup_thread(void *data)
06651 {
06652    /* Look up for dpreq */
06653    struct dpreq_data *dpr = data;
06654    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06655    if (dpr->callerid)
06656       free(dpr->callerid);
06657    free(dpr);
06658    return NULL;
06659 }
06660 
06661 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06662 {
06663    pthread_t newthread;
06664    struct dpreq_data *dpr;
06665    pthread_attr_t attr;
06666    
06667    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06668       return;
06669 
06670    pthread_attr_init(&attr);
06671    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06672 
06673    dpr->callno = callno;
06674    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06675    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06676    if (callerid)
06677       dpr->callerid = ast_strdup(callerid);
06678    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06679       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06680    }
06681 
06682    pthread_attr_destroy(&attr);
06683 }
06684 
06685 struct iax_dual {
06686    struct ast_channel *chan1;
06687    struct ast_channel *chan2;
06688 };
06689 
06690 static void *iax_park_thread(void *stuff)
06691 {
06692    struct ast_channel *chan1, *chan2;
06693    struct iax_dual *d;
06694    struct ast_frame *f;
06695    int ext;
06696    int res;
06697    d = stuff;
06698    chan1 = d->chan1;
06699    chan2 = d->chan2;
06700    free(d);
06701    f = ast_read(chan1);
06702    if (f)
06703       ast_frfree(f);
06704    res = ast_park_call(chan1, chan2, 0, &ext);
06705    ast_hangup(chan2);
06706    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06707    return NULL;
06708 }
06709 
06710 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06711 {
06712    struct iax_dual *d;
06713    struct ast_channel *chan1m, *chan2m;
06714    pthread_t th;
06715    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06716    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06717    if (chan2m && chan1m) {
06718       /* Make formats okay */
06719       chan1m->readformat = chan1->readformat;
06720       chan1m->writeformat = chan1->writeformat;
06721       ast_channel_masquerade(chan1m, chan1);
06722       /* Setup the extensions and such */
06723       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06724       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06725       chan1m->priority = chan1->priority;
06726       
06727       /* We make a clone of the peer channel too, so we can play
06728          back the announcement */
06729       /* Make formats okay */
06730       chan2m->readformat = chan2->readformat;
06731       chan2m->writeformat = chan2->writeformat;
06732       ast_channel_masquerade(chan2m, chan2);
06733       /* Setup the extensions and such */
06734       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06735       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06736       chan2m->priority = chan2->priority;
06737       if (ast_do_masquerade(chan2m)) {
06738          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06739          ast_hangup(chan2m);
06740          return -1;
06741       }
06742    } else {
06743       if (chan1m)
06744          ast_hangup(chan1m);
06745       if (chan2m)
06746          ast_hangup(chan2m);
06747       return -1;
06748    }
06749    if ((d = ast_calloc(1, sizeof(*d)))) {
06750       pthread_attr_t attr;
06751 
06752       pthread_attr_init(&attr);
06753       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06754 
06755       d->chan1 = chan1m;
06756       d->chan2 = chan2m;
06757       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06758          pthread_attr_destroy(&attr);
06759          return 0;
06760       }
06761       pthread_attr_destroy(&attr);
06762       free(d);
06763    }
06764    return -1;
06765 }
06766 
06767 
06768 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06769 
06770 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06771 {
06772    unsigned int ourver;
06773    char rsi[80];
06774    snprintf(rsi, sizeof(rsi), "si-%s", si);
06775    if (iax_provision_version(&ourver, rsi, 1))
06776       return 0;
06777    if (option_debug)
06778       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06779    if (ourver != ver) 
06780       iax2_provision(sin, sockfd, NULL, rsi, 1);
06781    return 0;
06782 }
06783 
06784 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06785 {
06786    jb_info stats;
06787    jb_getinfo(pvt->jb, &stats);
06788    
06789    memset(iep, 0, sizeof(*iep));
06790 
06791    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06792    if(stats.frames_in == 0) stats.frames_in = 1;
06793    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06794    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06795    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06796    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06797    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06798 }
06799 
06800 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06801 {
06802    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06803    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06804    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06805    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06806    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06807    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06808    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06809 }
06810 
06811 static int socket_process(struct iax2_thread *thread);
06812 
06813 /*!
06814  * \brief Handle any deferred full frames for this thread
06815  */
06816 static void handle_deferred_full_frames(struct iax2_thread *thread)
06817 {
06818    struct iax2_pkt_buf *pkt_buf;
06819 
06820    ast_mutex_lock(&thread->lock);
06821 
06822    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06823       ast_mutex_unlock(&thread->lock);
06824 
06825       thread->buf = pkt_buf->buf;
06826       thread->buf_len = pkt_buf->len;
06827       thread->buf_size = pkt_buf->len + 1;
06828       
06829       socket_process(thread);
06830 
06831       thread->buf = NULL;
06832       ast_free(pkt_buf);
06833 
06834       ast_mutex_lock(&thread->lock);
06835    }
06836 
06837    ast_mutex_unlock(&thread->lock);
06838 }
06839 
06840 /*!
06841  * \brief Queue the last read full frame for processing by a certain thread
06842  *
06843  * If there are already any full frames queued, they are sorted
06844  * by sequence number.
06845  */
06846 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06847 {
06848    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06849    struct ast_iax2_full_hdr *fh, *cur_fh;
06850 
06851    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06852       return;
06853 
06854    pkt_buf->len = from_here->buf_len;
06855    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06856 
06857    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06858    ast_mutex_lock(&to_here->lock);
06859    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06860       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06861       if (fh->oseqno < cur_fh->oseqno) {
06862          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06863          break;
06864       }
06865    }
06866    AST_LIST_TRAVERSE_SAFE_END
06867 
06868    if (!cur_pkt_buf)
06869       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06870    
06871    ast_mutex_unlock(&to_here->lock);
06872 }
06873 
06874 static int socket_read(int *id, int fd, short events, void *cbdata)
06875 {
06876    struct iax2_thread *thread;
06877    socklen_t len;
06878    time_t t;
06879    static time_t last_errtime = 0;
06880    struct ast_iax2_full_hdr *fh;
06881 
06882    if (!(thread = find_idle_thread())) {
06883       time(&t);
06884       if (t != last_errtime && option_debug)
06885          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06886       last_errtime = t;
06887       usleep(1);
06888       return 1;
06889    }
06890 
06891    len = sizeof(thread->iosin);
06892    thread->iofd = fd;
06893    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06894    thread->buf_size = sizeof(thread->readbuf);
06895    thread->buf = thread->readbuf;
06896    if (thread->buf_len < 0) {
06897       if (errno != ECONNREFUSED && errno != EAGAIN)
06898          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06899       handle_error();
06900       thread->iostate = IAX_IOSTATE_IDLE;
06901       signal_condition(&thread->lock, &thread->cond);
06902       return 1;
06903    }
06904    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06905       thread->iostate = IAX_IOSTATE_IDLE;
06906       signal_condition(&thread->lock, &thread->cond);
06907       return 1;
06908    }
06909    
06910    /* Determine if this frame is a full frame; if so, and any thread is currently
06911       processing a full frame for the same callno from this peer, then drop this
06912       frame (and the peer will retransmit it) */
06913    fh = (struct ast_iax2_full_hdr *) thread->buf;
06914    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06915       struct iax2_thread *cur = NULL;
06916       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06917       
06918       AST_LIST_LOCK(&active_list);
06919       AST_LIST_TRAVERSE(&active_list, cur, list) {
06920          if ((cur->ffinfo.callno == callno) &&
06921              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06922             break;
06923       }
06924       if (cur) {
06925          /* we found another thread processing a full frame for this call,
06926             so queue it up for processing later. */
06927          defer_full_frame(thread, cur);
06928          AST_LIST_UNLOCK(&active_list);
06929          thread->iostate = IAX_IOSTATE_IDLE;
06930          signal_condition(&thread->lock, &thread->cond);
06931          return 1;
06932       } else {
06933          /* this thread is going to process this frame, so mark it */
06934          thread->ffinfo.callno = callno;
06935          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06936          thread->ffinfo.type = fh->type;
06937          thread->ffinfo.csub = fh->csub;
06938       }
06939       AST_LIST_UNLOCK(&active_list);
06940    }
06941    
06942    /* Mark as ready and send on its way */
06943    thread->iostate = IAX_IOSTATE_READY;
06944 #ifdef DEBUG_SCHED_MULTITHREAD
06945    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06946 #endif
06947    signal_condition(&thread->lock, &thread->cond);
06948 
06949    return 1;
06950 }
06951 
06952 static int socket_process(struct iax2_thread *thread)
06953 {
06954    struct sockaddr_in sin;
06955    int res;
06956    int updatehistory=1;
06957    int new = NEW_PREVENT;
06958    void *ptr;
06959    int dcallno = 0;
06960    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06961    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06962    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06963    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06964    struct ast_iax2_meta_trunk_hdr *mth;
06965    struct ast_iax2_meta_trunk_entry *mte;
06966    struct ast_iax2_meta_trunk_mini *mtm;
06967    struct iax_frame *fr;
06968    struct iax_frame *cur;
06969    struct ast_frame f = { 0, };
06970    struct ast_channel *c;
06971    struct iax2_dpcache *dp;
06972    struct iax2_peer *peer;
06973    struct iax2_trunk_peer *tpeer;
06974    struct timeval rxtrunktime;
06975    struct iax_ies ies;
06976    struct iax_ie_data ied0, ied1;
06977    int format;
06978    int fd;
06979    int exists;
06980    int minivid = 0;
06981    unsigned int ts;
06982    char empty[32]="";      /* Safety measure */
06983    struct iax_frame *duped_fr;
06984    char host_pref_buf[128];
06985    char caller_pref_buf[128];
06986    struct ast_codec_pref pref;
06987    char *using_prefs = "mine";
06988 
06989    /* allocate an iax_frame with 4096 bytes of data buffer */
06990    fr = alloca(sizeof(*fr) + 4096);
06991    memset(fr, 0, sizeof(*fr));
06992    fr->afdatalen = 4096; /* From alloca() above */
06993 
06994    /* Copy frequently used parameters to the stack */
06995    res = thread->buf_len;
06996    fd = thread->iofd;
06997    memcpy(&sin, &thread->iosin, sizeof(sin));
06998 
06999    if (res < sizeof(*mh)) {
07000       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07001       return 1;
07002    }
07003    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07004       if (res < sizeof(*vh)) {
07005          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));
07006          return 1;
07007       }
07008 
07009       /* This is a video frame, get call number */
07010       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07011       minivid = 1;
07012    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07013       unsigned char metatype;
07014 
07015       if (res < sizeof(*meta)) {
07016          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));
07017          return 1;
07018       }
07019 
07020       /* This is a meta header */
07021       switch(meta->metacmd) {
07022       case IAX_META_TRUNK:
07023          if (res < (sizeof(*meta) + sizeof(*mth))) {
07024             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07025                sizeof(*meta) + sizeof(*mth));
07026             return 1;
07027          }
07028          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07029          ts = ntohl(mth->ts);
07030          metatype = meta->cmddata;
07031          res -= (sizeof(*meta) + sizeof(*mth));
07032          ptr = mth->data;
07033          tpeer = find_tpeer(&sin, fd);
07034          if (!tpeer) {
07035             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));
07036             return 1;
07037          }
07038          tpeer->trunkact = ast_tvnow();
07039          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07040             tpeer->rxtrunktime = tpeer->trunkact;
07041          rxtrunktime = tpeer->rxtrunktime;
07042          ast_mutex_unlock(&tpeer->lock);
07043          while(res >= sizeof(*mte)) {
07044             /* Process channels */
07045             unsigned short callno, trunked_ts, len;
07046 
07047             if (metatype == IAX_META_TRUNK_MINI) {
07048                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07049                ptr += sizeof(*mtm);
07050                res -= sizeof(*mtm);
07051                len = ntohs(mtm->len);
07052                callno = ntohs(mtm->mini.callno);
07053                trunked_ts = ntohs(mtm->mini.ts);
07054             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07055                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07056                ptr += sizeof(*mte);
07057                res -= sizeof(*mte);
07058                len = ntohs(mte->len);
07059                callno = ntohs(mte->callno);
07060                trunked_ts = 0;
07061             } else {
07062                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07063                break;
07064             }
07065             /* Stop if we don't have enough data */
07066             if (len > res)
07067                break;
07068             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07069             if (fr->callno) {
07070                /* If it's a valid call, deliver the contents.  If not, we
07071                   drop it, since we don't have a scallno to use for an INVAL */
07072                /* Process as a mini frame */
07073                memset(&f, 0, sizeof(f));
07074                f.frametype = AST_FRAME_VOICE;
07075                if (iaxs[fr->callno]) {
07076                   if (iaxs[fr->callno]->voiceformat > 0) {
07077                      f.subclass = iaxs[fr->callno]->voiceformat;
07078                      f.datalen = len;
07079                      if (f.datalen >= 0) {
07080                         if (f.datalen)
07081                            f.data = ptr;
07082                         if(trunked_ts) {
07083                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07084                         } else
07085                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07086                         /* Don't pass any packets until we're started */
07087                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07088                            /* Common things */
07089                            f.src = "IAX2";
07090                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07091                               f.samples = ast_codec_get_samples(&f);
07092                            iax_frame_wrap(fr, &f);
07093                            duped_fr = iaxfrdup2(fr);
07094                            if (duped_fr) {
07095                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07096                            }
07097                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07098                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07099                               iaxs[fr->callno]->last = fr->ts;
07100 #if 1
07101                               if (option_debug && iaxdebug)
07102                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07103 #endif
07104                            }
07105                         }
07106                      } else {
07107                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07108                      }
07109                   } else {
07110                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07111                      iax2_vnak(fr->callno);
07112                   }
07113                }
07114                ast_mutex_unlock(&iaxsl[fr->callno]);
07115             }
07116             ptr += len;
07117             res -= len;
07118          }
07119          
07120       }
07121       return 1;
07122    }
07123 
07124 #ifdef DEBUG_SUPPORT
07125    if (iaxdebug && (res >= sizeof(*fh)))
07126       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07127 #endif
07128    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07129       if (res < sizeof(*fh)) {
07130          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));
07131          return 1;
07132       }
07133 
07134       /* Get the destination call number */
07135       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07136       /* Retrieve the type and subclass */
07137       f.frametype = fh->type;
07138       if (f.frametype == AST_FRAME_VIDEO) {
07139          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07140       } else {
07141          f.subclass = uncompress_subclass(fh->csub);
07142       }
07143 
07144       /* Deal with POKE/PONG without allocating a callno */
07145       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07146          /* Reply back with a PONG, but don't care about the result. */
07147          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07148          return 1;
07149       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07150          /* Ignore */
07151          return 1;
07152       }
07153 
07154       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07155                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07156                          (f.subclass == IAX_COMMAND_REGREL)))
07157          new = NEW_ALLOW;
07158    } else {
07159       /* Don't know anything about it yet */
07160       f.frametype = AST_FRAME_NULL;
07161       f.subclass = 0;
07162    }
07163 
07164    if (!fr->callno) {
07165       int check_dcallno = 0;
07166 
07167       /*
07168        * We enforce accurate destination call numbers for all full frames except
07169        * LAGRQ and PING commands.  This is because older versions of Asterisk
07170        * schedule these commands to get sent very quickly, and they will sometimes
07171        * be sent before they receive the first frame from the other side.  When
07172        * that happens, it doesn't contain the destination call number.  However,
07173        * not checking it for these frames is safe.
07174        * 
07175        * Discussed in the following thread:
07176        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07177        */
07178 
07179       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07180          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07181       }
07182 
07183       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07184    }
07185 
07186    if (fr->callno > 0)
07187       ast_mutex_lock(&iaxsl[fr->callno]);
07188 
07189    if (!fr->callno || !iaxs[fr->callno]) {
07190       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07191          frame, reply with an inval */
07192       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07193          /* We can only raw hangup control frames */
07194          if (((f.subclass != IAX_COMMAND_INVAL) &&
07195              (f.subclass != IAX_COMMAND_TXCNT) &&
07196              (f.subclass != IAX_COMMAND_TXACC) &&
07197              (f.subclass != IAX_COMMAND_FWDOWNL))||
07198              (f.frametype != AST_FRAME_IAX))
07199             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07200             fd);
07201       }
07202       if (fr->callno > 0) 
07203          ast_mutex_unlock(&iaxsl[fr->callno]);
07204       return 1;
07205    }
07206    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07207       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07208          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07209          ast_mutex_unlock(&iaxsl[fr->callno]);
07210          return 1;
07211       }
07212 #ifdef DEBUG_SUPPORT
07213       else if (iaxdebug)
07214          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07215 #endif
07216    }
07217 
07218    /* count this frame */
07219    iaxs[fr->callno]->frames_received++;
07220 
07221    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07222       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07223       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07224       unsigned short new_peercallno;
07225 
07226       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07227       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07228          if (iaxs[fr->callno]->peercallno) {
07229             remove_by_peercallno(iaxs[fr->callno]);
07230          }
07231          iaxs[fr->callno]->peercallno = new_peercallno;
07232          store_by_peercallno(iaxs[fr->callno]);
07233       }
07234    }
07235    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07236       if (option_debug  && iaxdebug)
07237          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07238       /* Check if it's out of order (and not an ACK or INVAL) */
07239       fr->oseqno = fh->oseqno;
07240       fr->iseqno = fh->iseqno;
07241       fr->ts = ntohl(fh->ts);
07242 #ifdef IAXTESTS
07243       if (test_resync) {
07244          if (option_debug)
07245             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07246          fr->ts += test_resync;
07247       }
07248 #endif /* IAXTESTS */
07249 #if 0
07250       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07251            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07252                         (f.subclass == IAX_COMMAND_NEW ||
07253                          f.subclass == IAX_COMMAND_AUTHREQ ||
07254                          f.subclass == IAX_COMMAND_ACCEPT ||
07255                          f.subclass == IAX_COMMAND_REJECT))      ) )
07256 #endif
07257       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07258          updatehistory = 0;
07259       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07260          (iaxs[fr->callno]->iseqno ||
07261             ((f.subclass != IAX_COMMAND_TXCNT) &&
07262             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07263             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07264             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07265             (f.subclass != IAX_COMMAND_TXACC)) ||
07266             (f.frametype != AST_FRAME_IAX))) {
07267          if (
07268           ((f.subclass != IAX_COMMAND_ACK) &&
07269            (f.subclass != IAX_COMMAND_INVAL) &&
07270            (f.subclass != IAX_COMMAND_TXCNT) &&
07271            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07272            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07273            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07274            (f.subclass != IAX_COMMAND_TXACC) &&
07275            (f.subclass != IAX_COMMAND_VNAK)) ||
07276            (f.frametype != AST_FRAME_IAX)) {
07277             /* If it's not an ACK packet, it's out of order. */
07278             if (option_debug)
07279                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07280                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07281             /* Check to see if we need to request retransmission,
07282              * and take sequence number wraparound into account */
07283             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07284                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07285                if ((f.frametype != AST_FRAME_IAX) || 
07286                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07287                   if (option_debug)
07288                      ast_log(LOG_DEBUG, "Acking anyway\n");
07289                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07290                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07291                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07292                }
07293             } else {
07294                /* Send a VNAK requesting retransmission */
07295                iax2_vnak(fr->callno);
07296             }
07297             ast_mutex_unlock(&iaxsl[fr->callno]);
07298             return 1;
07299          }
07300       } else {
07301          /* Increment unless it's an ACK or VNAK */
07302          if (((f.subclass != IAX_COMMAND_ACK) &&
07303              (f.subclass != IAX_COMMAND_INVAL) &&
07304              (f.subclass != IAX_COMMAND_TXCNT) &&
07305              (f.subclass != IAX_COMMAND_TXACC) &&
07306             (f.subclass != IAX_COMMAND_VNAK)) ||
07307              (f.frametype != AST_FRAME_IAX))
07308             iaxs[fr->callno]->iseqno++;
07309       }
07310       /* A full frame */
07311       if (res < sizeof(*fh)) {
07312          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07313          ast_mutex_unlock(&iaxsl[fr->callno]);
07314          return 1;
07315       }
07316       /* Ensure text frames are NULL-terminated */
07317       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07318          if (res < thread->buf_size)
07319             thread->buf[res++] = '\0';
07320          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07321             thread->buf[res - 1] = '\0';
07322       }
07323       f.datalen = res - sizeof(*fh);
07324 
07325       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07326          from the real peer, not the transfer peer */
07327       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07328           ((f.subclass != IAX_COMMAND_INVAL) ||
07329            (f.frametype != AST_FRAME_IAX))) {
07330          unsigned char x;
07331          int call_to_destroy;
07332          /* XXX This code is not very efficient.  Surely there is a better way which still
07333                 properly handles boundary conditions? XXX */
07334          /* First we have to qualify that the ACKed value is within our window */
07335          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07336             if (fr->iseqno == x)
07337                break;
07338          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07339             /* The acknowledgement is within our window.  Time to acknowledge everything
07340                that it says to */
07341             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07342                /* Ack the packet with the given timestamp */
07343                if (option_debug && iaxdebug)
07344                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07345                call_to_destroy = 0;
07346                AST_LIST_LOCK(&iaxq.queue);
07347                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07348                   /* If it's our call, and our timestamp, mark -1 retries */
07349                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07350                      cur->retries = -1;
07351                      /* Destroy call if this is the end */
07352                      if (cur->final)
07353                         call_to_destroy = fr->callno;
07354                   }
07355                }
07356                AST_LIST_UNLOCK(&iaxq.queue);
07357                if (call_to_destroy) {
07358                   if (iaxdebug && option_debug)
07359                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07360                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07361                   iax2_destroy(call_to_destroy);
07362                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07363                }
07364             }
07365             /* Note how much we've received acknowledgement for */
07366             if (iaxs[fr->callno])
07367                iaxs[fr->callno]->rseqno = fr->iseqno;
07368             else {
07369                /* Stop processing now */
07370                ast_mutex_unlock(&iaxsl[fr->callno]);
07371                return 1;
07372             }
07373          } else if (option_debug)
07374             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07375       }
07376       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07377          ((f.frametype != AST_FRAME_IAX) || 
07378           ((f.subclass != IAX_COMMAND_TXACC) &&
07379            (f.subclass != IAX_COMMAND_TXCNT)))) {
07380          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07381          ast_mutex_unlock(&iaxsl[fr->callno]);
07382          return 1;
07383       }
07384 
07385       if (f.datalen) {
07386          if (f.frametype == AST_FRAME_IAX) {
07387             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07388                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07389                ast_mutex_unlock(&iaxsl[fr->callno]);
07390                return 1;
07391             }
07392             f.data = NULL;
07393             f.datalen = 0;
07394          } else
07395             f.data = thread->buf + sizeof(*fh);
07396       } else {
07397          if (f.frametype == AST_FRAME_IAX)
07398             f.data = NULL;
07399          else
07400             f.data = empty;
07401          memset(&ies, 0, sizeof(ies));
07402       }
07403 
07404       /* when we receive the first full frame for a new incoming channel,
07405          it is safe to start the PBX on the channel because we have now
07406          completed a 3-way handshake with the peer */
07407       if ((f.frametype == AST_FRAME_VOICE) ||
07408           (f.frametype == AST_FRAME_VIDEO) ||
07409           (f.frametype == AST_FRAME_IAX)) {
07410          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07411             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07412             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07413                ast_mutex_unlock(&iaxsl[fr->callno]);
07414                return 1;
07415             }
07416          }
07417       }
07418 
07419       if (f.frametype == AST_FRAME_VOICE) {
07420          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07421                iaxs[fr->callno]->voiceformat = f.subclass;
07422                if (option_debug)
07423                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07424                if (iaxs[fr->callno]->owner) {
07425                   int orignative;
07426 retryowner:
07427                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07428                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07429                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07430                   }
07431                   if (iaxs[fr->callno]) {
07432                      if (iaxs[fr->callno]->owner) {
07433                         orignative = iaxs[fr->callno]->owner->nativeformats;
07434                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07435                         if (iaxs[fr->callno]->owner->readformat)
07436                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07437                         iaxs[fr->callno]->owner->nativeformats = orignative;
07438                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07439                      }
07440                   } else {
07441                      if (option_debug)
07442                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07443                      ast_mutex_unlock(&iaxsl[fr->callno]);
07444                      return 1;
07445                   }
07446                }
07447          }
07448       }
07449       if (f.frametype == AST_FRAME_VIDEO) {
07450          if (f.subclass != iaxs[fr->callno]->videoformat) {
07451             if (option_debug)
07452                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07453             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07454          }
07455       }
07456       if (f.frametype == AST_FRAME_IAX) {
07457          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07458          /* Handle the IAX pseudo frame itself */
07459          if (option_debug && iaxdebug)
07460             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07461 
07462                         /* Update last ts unless the frame's timestamp originated with us. */
07463          if (iaxs[fr->callno]->last < fr->ts &&
07464                             f.subclass != IAX_COMMAND_ACK &&
07465                             f.subclass != IAX_COMMAND_PONG &&
07466                             f.subclass != IAX_COMMAND_LAGRP) {
07467             iaxs[fr->callno]->last = fr->ts;
07468             if (option_debug && iaxdebug)
07469                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07470          }
07471 
07472          switch(f.subclass) {
07473          case IAX_COMMAND_ACK:
07474             /* Do nothing */
07475             break;
07476          case IAX_COMMAND_QUELCH:
07477             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07478                     /* Generate Manager Hold event, if necessary*/
07479                if (iaxs[fr->callno]->owner) {
07480                   manager_event(EVENT_FLAG_CALL, "Hold",
07481                      "Channel: %s\r\n"
07482                      "Uniqueid: %s\r\n",
07483                      iaxs[fr->callno]->owner->name, 
07484                      iaxs[fr->callno]->owner->uniqueid);
07485                }
07486 
07487                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07488                if (ies.musiconhold) {
07489                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07490                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07491                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07492                         S_OR(mohsuggest, NULL),
07493                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07494                      if (!iaxs[fr->callno]) {
07495                         ast_mutex_unlock(&iaxsl[fr->callno]);
07496                         return 1;
07497                      }
07498                   }
07499                }
07500             }
07501             break;
07502          case IAX_COMMAND_UNQUELCH:
07503             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07504                     /* Generate Manager Unhold event, if necessary*/
07505                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07506                   manager_event(EVENT_FLAG_CALL, "Unhold",
07507                      "Channel: %s\r\n"
07508                      "Uniqueid: %s\r\n",
07509                      iaxs[fr->callno]->owner->name, 
07510                      iaxs[fr->callno]->owner->uniqueid);
07511                }
07512 
07513                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07514                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07515                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07516                   if (!iaxs[fr->callno]) {
07517                      ast_mutex_unlock(&iaxsl[fr->callno]);
07518                      return 1;
07519                   }
07520                }
07521             }
07522             break;
07523          case IAX_COMMAND_TXACC:
07524             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07525                /* Ack the packet with the given timestamp */
07526                AST_LIST_LOCK(&iaxq.queue);
07527                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07528                   /* Cancel any outstanding txcnt's */
07529                   if ((fr->callno == cur->callno) && (cur->transfer))
07530                      cur->retries = -1;
07531                }
07532                AST_LIST_UNLOCK(&iaxq.queue);
07533                memset(&ied1, 0, sizeof(ied1));
07534                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07535                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07536                iaxs[fr->callno]->transferring = TRANSFER_READY;
07537             }
07538             break;
07539          case IAX_COMMAND_NEW:
07540             /* Ignore if it's already up */
07541             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07542                break;
07543             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07544                ast_mutex_unlock(&iaxsl[fr->callno]);
07545                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07546                ast_mutex_lock(&iaxsl[fr->callno]);
07547                if (!iaxs[fr->callno]) {
07548                   ast_mutex_unlock(&iaxsl[fr->callno]);
07549                   return 1;
07550                }
07551             }
07552             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07553             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07554                int new_callno;
07555                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07556                   fr->callno = new_callno;
07557             }
07558             /* For security, always ack immediately */
07559             if (delayreject)
07560                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07561             if (check_access(fr->callno, &sin, &ies)) {
07562                /* They're not allowed on */
07563                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07564                if (authdebug)
07565                   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);
07566                break;
07567             }
07568             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07569                const char *context, *exten, *cid_num;
07570 
07571                context = ast_strdupa(iaxs[fr->callno]->context);
07572                exten = ast_strdupa(iaxs[fr->callno]->exten);
07573                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07574 
07575                /* This might re-enter the IAX code and need the lock */
07576                ast_mutex_unlock(&iaxsl[fr->callno]);
07577                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07578                ast_mutex_lock(&iaxsl[fr->callno]);
07579 
07580                if (!iaxs[fr->callno]) {
07581                   ast_mutex_unlock(&iaxsl[fr->callno]);
07582                   return 1;
07583                }
07584             } else
07585                exists = 0;
07586             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07587                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07588                   memset(&ied0, 0, sizeof(ied0));
07589                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07590                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07591                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07592                   if (!iaxs[fr->callno]) {
07593                      ast_mutex_unlock(&iaxsl[fr->callno]);
07594                      return 1;
07595                   }
07596                   if (authdebug)
07597                      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);
07598                } else {
07599                   /* Select an appropriate format */
07600 
07601                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07602                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07603                         using_prefs = "reqonly";
07604                      } else {
07605                         using_prefs = "disabled";
07606                      }
07607                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07608                      memset(&pref, 0, sizeof(pref));
07609                      strcpy(caller_pref_buf, "disabled");
07610                      strcpy(host_pref_buf, "disabled");
07611                   } else {
07612                      using_prefs = "mine";
07613                      /* If the information elements are in here... use them */
07614                      if (ies.codec_prefs)
07615                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07616                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07617                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07618                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07619                            pref = iaxs[fr->callno]->rprefs;
07620                            using_prefs = "caller";
07621                         } else {
07622                            pref = iaxs[fr->callno]->prefs;
07623                         }
07624                      } else
07625                         pref = iaxs[fr->callno]->prefs;
07626                      
07627                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07628                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07629                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07630                   }
07631                   if (!format) {
07632                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07633                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07634                      if (!format) {
07635                         memset(&ied0, 0, sizeof(ied0));
07636                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07637                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07638                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07639                         if (!iaxs[fr->callno]) {
07640                            ast_mutex_unlock(&iaxsl[fr->callno]);
07641                            return 1;
07642                         }
07643                         if (authdebug) {
07644                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07645                               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);
07646                            else 
07647                               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);
07648                         }
07649                      } else {
07650                         /* Pick one... */
07651                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07652                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07653                               format = 0;
07654                         } else {
07655                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07656                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07657                               memset(&pref, 0, sizeof(pref));
07658                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07659                               strcpy(caller_pref_buf,"disabled");
07660                               strcpy(host_pref_buf,"disabled");
07661                            } else {
07662                               using_prefs = "mine";
07663                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07664                                  /* Do the opposite of what we tried above. */
07665                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07666                                     pref = iaxs[fr->callno]->prefs;                       
07667                                  } else {
07668                                     pref = iaxs[fr->callno]->rprefs;
07669                                     using_prefs = "caller";
07670                                  }
07671                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07672                            
07673                               } else /* if no codec_prefs IE do it the old way */
07674                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07675                            }
07676                         }
07677 
07678                         if (!format) {
07679                            memset(&ied0, 0, sizeof(ied0));
07680                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07681                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07682                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07683                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07684                            if (!iaxs[fr->callno]) {
07685                               ast_mutex_unlock(&iaxsl[fr->callno]);
07686                               return 1;
07687                            }
07688                            if (authdebug)
07689                               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);
07690                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07691                            break;
07692                         }
07693                      }
07694                   }
07695                   if (format) {
07696                      /* No authentication required, let them in */
07697                      memset(&ied1, 0, sizeof(ied1));
07698                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07699                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07700                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07701                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07702                         if (option_verbose > 2) 
07703                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07704                                     "%srequested format = %s,\n"
07705                                     "%srequested prefs = %s,\n"
07706                                     "%sactual format = %s,\n"
07707                                     "%shost prefs = %s,\n"
07708                                     "%spriority = %s\n",
07709                                     ast_inet_ntoa(sin.sin_addr), 
07710                                     VERBOSE_PREFIX_4,
07711                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07712                                     VERBOSE_PREFIX_4,
07713                                     caller_pref_buf,
07714                                     VERBOSE_PREFIX_4,
07715                                     ast_getformatname(format), 
07716                                     VERBOSE_PREFIX_4,
07717                                     host_pref_buf, 
07718                                     VERBOSE_PREFIX_4,
07719                                     using_prefs);
07720                         
07721                         iaxs[fr->callno]->chosenformat = format;
07722                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07723                      } else {
07724                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07725                         /* If this is a TBD call, we're ready but now what...  */
07726                         if (option_verbose > 2)
07727                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07728                      }
07729                   }
07730                }
07731                break;
07732             }
07733             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07734                merge_encryption(iaxs[fr->callno],ies.encmethods);
07735             else
07736                iaxs[fr->callno]->encmethods = 0;
07737             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07738                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07739             if (!iaxs[fr->callno]) {
07740                ast_mutex_unlock(&iaxsl[fr->callno]);
07741                return 1;
07742             }
07743             break;
07744          case IAX_COMMAND_DPREQ:
07745             /* Request status in the dialplan */
07746             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07747                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07748                if (iaxcompat) {
07749                   /* Spawn a thread for the lookup */
07750                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07751                } else {
07752                   /* Just look it up */
07753                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07754                }
07755             }
07756             break;
07757          case IAX_COMMAND_HANGUP:
07758             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07759             if (option_debug)
07760                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07761             /* Set hangup cause according to remote */
07762             if (ies.causecode && iaxs[fr->callno]->owner)
07763                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07764             /* Send ack immediately, before we destroy */
07765             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07766             iax2_destroy(fr->callno);
07767             break;
07768          case IAX_COMMAND_REJECT:
07769             /* Set hangup cause according to remote */
07770             if (ies.causecode && iaxs[fr->callno]->owner)
07771                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07772 
07773             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07774                if (iaxs[fr->callno]->owner && authdebug)
07775                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07776                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07777                      ies.cause ? ies.cause : "<Unknown>");
07778                if (option_debug)
07779                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07780                      fr->callno);
07781             }
07782             /* Send ack immediately, before we destroy */
07783             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07784                          fr->ts, NULL, 0, fr->iseqno);
07785             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07786                iaxs[fr->callno]->error = EPERM;
07787             iax2_destroy(fr->callno);
07788             break;
07789          case IAX_COMMAND_TRANSFER:
07790          {
07791             struct ast_channel *bridged_chan;
07792 
07793             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07794                /* Set BLINDTRANSFER channel variables */
07795 
07796                ast_mutex_unlock(&iaxsl[fr->callno]);
07797                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07798                ast_mutex_lock(&iaxsl[fr->callno]);
07799                if (!iaxs[fr->callno]) {
07800                   ast_mutex_unlock(&iaxsl[fr->callno]);
07801                   return 1;
07802                }
07803 
07804                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07805                if (!strcmp(ies.called_number, ast_parking_ext())) {
07806                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07807                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07808                   } else {
07809                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07810                   }
07811                } else {
07812                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07813                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07814                         ies.called_number, iaxs[fr->callno]->context);
07815                   else
07816                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07817                         ies.called_number, iaxs[fr->callno]->context);
07818                }
07819             } else
07820                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07821 
07822             break;
07823          }
07824          case IAX_COMMAND_ACCEPT:
07825             /* Ignore if call is already up or needs authentication or is a TBD */
07826             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07827                break;
07828             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07829                /* Send ack immediately, before we destroy */
07830                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07831                iax2_destroy(fr->callno);
07832                break;
07833             }
07834             if (ies.format) {
07835                iaxs[fr->callno]->peerformat = ies.format;
07836             } else {
07837                if (iaxs[fr->callno]->owner)
07838                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07839                else
07840                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07841             }
07842             if (option_verbose > 2)
07843                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));
07844             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07845                memset(&ied0, 0, sizeof(ied0));
07846                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07847                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07848                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07849                if (!iaxs[fr->callno]) {
07850                   ast_mutex_unlock(&iaxsl[fr->callno]);
07851                   return 1;
07852                }
07853                if (authdebug)
07854                   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);
07855             } else {
07856                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07857                if (iaxs[fr->callno]->owner) {
07858                   /* Switch us to use a compatible format */
07859                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07860                   if (option_verbose > 2)
07861                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07862 retryowner2:
07863                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07864                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07865                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07866                   }
07867                   
07868                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07869                      /* Setup read/write formats properly. */
07870                      if (iaxs[fr->callno]->owner->writeformat)
07871                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07872                      if (iaxs[fr->callno]->owner->readformat)
07873                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07874                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07875                   }
07876                }
07877             }
07878             if (iaxs[fr->callno]) {
07879                ast_mutex_lock(&dpcache_lock);
07880                dp = iaxs[fr->callno]->dpentries;
07881                while(dp) {
07882                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07883                      iax2_dprequest(dp, fr->callno);
07884                   }
07885                   dp = dp->peer;
07886                }
07887                ast_mutex_unlock(&dpcache_lock);
07888             }
07889             break;
07890          case IAX_COMMAND_POKE:
07891             /* Send back a pong packet with the original timestamp */
07892             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07893             if (!iaxs[fr->callno]) {
07894                ast_mutex_unlock(&iaxsl[fr->callno]);
07895                return 1;
07896             }
07897             break;
07898          case IAX_COMMAND_PING:
07899          {
07900             struct iax_ie_data pingied;
07901             construct_rr(iaxs[fr->callno], &pingied);
07902             /* Send back a pong packet with the original timestamp */
07903             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07904          }
07905             break;
07906          case IAX_COMMAND_PONG:
07907             /* Calculate ping time */
07908             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07909             /* save RR info */
07910             save_rr(fr, &ies);
07911 
07912             if (iaxs[fr->callno]->peerpoke) {
07913                peer = iaxs[fr->callno]->peerpoke;
07914                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07915                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07916                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07917                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07918                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07919                   }
07920                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07921                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07922                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07923                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07924                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07925                   }
07926                }
07927                peer->lastms = iaxs[fr->callno]->pingtime;
07928                if (peer->smoothing && (peer->lastms > -1))
07929                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07930                else if (peer->smoothing && peer->lastms < 0)
07931                   peer->historicms = (0 + peer->historicms) / 2;
07932                else              
07933                   peer->historicms = iaxs[fr->callno]->pingtime;
07934 
07935                /* Remove scheduled iax2_poke_noanswer */
07936                if (peer->pokeexpire > -1) {
07937                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07938                      peer_unref(peer);
07939                      peer->pokeexpire = -1;
07940                   }
07941                }
07942                /* Schedule the next cycle */
07943                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07944                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07945                else
07946                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07947                if (peer->pokeexpire == -1)
07948                   peer_unref(peer);
07949                /* and finally send the ack */
07950                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07951                /* And wrap up the qualify call */
07952                iax2_destroy(fr->callno);
07953                peer->callno = 0;
07954                if (option_debug)
07955                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07956             }
07957             break;
07958          case IAX_COMMAND_LAGRQ:
07959          case IAX_COMMAND_LAGRP:
07960             f.src = "LAGRQ";
07961             f.mallocd = 0;
07962             f.offset = 0;
07963             f.samples = 0;
07964             iax_frame_wrap(fr, &f);
07965             if(f.subclass == IAX_COMMAND_LAGRQ) {
07966                /* Received a LAGRQ - echo back a LAGRP */
07967                fr->af.subclass = IAX_COMMAND_LAGRP;
07968                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07969             } else {
07970                /* Received LAGRP in response to our LAGRQ */
07971                unsigned int ts;
07972                /* This is a reply we've been given, actually measure the difference */
07973                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07974                iaxs[fr->callno]->lag = ts - fr->ts;
07975                if (option_debug && iaxdebug)
07976                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07977                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07978             }
07979             break;
07980          case IAX_COMMAND_AUTHREQ:
07981             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07982                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>");
07983                break;
07984             }
07985             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07986                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
07987                         .subclass = AST_CONTROL_HANGUP,
07988                };
07989                ast_log(LOG_WARNING, 
07990                   "I don't know how to authenticate %s to %s\n", 
07991                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07992                iax2_queue_frame(fr->callno, &hangup_fr);
07993             }
07994             if (!iaxs[fr->callno]) {
07995                ast_mutex_unlock(&iaxsl[fr->callno]);
07996                return 1;
07997             }
07998             break;
07999          case IAX_COMMAND_AUTHREP:
08000             /* For security, always ack immediately */
08001             if (delayreject)
08002                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08003             /* Ignore once we've started */
08004             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08005                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>");
08006                break;
08007             }
08008             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08009                if (authdebug)
08010                   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);
08011                memset(&ied0, 0, sizeof(ied0));
08012                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08013                break;
08014             }
08015             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08016                /* This might re-enter the IAX code and need the lock */
08017                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08018             } else
08019                exists = 0;
08020             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08021                if (authdebug)
08022                   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);
08023                memset(&ied0, 0, sizeof(ied0));
08024                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08025                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08026                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08027                if (!iaxs[fr->callno]) {
08028                   ast_mutex_unlock(&iaxsl[fr->callno]);
08029                   return 1;
08030                }
08031             } else {
08032                /* Select an appropriate format */
08033                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08034                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08035                      using_prefs = "reqonly";
08036                   } else {
08037                      using_prefs = "disabled";
08038                   }
08039                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08040                   memset(&pref, 0, sizeof(pref));
08041                   strcpy(caller_pref_buf, "disabled");
08042                   strcpy(host_pref_buf, "disabled");
08043                } else {
08044                   using_prefs = "mine";
08045                   if (ies.codec_prefs)
08046                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08047                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08048                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08049                         pref = iaxs[fr->callno]->rprefs;
08050                         using_prefs = "caller";
08051                      } else {
08052                         pref = iaxs[fr->callno]->prefs;
08053                      }
08054                   } else /* if no codec_prefs IE do it the old way */
08055                      pref = iaxs[fr->callno]->prefs;
08056                
08057                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08058                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08059                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08060                }
08061                if (!format) {
08062                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08063                      if (option_debug)
08064                         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);
08065                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08066                   }
08067                   if (!format) {
08068                      if (authdebug) {
08069                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08070                            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);
08071                         else
08072                            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);
08073                      }
08074                      memset(&ied0, 0, sizeof(ied0));
08075                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08076                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08077                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08078                      if (!iaxs[fr->callno]) {
08079                         ast_mutex_unlock(&iaxsl[fr->callno]);
08080                         return 1;
08081                      }
08082                   } else {
08083                      /* Pick one... */
08084                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08085                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08086                            format = 0;
08087                      } else {
08088                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08089                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08090                            memset(&pref, 0, sizeof(pref));
08091                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08092                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08093                            strcpy(caller_pref_buf,"disabled");
08094                            strcpy(host_pref_buf,"disabled");
08095                         } else {
08096                            using_prefs = "mine";
08097                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08098                               /* Do the opposite of what we tried above. */
08099                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08100                                  pref = iaxs[fr->callno]->prefs;                 
08101                               } else {
08102                                  pref = iaxs[fr->callno]->rprefs;
08103                                  using_prefs = "caller";
08104                               }
08105                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08106                            } else /* if no codec_prefs IE do it the old way */
08107                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08108                         }
08109                      }
08110                      if (!format) {
08111                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08112                         if (authdebug) {
08113                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08114                               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);
08115                            else
08116                               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);
08117                         }
08118                         memset(&ied0, 0, sizeof(ied0));
08119                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08120                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08121                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08122                         if (!iaxs[fr->callno]) {
08123                            ast_mutex_unlock(&iaxsl[fr->callno]);
08124                            return 1;
08125                         }
08126                      }
08127                   }
08128                }
08129                if (format) {
08130                   /* Authentication received */
08131                   memset(&ied1, 0, sizeof(ied1));
08132                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08133                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08134                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08135                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08136                      if (option_verbose > 2) 
08137                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08138                                  "%srequested format = %s,\n"
08139                                  "%srequested prefs = %s,\n"
08140                                  "%sactual format = %s,\n"
08141                                  "%shost prefs = %s,\n"
08142                                  "%spriority = %s\n", 
08143                                  ast_inet_ntoa(sin.sin_addr), 
08144                                  VERBOSE_PREFIX_4,
08145                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08146                                  VERBOSE_PREFIX_4,
08147                                  caller_pref_buf,
08148                                  VERBOSE_PREFIX_4,
08149                                  ast_getformatname(format),
08150                                  VERBOSE_PREFIX_4,
08151                                  host_pref_buf,
08152                                  VERBOSE_PREFIX_4,
08153                                  using_prefs);
08154 
08155                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08156                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08157                         iax2_destroy(fr->callno);
08158                   } else {
08159                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08160                      /* If this is a TBD call, we're ready but now what...  */
08161                      if (option_verbose > 2)
08162                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08163                   }
08164                }
08165             }
08166             break;
08167          case IAX_COMMAND_DIAL:
08168             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08169                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08170                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08171                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08172                   if (authdebug)
08173                      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);
08174                   memset(&ied0, 0, sizeof(ied0));
08175                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08176                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08177                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08178                   if (!iaxs[fr->callno]) {
08179                      ast_mutex_unlock(&iaxsl[fr->callno]);
08180                      return 1;
08181                   }
08182                } else {
08183                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08184                   if (option_verbose > 2) 
08185                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08186                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08187                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08188                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08189                      iax2_destroy(fr->callno);
08190                }
08191             }
08192             break;
08193          case IAX_COMMAND_INVAL:
08194             iaxs[fr->callno]->error = ENOTCONN;
08195             if (option_debug)
08196                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08197             iax2_destroy(fr->callno);
08198             if (option_debug)
08199                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08200             break;
08201          case IAX_COMMAND_VNAK:
08202             if (option_debug)
08203                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08204             /* Force retransmission */
08205             vnak_retransmit(fr->callno, fr->iseqno);
08206             break;
08207          case IAX_COMMAND_REGREQ:
08208          case IAX_COMMAND_REGREL:
08209             /* For security, always ack immediately */
08210             if (delayreject)
08211                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08212             if (register_verify(fr->callno, &sin, &ies)) {
08213                if (!iaxs[fr->callno]) {
08214                   ast_mutex_unlock(&iaxsl[fr->callno]);
08215                   return 1;
08216                }
08217                /* Send delayed failure */
08218                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08219                break;
08220             }
08221             if (!iaxs[fr->callno]) {
08222                ast_mutex_unlock(&iaxsl[fr->callno]);
08223                return 1;
08224             }
08225             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08226                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08227                if (f.subclass == IAX_COMMAND_REGREL)
08228                   memset(&sin, 0, sizeof(sin));
08229                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08230                   ast_log(LOG_WARNING, "Registry error\n");
08231                if (!iaxs[fr->callno]) {
08232                   ast_mutex_unlock(&iaxsl[fr->callno]);
08233                   return 1;
08234                }
08235                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08236                   ast_mutex_unlock(&iaxsl[fr->callno]);
08237                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08238                   ast_mutex_lock(&iaxsl[fr->callno]);
08239                   if (!iaxs[fr->callno]) {
08240                      ast_mutex_unlock(&iaxsl[fr->callno]);
08241                      return 1;
08242                   }
08243                }
08244                break;
08245             }
08246             registry_authrequest(fr->callno);
08247             if (!iaxs[fr->callno]) {
08248                ast_mutex_unlock(&iaxsl[fr->callno]);
08249                return 1;
08250             }
08251             break;
08252          case IAX_COMMAND_REGACK:
08253             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08254                ast_log(LOG_WARNING, "Registration failure\n");
08255             /* Send ack immediately, before we destroy */
08256             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08257             iax2_destroy(fr->callno);
08258             break;
08259          case IAX_COMMAND_REGREJ:
08260             if (iaxs[fr->callno]->reg) {
08261                if (authdebug) {
08262                   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));
08263                   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>");
08264                }
08265                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08266             }
08267             /* Send ack immediately, before we destroy */
08268             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08269             iax2_destroy(fr->callno);
08270             break;
08271          case IAX_COMMAND_REGAUTH:
08272             /* Authentication request */
08273             if (registry_rerequest(&ies, fr->callno, &sin)) {
08274                memset(&ied0, 0, sizeof(ied0));
08275                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08276                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08277                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08278                if (!iaxs[fr->callno]) {
08279                   ast_mutex_unlock(&iaxsl[fr->callno]);
08280                   return 1;
08281                }
08282             }
08283             break;
08284          case IAX_COMMAND_TXREJ:
08285             iaxs[fr->callno]->transferring = 0;
08286             if (option_verbose > 2) 
08287                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08288             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08289             if (iaxs[fr->callno]->bridgecallno) {
08290                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08291                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08292                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08293                }
08294             }
08295             break;
08296          case IAX_COMMAND_TXREADY:
08297             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08298                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08299                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08300                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08301                else
08302                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08303                if (option_verbose > 2) 
08304                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08305                if (iaxs[fr->callno]->bridgecallno) {
08306                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08307                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08308                      /* They're both ready, now release them. */
08309                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08310                         if (option_verbose > 2) 
08311                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08312                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08313 
08314                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08315                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08316 
08317                         memset(&ied0, 0, sizeof(ied0));
08318                         memset(&ied1, 0, sizeof(ied1));
08319                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08320                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08321                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08322                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08323                      } else {
08324                         if (option_verbose > 2) 
08325                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08326                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08327 
08328                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08329                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08330                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08331                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08332 
08333                         /* Stop doing lag & ping requests */
08334                         stop_stuff(fr->callno);
08335                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08336 
08337                         memset(&ied0, 0, sizeof(ied0));
08338                         memset(&ied1, 0, sizeof(ied1));
08339                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08340                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08341                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08342                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08343                      }
08344 
08345                   }
08346                }
08347             }
08348             break;
08349          case IAX_COMMAND_TXREQ:
08350             try_transfer(iaxs[fr->callno], &ies);
08351             break;
08352          case IAX_COMMAND_TXCNT:
08353             if (iaxs[fr->callno]->transferring)
08354                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08355             break;
08356          case IAX_COMMAND_TXREL:
08357             /* Send ack immediately, rather than waiting until we've changed addresses */
08358             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08359             complete_transfer(fr->callno, &ies);
08360             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08361             break;   
08362          case IAX_COMMAND_TXMEDIA:
08363             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08364                                         AST_LIST_LOCK(&iaxq.queue);
08365                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08366                                                 /* Cancel any outstanding frames and start anew */
08367                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08368                                                         cur->retries = -1;
08369                                                 }
08370                                         }
08371                                         AST_LIST_UNLOCK(&iaxq.queue);
08372                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08373                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08374             }
08375             break;   
08376          case IAX_COMMAND_DPREP:
08377             complete_dpreply(iaxs[fr->callno], &ies);
08378             break;
08379          case IAX_COMMAND_UNSUPPORT:
08380             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08381             break;
08382          case IAX_COMMAND_FWDOWNL:
08383             /* Firmware download */
08384             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08385                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08386                break;
08387             }
08388             memset(&ied0, 0, sizeof(ied0));
08389             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08390             if (res < 0)
08391                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08392             else if (res > 0)
08393                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08394             else
08395                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08396             if (!iaxs[fr->callno]) {
08397                ast_mutex_unlock(&iaxsl[fr->callno]);
08398                return 1;
08399             }
08400             break;
08401          default:
08402             if (option_debug)
08403                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08404             memset(&ied0, 0, sizeof(ied0));
08405             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08406             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08407          }
08408          /* Don't actually pass these frames along */
08409          if ((f.subclass != IAX_COMMAND_ACK) && 
08410            (f.subclass != IAX_COMMAND_TXCNT) && 
08411            (f.subclass != IAX_COMMAND_TXACC) && 
08412            (f.subclass != IAX_COMMAND_INVAL) &&
08413            (f.subclass != IAX_COMMAND_VNAK)) { 
08414             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08415                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08416          }
08417          ast_mutex_unlock(&iaxsl[fr->callno]);
08418          return 1;
08419       }
08420       /* Unless this is an ACK or INVAL frame, ack it */
08421       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08422          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08423    } else if (minivid) {
08424       f.frametype = AST_FRAME_VIDEO;
08425       if (iaxs[fr->callno]->videoformat > 0) 
08426          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08427       else {
08428          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08429          iax2_vnak(fr->callno);
08430          ast_mutex_unlock(&iaxsl[fr->callno]);
08431          return 1;
08432       }
08433       f.datalen = res - sizeof(*vh);
08434       if (f.datalen)
08435          f.data = thread->buf + sizeof(*vh);
08436       else
08437          f.data = NULL;
08438 #ifdef IAXTESTS
08439       if (test_resync) {
08440          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08441       } else
08442 #endif /* IAXTESTS */
08443          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08444    } else {
08445       /* A mini frame */
08446       f.frametype = AST_FRAME_VOICE;
08447       if (iaxs[fr->callno]->voiceformat > 0)
08448          f.subclass = iaxs[fr->callno]->voiceformat;
08449       else {
08450          if (option_debug)
08451             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08452          iax2_vnak(fr->callno);
08453          ast_mutex_unlock(&iaxsl[fr->callno]);
08454          return 1;
08455       }
08456       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08457       if (f.datalen < 0) {
08458          ast_log(LOG_WARNING, "Datalen < 0?\n");
08459          ast_mutex_unlock(&iaxsl[fr->callno]);
08460          return 1;
08461       }
08462       if (f.datalen)
08463          f.data = thread->buf + sizeof(*mh);
08464       else
08465          f.data = NULL;
08466 #ifdef IAXTESTS
08467       if (test_resync) {
08468          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08469       } else
08470 #endif /* IAXTESTS */
08471       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08472       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08473    }
08474    /* Don't pass any packets until we're started */
08475    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08476       ast_mutex_unlock(&iaxsl[fr->callno]);
08477       return 1;
08478    }
08479    /* Common things */
08480    f.src = "IAX2";
08481    f.mallocd = 0;
08482    f.offset = 0;
08483    f.len = 0;
08484    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08485       f.samples = ast_codec_get_samples(&f);
08486       /* We need to byteswap incoming slinear samples from network byte order */
08487       if (f.subclass == AST_FORMAT_SLINEAR)
08488          ast_frame_byteswap_be(&f);
08489    } else
08490       f.samples = 0;
08491    iax_frame_wrap(fr, &f);
08492 
08493    /* If this is our most recent packet, use it as our basis for timestamping */
08494    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08495       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08496       fr->outoforder = 0;
08497    } else {
08498       if (option_debug && iaxdebug && iaxs[fr->callno])
08499          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);
08500       fr->outoforder = -1;
08501    }
08502    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08503    duped_fr = iaxfrdup2(fr);
08504    if (duped_fr) {
08505       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08506    }
08507    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08508       iaxs[fr->callno]->last = fr->ts;
08509 #if 1
08510       if (option_debug && iaxdebug)
08511          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08512 #endif
08513    }
08514 
08515    /* Always run again */
08516    ast_mutex_unlock(&iaxsl[fr->callno]);
08517    return 1;
08518 }
08519 
08520 /* Function to clean up process thread if it is cancelled */
08521 static void iax2_process_thread_cleanup(void *data)
08522 {
08523    struct iax2_thread *thread = data;
08524    ast_mutex_destroy(&thread->lock);
08525    ast_cond_destroy(&thread->cond);
08526    free(thread);
08527    ast_atomic_dec_and_test(&iaxactivethreadcount);
08528 }
08529 
08530 static void *iax2_process_thread(void *data)
08531 {
08532    struct iax2_thread *thread = data;
08533    struct timeval tv;
08534    struct timespec ts;
08535    int put_into_idle = 0;
08536 
08537    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08538    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08539    for(;;) {
08540       /* Wait for something to signal us to be awake */
08541       ast_mutex_lock(&thread->lock);
08542 
08543       /* Flag that we're ready to accept signals */
08544       thread->ready_for_signal = 1;
08545       
08546       /* Put into idle list if applicable */
08547       if (put_into_idle)
08548          insert_idle_thread(thread);
08549 
08550       if (thread->type == IAX_TYPE_DYNAMIC) {
08551          struct iax2_thread *t = NULL;
08552          /* Wait to be signalled or time out */
08553          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08554          ts.tv_sec = tv.tv_sec;
08555          ts.tv_nsec = tv.tv_usec * 1000;
08556          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08557             /* This thread was never put back into the available dynamic
08558              * thread list, so just go away. */
08559             if (!put_into_idle) {
08560                ast_mutex_unlock(&thread->lock);
08561                break;
08562             }
08563             AST_LIST_LOCK(&dynamic_list);
08564             /* Account for the case where this thread is acquired *right* after a timeout */
08565             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08566                iaxdynamicthreadcount--;
08567             AST_LIST_UNLOCK(&dynamic_list);
08568             if (t) {
08569                /* This dynamic thread timed out waiting for a task and was
08570                 * not acquired immediately after the timeout, 
08571                 * so it's time to go away. */
08572                ast_mutex_unlock(&thread->lock);
08573                break;
08574             }
08575             /* Someone grabbed our thread *right* after we timed out.
08576              * Wait for them to set us up with something to do and signal
08577              * us to continue. */
08578             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08579             ts.tv_sec = tv.tv_sec;
08580             ts.tv_nsec = tv.tv_usec * 1000;
08581             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08582             {
08583                ast_mutex_unlock(&thread->lock);
08584                break;
08585             }
08586          }
08587       } else {
08588          ast_cond_wait(&thread->cond, &thread->lock);
08589       }
08590 
08591       /* Go back into our respective list */
08592       put_into_idle = 1;
08593 
08594       ast_mutex_unlock(&thread->lock);
08595 
08596       if (thread->iostate == IAX_IOSTATE_IDLE)
08597          continue;
08598 
08599       /* Add ourselves to the active list now */
08600       AST_LIST_LOCK(&active_list);
08601       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08602       AST_LIST_UNLOCK(&active_list);
08603 
08604       /* See what we need to do */
08605       switch(thread->iostate) {
08606       case IAX_IOSTATE_READY:
08607          thread->actions++;
08608          thread->iostate = IAX_IOSTATE_PROCESSING;
08609          socket_process(thread);
08610          handle_deferred_full_frames(thread);
08611          break;
08612       case IAX_IOSTATE_SCHEDREADY:
08613          thread->actions++;
08614          thread->iostate = IAX_IOSTATE_PROCESSING;
08615 #ifdef SCHED_MULTITHREADED
08616          thread->schedfunc(thread->scheddata);
08617 #endif      
08618          break;
08619       }
08620       time(&thread->checktime);
08621       thread->iostate = IAX_IOSTATE_IDLE;
08622 #ifdef DEBUG_SCHED_MULTITHREAD
08623       thread->curfunc[0]='\0';
08624 #endif      
08625 
08626       /* Now... remove ourselves from the active list, and return to the idle list */
08627       AST_LIST_LOCK(&active_list);
08628       AST_LIST_REMOVE(&active_list, thread, list);
08629       AST_LIST_UNLOCK(&active_list);
08630 
08631       /* Make sure another frame didn't sneak in there after we thought we were done. */
08632       handle_deferred_full_frames(thread);
08633    }
08634 
08635    /*!\note For some reason, idle threads are exiting without being removed
08636     * from an idle list, which is causing memory corruption.  Forcibly remove
08637     * it from the list, if it's there.
08638     */
08639    AST_LIST_LOCK(&idle_list);
08640    AST_LIST_REMOVE(&idle_list, thread, list);
08641    AST_LIST_UNLOCK(&idle_list);
08642 
08643    AST_LIST_LOCK(&dynamic_list);
08644    AST_LIST_REMOVE(&dynamic_list, thread, list);
08645    AST_LIST_UNLOCK(&dynamic_list);
08646 
08647    /* I am exiting here on my own volition, I need to clean up my own data structures
08648    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08649    */
08650    pthread_cleanup_pop(1);
08651 
08652    return NULL;
08653 }
08654 
08655 static int iax2_do_register(struct iax2_registry *reg)
08656 {
08657    struct iax_ie_data ied;
08658    if (option_debug && iaxdebug)
08659       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08660 
08661    if (reg->dnsmgr && 
08662        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08663       /* Maybe the IP has changed, force DNS refresh */
08664       ast_dnsmgr_refresh(reg->dnsmgr);
08665    }
08666    
08667    /*
08668     * if IP has Changed, free allocated call to create a new one with new IP
08669     * call has the pointer to IP and must be updated to the new one
08670     */
08671    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08672       ast_mutex_lock(&iaxsl[reg->callno]);
08673       iax2_destroy(reg->callno);
08674       ast_mutex_unlock(&iaxsl[reg->callno]);
08675       reg->callno = 0;
08676    }
08677    if (!reg->addr.sin_addr.s_addr) {
08678       if (option_debug && iaxdebug)
08679          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08680       /* Setup the next registration attempt */
08681       AST_SCHED_DEL(sched, reg->expire);
08682       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08683       return -1;
08684    }
08685 
08686    if (!reg->callno) {
08687       if (option_debug)
08688          ast_log(LOG_DEBUG, "Allocate call number\n");
08689       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08690       if (reg->callno < 1) {
08691          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08692          return -1;
08693       } else if (option_debug)
08694          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08695       iaxs[reg->callno]->reg = reg;
08696       ast_mutex_unlock(&iaxsl[reg->callno]);
08697    }
08698    /* Schedule the next registration attempt */
08699    AST_SCHED_DEL(sched, reg->expire);
08700    /* Setup the next registration a little early */
08701    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08702    /* Send the request */
08703    memset(&ied, 0, sizeof(ied));
08704    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08705    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08706    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08707    reg->regstate = REG_STATE_REGSENT;
08708    return 0;
08709 }
08710 
08711 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08712 {
08713    if (pos != 3)
08714       return NULL;
08715    return iax_prov_complete_template(line, word, pos, state);
08716 }
08717 
08718 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08719 {
08720    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08721       is found for template */
08722    struct iax_ie_data provdata;
08723    struct iax_ie_data ied;
08724    unsigned int sig;
08725    struct sockaddr_in sin;
08726    int callno;
08727    struct create_addr_info cai;
08728 
08729    memset(&cai, 0, sizeof(cai));
08730 
08731    if (option_debug)
08732       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08733 
08734    if (iax_provision_build(&provdata, &sig, template, force)) {
08735       if (option_debug)
08736          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08737       return 0;
08738    }
08739 
08740    if (end) {
08741       memcpy(&sin, end, sizeof(sin));
08742       cai.sockfd = sockfd;
08743    } else if (create_addr(dest, NULL, &sin, &cai))
08744       return -1;
08745 
08746    /* Build the rest of the message */
08747    memset(&ied, 0, sizeof(ied));
08748    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08749 
08750    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08751    if (!callno)
08752       return -1;
08753 
08754    if (iaxs[callno]) {
08755       /* Schedule autodestruct in case they don't ever give us anything back */
08756       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08757       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08758       ast_set_flag(iaxs[callno], IAX_PROVISION);
08759       /* Got a call number now, so go ahead and send the provisioning information */
08760       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08761    }
08762    ast_mutex_unlock(&iaxsl[callno]);
08763 
08764    return 1;
08765 }
08766 
08767 static char *papp = "IAX2Provision";
08768 static char *psyn = "Provision a calling IAXy with a given template";
08769 static char *pdescrip = 
08770 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08771 "the calling entity is in fact an IAXy) with the given template or\n"
08772 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08773 
08774 /*! iax2provision
08775 \ingroup applications
08776 */
08777 static int iax2_prov_app(struct ast_channel *chan, void *data)
08778 {
08779    int res;
08780    char *sdata;
08781    char *opts;
08782    int force =0;
08783    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08784    if (ast_strlen_zero(data))
08785       data = "default";
08786    sdata = ast_strdupa(data);
08787    opts = strchr(sdata, '|');
08788    if (opts)
08789       *opts='\0';
08790 
08791    if (chan->tech != &iax2_tech) {
08792       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08793       return -1;
08794    } 
08795    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08796       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08797       return -1;
08798    }
08799    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08800    if (option_verbose > 2)
08801       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08802       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08803       sdata, res);
08804    return res;
08805 }
08806 
08807 
08808 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08809 {
08810    int force = 0;
08811    int res;
08812    if (argc < 4)
08813       return RESULT_SHOWUSAGE;
08814    if ((argc > 4)) {
08815       if (!strcasecmp(argv[4], "forced"))
08816          force = 1;
08817       else
08818          return RESULT_SHOWUSAGE;
08819    }
08820    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08821    if (res < 0)
08822       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08823    else if (res < 1)
08824       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08825    else
08826       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08827    return RESULT_SUCCESS;
08828 }
08829 
08830 static void __iax2_poke_noanswer(const void *data)
08831 {
08832    struct iax2_peer *peer = (struct iax2_peer *)data;
08833    int callno;
08834 
08835    if (peer->lastms > -1) {
08836       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08837       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08838       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08839    }
08840    if ((callno = peer->callno) > 0) {
08841       ast_mutex_lock(&iaxsl[callno]);
08842       iax2_destroy(callno);
08843       ast_mutex_unlock(&iaxsl[callno]);
08844    }
08845    peer->callno = 0;
08846    peer->lastms = -1;
08847    /* Try again quickly */
08848    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08849    if (peer->pokeexpire == -1)
08850       peer_unref(peer);
08851 }
08852 
08853 static int iax2_poke_noanswer(const void *data)
08854 {
08855    struct iax2_peer *peer = (struct iax2_peer *)data;
08856    peer->pokeexpire = -1;
08857 #ifdef SCHED_MULTITHREADED
08858    if (schedule_action(__iax2_poke_noanswer, data))
08859 #endif      
08860       __iax2_poke_noanswer(data);
08861    peer_unref(peer);
08862    return 0;
08863 }
08864 
08865 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08866 {
08867    struct iax2_peer *peer = obj;
08868 
08869    iax2_poke_peer(peer, 0);
08870 
08871    return 0;
08872 }
08873 
08874 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08875 {
08876    int callno;
08877    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08878       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08879         immediately after clearing things out */
08880       peer->lastms = 0;
08881       peer->historicms = 0;
08882       peer->pokeexpire = -1;
08883       peer->callno = 0;
08884       return 0;
08885    }
08886 
08887    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
08888    if ((callno = peer->callno) > 0) {
08889       ast_log(LOG_NOTICE, "Still have a callno...\n");
08890       ast_mutex_lock(&iaxsl[callno]);
08891       iax2_destroy(callno);
08892       ast_mutex_unlock(&iaxsl[callno]);
08893    }
08894    if (heldcall)
08895       ast_mutex_unlock(&iaxsl[heldcall]);
08896    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08897    if (heldcall)
08898       ast_mutex_lock(&iaxsl[heldcall]);
08899    if (peer->callno < 1) {
08900       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08901       return -1;
08902    }
08903 
08904    /* Speed up retransmission times for this qualify call */
08905    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08906    iaxs[peer->callno]->peerpoke = peer;
08907    
08908    /* Remove any pending pokeexpire task */
08909    if (peer->pokeexpire > -1) {
08910       if (!ast_sched_del(sched, peer->pokeexpire)) {
08911          peer->pokeexpire = -1;
08912          peer_unref(peer);
08913       }
08914    }
08915 
08916    /* Queue up a new task to handle no reply */
08917    /* If the host is already unreachable then use the unreachable interval instead */
08918    if (peer->lastms < 0) {
08919       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08920    } else
08921       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08922 
08923    if (peer->pokeexpire == -1)
08924       peer_unref(peer);
08925 
08926    /* And send the poke */
08927    ast_mutex_lock(&iaxsl[callno]);
08928    if (iaxs[callno]) {
08929       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08930    }
08931    ast_mutex_unlock(&iaxsl[callno]);
08932 
08933    return 0;
08934 }
08935 
08936 static void free_context(struct iax2_context *con)
08937 {
08938    struct iax2_context *conl;
08939    while(con) {
08940       conl = con;
08941       con = con->next;
08942       free(conl);
08943    }
08944 }
08945 
08946 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08947 {
08948    int callno;
08949    int res;
08950    int fmt, native;
08951    struct sockaddr_in sin;
08952    struct ast_channel *c;
08953    struct parsed_dial_string pds;
08954    struct create_addr_info cai;
08955    char *tmpstr;
08956 
08957    memset(&pds, 0, sizeof(pds));
08958    tmpstr = ast_strdupa(data);
08959    parse_dial_string(tmpstr, &pds);
08960 
08961    if (ast_strlen_zero(pds.peer)) {
08962       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
08963       return NULL;
08964    }
08965           
08966    memset(&cai, 0, sizeof(cai));
08967    cai.capability = iax2_capability;
08968 
08969    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08970    
08971    /* Populate our address from the given */
08972    if (create_addr(pds.peer, NULL, &sin, &cai)) {
08973       *cause = AST_CAUSE_UNREGISTERED;
08974       return NULL;
08975    }
08976 
08977    if (pds.port)
08978       sin.sin_port = htons(atoi(pds.port));
08979 
08980    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08981    if (callno < 1) {
08982       ast_log(LOG_WARNING, "Unable to create call\n");
08983       *cause = AST_CAUSE_CONGESTION;
08984       return NULL;
08985    }
08986 
08987    /* If this is a trunk, update it now */
08988    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08989    if (ast_test_flag(&cai, IAX_TRUNK)) {
08990       int new_callno;
08991       if ((new_callno = make_trunk(callno, 1)) != -1)
08992          callno = new_callno;
08993    }
08994    iaxs[callno]->maxtime = cai.maxtime;
08995    if (cai.found)
08996       ast_string_field_set(iaxs[callno], host, pds.peer);
08997 
08998    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08999 
09000    ast_mutex_unlock(&iaxsl[callno]);
09001 
09002    if (c) {
09003       /* Choose a format we can live with */
09004       if (c->nativeformats & format) 
09005          c->nativeformats &= format;
09006       else {
09007          native = c->nativeformats;
09008          fmt = format;
09009          res = ast_translator_best_choice(&fmt, &native);
09010          if (res < 0) {
09011             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09012                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09013             ast_hangup(c);
09014             return NULL;
09015          }
09016          c->nativeformats = native;
09017       }
09018       c->readformat = ast_best_codec(c->nativeformats);
09019       c->writeformat = c->readformat;
09020    }
09021 
09022    return c;
09023 }
09024 
09025 static void *sched_thread(void *ignore)
09026 {
09027    int count;
09028    int res;
09029    struct timeval tv;
09030    struct timespec ts;
09031 
09032    for (;;) {
09033       res = ast_sched_wait(sched);
09034       if ((res > 1000) || (res < 0))
09035          res = 1000;
09036       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09037       ts.tv_sec = tv.tv_sec;
09038       ts.tv_nsec = tv.tv_usec * 1000;
09039 
09040       pthread_testcancel();
09041       ast_mutex_lock(&sched_lock);
09042       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09043       ast_mutex_unlock(&sched_lock);
09044       pthread_testcancel();
09045 
09046       count = ast_sched_runq(sched);
09047       if (option_debug && count >= 20)
09048          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09049    }
09050    return NULL;
09051 }
09052 
09053 static void *network_thread(void *ignore)
09054 {
09055    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09056       from the network, and queue them for delivery to the channels */
09057    int res, count, wakeup;
09058    struct iax_frame *f;
09059 
09060    if (timingfd > -1)
09061       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09062    
09063    for(;;) {
09064       pthread_testcancel();
09065 
09066       /* Go through the queue, sending messages which have not yet been
09067          sent, and scheduling retransmissions if appropriate */
09068       AST_LIST_LOCK(&iaxq.queue);
09069       count = 0;
09070       wakeup = -1;
09071       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09072          if (f->sentyet)
09073             continue;
09074          
09075          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09076          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09077             wakeup = 1;
09078             continue;
09079          }
09080 
09081          f->sentyet++;
09082 
09083          if (iaxs[f->callno]) {
09084             send_packet(f);
09085             count++;
09086          } 
09087 
09088          ast_mutex_unlock(&iaxsl[f->callno]);
09089 
09090          if (f->retries < 0) {
09091             /* This is not supposed to be retransmitted */
09092             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09093             iaxq.count--;
09094             /* Free the iax frame */
09095             iax_frame_free(f);
09096          } else {
09097             /* We need reliable delivery.  Schedule a retransmission */
09098             f->retries++;
09099             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09100          }
09101       }
09102       AST_LIST_TRAVERSE_SAFE_END
09103       AST_LIST_UNLOCK(&iaxq.queue);
09104 
09105       pthread_testcancel();
09106 
09107       if (option_debug && count >= 20)
09108          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09109 
09110       /* Now do the IO, and run scheduled tasks */
09111       res = ast_io_wait(io, wakeup);
09112       if (res >= 0) {
09113          if (option_debug && res >= 20)
09114             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09115       }
09116    }
09117    return NULL;
09118 }
09119 
09120 static int start_network_thread(void)
09121 {
09122    pthread_attr_t attr;
09123    int threadcount = 0;
09124    int x;
09125    for (x = 0; x < iaxthreadcount; x++) {
09126       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09127       if (thread) {
09128          thread->type = IAX_TYPE_POOL;
09129          thread->threadnum = ++threadcount;
09130          ast_mutex_init(&thread->lock);
09131          ast_cond_init(&thread->cond, NULL);
09132          pthread_attr_init(&attr);
09133          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09134          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09135             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09136             free(thread);
09137             thread = NULL;
09138          }
09139          AST_LIST_LOCK(&idle_list);
09140          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09141          AST_LIST_UNLOCK(&idle_list);
09142       }
09143    }
09144    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09145    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09146    if (option_verbose > 1)
09147       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09148    return 0;
09149 }
09150 
09151 static struct iax2_context *build_context(char *context)
09152 {
09153    struct iax2_context *con;
09154 
09155    if ((con = ast_calloc(1, sizeof(*con))))
09156       ast_copy_string(con->context, context, sizeof(con->context));
09157    
09158    return con;
09159 }
09160 
09161 static int get_auth_methods(char *value)
09162 {
09163    int methods = 0;
09164    if (strstr(value, "rsa"))
09165       methods |= IAX_AUTH_RSA;
09166    if (strstr(value, "md5"))
09167       methods |= IAX_AUTH_MD5;
09168    if (strstr(value, "plaintext"))
09169       methods |= IAX_AUTH_PLAINTEXT;
09170    return methods;
09171 }
09172 
09173 
09174 /*! \brief Check if address can be used as packet source.
09175  \return 0  address available, 1  address unavailable, -1  error
09176 */
09177 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09178 {
09179    int sd;
09180    int res;
09181    
09182    sd = socket(AF_INET, SOCK_DGRAM, 0);
09183    if (sd < 0) {
09184       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09185       return -1;
09186    }
09187 
09188    res = bind(sd, sa, salen);
09189    if (res < 0) {
09190       if (option_debug)
09191          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09192       close(sd);
09193       return 1;
09194    }
09195 
09196    close(sd);
09197    return 0;
09198 }
09199 
09200 /*! \brief Parse the "sourceaddress" value,
09201   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09202   not found. */
09203 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09204 {
09205    struct sockaddr_in sin;
09206    int nonlocal = 1;
09207    int port = IAX_DEFAULT_PORTNO;
09208    int sockfd = defaultsockfd;
09209    char *tmp;
09210    char *addr;
09211    char *portstr;
09212 
09213    if (!(tmp = ast_strdupa(srcaddr)))
09214       return -1;
09215 
09216    addr = strsep(&tmp, ":");
09217    portstr = tmp;
09218 
09219    if (portstr) {
09220       port = atoi(portstr);
09221       if (port < 1)
09222          port = IAX_DEFAULT_PORTNO;
09223    }
09224    
09225    if (!ast_get_ip(&sin, addr)) {
09226       struct ast_netsock *sock;
09227       int res;
09228 
09229       sin.sin_port = 0;
09230       sin.sin_family = AF_INET;
09231       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09232       if (res == 0) {
09233          /* ip address valid. */
09234          sin.sin_port = htons(port);
09235          if (!(sock = ast_netsock_find(netsock, &sin)))
09236             sock = ast_netsock_find(outsock, &sin);
09237          if (sock) {
09238             sockfd = ast_netsock_sockfd(sock);
09239             nonlocal = 0;
09240          } else {
09241             unsigned int orig_saddr = sin.sin_addr.s_addr;
09242             /* INADDR_ANY matches anyway! */
09243             sin.sin_addr.s_addr = INADDR_ANY;
09244             if (ast_netsock_find(netsock, &sin)) {
09245                sin.sin_addr.s_addr = orig_saddr;
09246                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09247                if (sock) {
09248                   sockfd = ast_netsock_sockfd(sock);
09249                   ast_netsock_unref(sock);
09250                   nonlocal = 0;
09251                } else {
09252                   nonlocal = 2;
09253                }
09254             }
09255          }
09256       }
09257    }
09258       
09259    peer->sockfd = sockfd;
09260 
09261    if (nonlocal == 1) {
09262       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09263          srcaddr, peer->name);
09264       return -1;
09265         } else if (nonlocal == 2) {
09266       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09267          srcaddr, peer->name);
09268          return -1;
09269    } else {
09270       if (option_debug)
09271          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09272       return 0;
09273    }
09274 }
09275 
09276 static void peer_destructor(void *obj)
09277 {
09278    struct iax2_peer *peer = obj;
09279 
09280    ast_free_ha(peer->ha);
09281 
09282    if (peer->callno > 0) {
09283       ast_mutex_lock(&iaxsl[peer->callno]);
09284       iax2_destroy(peer->callno);
09285       ast_mutex_unlock(&iaxsl[peer->callno]);
09286    }
09287 
09288    register_peer_exten(peer, 0);
09289 
09290    if (peer->dnsmgr)
09291       ast_dnsmgr_release(peer->dnsmgr);
09292 
09293    ast_string_field_free_memory(peer);
09294 }
09295 
09296 /*! \brief Create peer structure based on configuration */
09297 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09298 {
09299    struct iax2_peer *peer = NULL;
09300    struct ast_ha *oldha = NULL;
09301    int maskfound=0;
09302    int found=0;
09303    int firstpass=1;
09304    struct iax2_peer tmp_peer = {
09305       .name = name,
09306    };
09307 
09308    if (!temponly) {
09309       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09310       if (peer && !ast_test_flag(peer, IAX_DELME))
09311          firstpass = 0;
09312    }
09313 
09314    if (peer) {
09315       found++;
09316       if (firstpass) {
09317          oldha = peer->ha;
09318          peer->ha = NULL;
09319       }
09320       unlink_peer(peer);
09321    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09322       peer->expire = -1;
09323       peer->pokeexpire = -1;
09324       peer->sockfd = defaultsockfd;
09325       if (ast_string_field_init(peer, 32))
09326          peer = peer_unref(peer);
09327    }
09328 
09329    if (peer) {
09330       if (firstpass) {
09331          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09332          peer->encmethods = iax2_encryption;
09333          peer->adsi = adsi;
09334          ast_string_field_set(peer,secret,"");
09335          if (!found) {
09336             ast_string_field_set(peer, name, name);
09337             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09338             peer->expiry = min_reg_expire;
09339          }
09340          peer->prefs = prefs;
09341          peer->capability = iax2_capability;
09342          peer->smoothing = 0;
09343          peer->pokefreqok = DEFAULT_FREQ_OK;
09344          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09345          ast_string_field_set(peer,context,"");
09346          ast_string_field_set(peer,peercontext,"");
09347          ast_clear_flag(peer, IAX_HASCALLERID);
09348          ast_string_field_set(peer, cid_name, "");
09349          ast_string_field_set(peer, cid_num, "");
09350       }
09351 
09352       if (!v) {
09353          v = alt;
09354          alt = NULL;
09355       }
09356       while(v) {
09357          if (!strcasecmp(v->name, "secret")) {
09358             ast_string_field_set(peer, secret, v->value);
09359          } else if (!strcasecmp(v->name, "mailbox")) {
09360             ast_string_field_set(peer, mailbox, v->value);
09361          } else if (!strcasecmp(v->name, "mohinterpret")) {
09362             ast_string_field_set(peer, mohinterpret, v->value);
09363          } else if (!strcasecmp(v->name, "mohsuggest")) {
09364             ast_string_field_set(peer, mohsuggest, v->value);
09365          } else if (!strcasecmp(v->name, "dbsecret")) {
09366             ast_string_field_set(peer, dbsecret, v->value);
09367          } else if (!strcasecmp(v->name, "trunk")) {
09368             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09369             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09370                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09371                ast_clear_flag(peer, IAX_TRUNK);
09372             }
09373          } else if (!strcasecmp(v->name, "auth")) {
09374             peer->authmethods = get_auth_methods(v->value);
09375          } else if (!strcasecmp(v->name, "encryption")) {
09376             peer->encmethods = get_encrypt_methods(v->value);
09377          } else if (!strcasecmp(v->name, "notransfer")) {
09378             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09379             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09380             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09381          } else if (!strcasecmp(v->name, "transfer")) {
09382             if (!strcasecmp(v->value, "mediaonly")) {
09383                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09384             } else if (ast_true(v->value)) {
09385                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09386             } else 
09387                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09388          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09389             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09390          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09391             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09392          } else if (!strcasecmp(v->name, "host")) {
09393             if (!strcasecmp(v->value, "dynamic")) {
09394                /* They'll register with us */
09395                ast_set_flag(peer, IAX_DYNAMIC); 
09396                if (!found) {
09397                   /* Initialize stuff iff we're not found, otherwise
09398                      we keep going with what we had */
09399                   memset(&peer->addr.sin_addr, 0, 4);
09400                   if (peer->addr.sin_port) {
09401                      /* If we've already got a port, make it the default rather than absolute */
09402                      peer->defaddr.sin_port = peer->addr.sin_port;
09403                      peer->addr.sin_port = 0;
09404                   }
09405                }
09406             } else {
09407                /* Non-dynamic.  Make sure we become that way if we're not */
09408                AST_SCHED_DEL(sched, peer->expire);
09409                ast_clear_flag(peer, IAX_DYNAMIC);
09410                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09411                   return peer_unref(peer);
09412                if (!peer->addr.sin_port)
09413                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09414             }
09415             if (!maskfound)
09416                inet_aton("255.255.255.255", &peer->mask);
09417          } else if (!strcasecmp(v->name, "defaultip")) {
09418             if (ast_get_ip(&peer->defaddr, v->value))
09419                return peer_unref(peer);
09420          } else if (!strcasecmp(v->name, "sourceaddress")) {
09421             peer_set_srcaddr(peer, v->value);
09422          } else if (!strcasecmp(v->name, "permit") ||
09423                   !strcasecmp(v->name, "deny")) {
09424             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09425          } else if (!strcasecmp(v->name, "mask")) {
09426             maskfound++;
09427             inet_aton(v->value, &peer->mask);
09428          } else if (!strcasecmp(v->name, "context")) {
09429             ast_string_field_set(peer, context, v->value);
09430          } else if (!strcasecmp(v->name, "regexten")) {
09431             ast_string_field_set(peer, regexten, v->value);
09432          } else if (!strcasecmp(v->name, "peercontext")) {
09433             ast_string_field_set(peer, peercontext, v->value);
09434          } else if (!strcasecmp(v->name, "port")) {
09435             if (ast_test_flag(peer, IAX_DYNAMIC))
09436                peer->defaddr.sin_port = htons(atoi(v->value));
09437             else
09438                peer->addr.sin_port = htons(atoi(v->value));
09439          } else if (!strcasecmp(v->name, "username")) {
09440             ast_string_field_set(peer, username, v->value);
09441          } else if (!strcasecmp(v->name, "allow")) {
09442             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09443          } else if (!strcasecmp(v->name, "disallow")) {
09444             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09445          } else if (!strcasecmp(v->name, "callerid")) {
09446             if (!ast_strlen_zero(v->value)) {
09447                char name2[80];
09448                char num2[80];
09449                ast_callerid_split(v->value, name2, 80, num2, 80);
09450                ast_string_field_set(peer, cid_name, name2);
09451                ast_string_field_set(peer, cid_num, num2);
09452                ast_set_flag(peer, IAX_HASCALLERID);
09453             } else {
09454                ast_clear_flag(peer, IAX_HASCALLERID);
09455                ast_string_field_set(peer, cid_name, "");
09456                ast_string_field_set(peer, cid_num, "");
09457             }
09458          } else if (!strcasecmp(v->name, "fullname")) {
09459             if (!ast_strlen_zero(v->value)) {
09460                ast_string_field_set(peer, cid_name, v->value);
09461                ast_set_flag(peer, IAX_HASCALLERID);
09462             } else {
09463                ast_string_field_set(peer, cid_name, "");
09464                if (ast_strlen_zero(peer->cid_num))
09465                   ast_clear_flag(peer, IAX_HASCALLERID);
09466             }
09467          } else if (!strcasecmp(v->name, "cid_number")) {
09468             if (!ast_strlen_zero(v->value)) {
09469                ast_string_field_set(peer, cid_num, v->value);
09470                ast_set_flag(peer, IAX_HASCALLERID);
09471             } else {
09472                ast_string_field_set(peer, cid_num, "");
09473                if (ast_strlen_zero(peer->cid_name))
09474                   ast_clear_flag(peer, IAX_HASCALLERID);
09475             }
09476          } else if (!strcasecmp(v->name, "sendani")) {
09477             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09478          } else if (!strcasecmp(v->name, "inkeys")) {
09479             ast_string_field_set(peer, inkeys, v->value);
09480          } else if (!strcasecmp(v->name, "outkey")) {
09481             ast_string_field_set(peer, outkey, v->value);
09482          } else if (!strcasecmp(v->name, "qualify")) {
09483             if (!strcasecmp(v->value, "no")) {
09484                peer->maxms = 0;
09485             } else if (!strcasecmp(v->value, "yes")) {
09486                peer->maxms = DEFAULT_MAXMS;
09487             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09488                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);
09489                peer->maxms = 0;
09490             }
09491          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09492             peer->smoothing = ast_true(v->value);
09493          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09494             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09495                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);
09496             }
09497          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09498             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09499                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);
09500             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09501          } else if (!strcasecmp(v->name, "timezone")) {
09502             ast_string_field_set(peer, zonetag, v->value);
09503          } else if (!strcasecmp(v->name, "adsi")) {
09504             peer->adsi = ast_true(v->value);
09505          }/* else if (strcasecmp(v->name,"type")) */
09506          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09507          v = v->next;
09508          if (!v) {
09509             v = alt;
09510             alt = NULL;
09511          }
09512       }
09513       if (!peer->authmethods)
09514          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09515       ast_clear_flag(peer, IAX_DELME); 
09516       /* Make sure these are IPv4 addresses */
09517       peer->addr.sin_family = AF_INET;
09518    }
09519    if (oldha)
09520       ast_free_ha(oldha);
09521    return peer;
09522 }
09523 
09524 static void user_destructor(void *obj)
09525 {
09526    struct iax2_user *user = obj;
09527 
09528    ast_free_ha(user->ha);
09529    free_context(user->contexts);
09530    if(user->vars) {
09531       ast_variables_destroy(user->vars);
09532       user->vars = NULL;
09533    }
09534    ast_string_field_free_memory(user);
09535 }
09536 
09537 /*! \brief Create in-memory user structure from configuration */
09538 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09539 {
09540    struct iax2_user *user = NULL;
09541    struct iax2_context *con, *conl = NULL;
09542    struct ast_ha *oldha = NULL;
09543    struct iax2_context *oldcon = NULL;
09544    int format;
09545    int firstpass=1;
09546    int oldcurauthreq = 0;
09547    char *varname = NULL, *varval = NULL;
09548    struct ast_variable *tmpvar = NULL;
09549    struct iax2_user tmp_user = {
09550       .name = name,
09551    };
09552 
09553    if (!temponly) {
09554       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09555       if (user && !ast_test_flag(user, IAX_DELME))
09556          firstpass = 0;
09557    }
09558 
09559    if (user) {
09560       if (firstpass) {
09561          oldcurauthreq = user->curauthreq;
09562          oldha = user->ha;
09563          oldcon = user->contexts;
09564          user->ha = NULL;
09565          user->contexts = NULL;
09566       }
09567       /* Already in the list, remove it and it will be added back (or FREE'd) */
09568       ao2_unlink(users, user);
09569    } else {
09570       user = ao2_alloc(sizeof(*user), user_destructor);
09571    }
09572    
09573    if (user) {
09574       if (firstpass) {
09575          ast_string_field_free_memory(user);
09576          memset(user, 0, sizeof(struct iax2_user));
09577          if (ast_string_field_init(user, 32)) {
09578             user = user_unref(user);
09579             goto cleanup;
09580          }
09581          user->maxauthreq = maxauthreq;
09582          user->curauthreq = oldcurauthreq;
09583          user->prefs = prefs;
09584          user->capability = iax2_capability;
09585          user->encmethods = iax2_encryption;
09586          user->adsi = adsi;
09587          ast_string_field_set(user, name, name);
09588          ast_string_field_set(user, language, language);
09589          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09590          ast_clear_flag(user, IAX_HASCALLERID);
09591          ast_string_field_set(user, cid_name, "");
09592          ast_string_field_set(user, cid_num, "");
09593       }
09594       if (!v) {
09595          v = alt;
09596          alt = NULL;
09597       }
09598       while(v) {
09599          if (!strcasecmp(v->name, "context")) {
09600             con = build_context(v->value);
09601             if (con) {
09602                if (conl)
09603                   conl->next = con;
09604                else
09605                   user->contexts = con;
09606                conl = con;
09607             }
09608          } else if (!strcasecmp(v->name, "permit") ||
09609                   !strcasecmp(v->name, "deny")) {
09610             user->ha = ast_append_ha(v->name, v->value, user->ha);
09611          } else if (!strcasecmp(v->name, "setvar")) {
09612             varname = ast_strdupa(v->value);
09613             if (varname && (varval = strchr(varname,'='))) {
09614                *varval = '\0';
09615                varval++;
09616                if((tmpvar = ast_variable_new(varname, varval))) {
09617                   tmpvar->next = user->vars; 
09618                   user->vars = tmpvar;
09619                }
09620             }
09621          } else if (!strcasecmp(v->name, "allow")) {
09622             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09623          } else if (!strcasecmp(v->name, "disallow")) {
09624             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09625          } else if (!strcasecmp(v->name, "trunk")) {
09626             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09627             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09628                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09629                ast_clear_flag(user, IAX_TRUNK);
09630             }
09631          } else if (!strcasecmp(v->name, "auth")) {
09632             user->authmethods = get_auth_methods(v->value);
09633          } else if (!strcasecmp(v->name, "encryption")) {
09634             user->encmethods = get_encrypt_methods(v->value);
09635          } else if (!strcasecmp(v->name, "notransfer")) {
09636             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09637             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09638             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09639          } else if (!strcasecmp(v->name, "transfer")) {
09640             if (!strcasecmp(v->value, "mediaonly")) {
09641                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09642             } else if (ast_true(v->value)) {
09643                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09644             } else 
09645                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09646          } else if (!strcasecmp(v->name, "codecpriority")) {
09647             if(!strcasecmp(v->value, "caller"))
09648                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09649             else if(!strcasecmp(v->value, "disabled"))
09650                ast_set_flag(user, IAX_CODEC_NOPREFS);
09651             else if(!strcasecmp(v->value, "reqonly")) {
09652                ast_set_flag(user, IAX_CODEC_NOCAP);
09653                ast_set_flag(user, IAX_CODEC_NOPREFS);
09654             }
09655          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09656             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09657          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09658             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09659          } else if (!strcasecmp(v->name, "dbsecret")) {
09660             ast_string_field_set(user, dbsecret, v->value);
09661          } else if (!strcasecmp(v->name, "secret")) {
09662             if (!ast_strlen_zero(user->secret)) {
09663                char *old = ast_strdupa(user->secret);
09664 
09665                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09666             } else
09667                ast_string_field_set(user, secret, v->value);
09668          } else if (!strcasecmp(v->name, "callerid")) {
09669             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09670                char name2[80];
09671                char num2[80];
09672                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09673                ast_string_field_set(user, cid_name, name2);
09674                ast_string_field_set(user, cid_num, num2);
09675                ast_set_flag(user, IAX_HASCALLERID);
09676             } else {
09677                ast_clear_flag(user, IAX_HASCALLERID);
09678                ast_string_field_set(user, cid_name, "");
09679                ast_string_field_set(user, cid_num, "");
09680             }
09681          } else if (!strcasecmp(v->name, "fullname")) {
09682             if (!ast_strlen_zero(v->value)) {
09683                ast_string_field_set(user, cid_name, v->value);
09684                ast_set_flag(user, IAX_HASCALLERID);
09685             } else {
09686                ast_string_field_set(user, cid_name, "");
09687                if (ast_strlen_zero(user->cid_num))
09688                   ast_clear_flag(user, IAX_HASCALLERID);
09689             }
09690          } else if (!strcasecmp(v->name, "cid_number")) {
09691             if (!ast_strlen_zero(v->value)) {
09692                ast_string_field_set(user, cid_num, v->value);
09693                ast_set_flag(user, IAX_HASCALLERID);
09694             } else {
09695                ast_string_field_set(user, cid_num, "");
09696                if (ast_strlen_zero(user->cid_name))
09697                   ast_clear_flag(user, IAX_HASCALLERID);
09698             }
09699          } else if (!strcasecmp(v->name, "accountcode")) {
09700             ast_string_field_set(user, accountcode, v->value);
09701          } else if (!strcasecmp(v->name, "mohinterpret")) {
09702             ast_string_field_set(user, mohinterpret, v->value);
09703          } else if (!strcasecmp(v->name, "mohsuggest")) {
09704             ast_string_field_set(user, mohsuggest, v->value);
09705          } else if (!strcasecmp(v->name, "language")) {
09706             ast_string_field_set(user, language, v->value);
09707          } else if (!strcasecmp(v->name, "amaflags")) {
09708             format = ast_cdr_amaflags2int(v->value);
09709             if (format < 0) {
09710                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09711             } else {
09712                user->amaflags = format;
09713             }
09714          } else if (!strcasecmp(v->name, "inkeys")) {
09715             ast_string_field_set(user, inkeys, v->value);
09716          } else if (!strcasecmp(v->name, "maxauthreq")) {
09717             user->maxauthreq = atoi(v->value);
09718             if (user->maxauthreq < 0)
09719                user->maxauthreq = 0;
09720          } else if (!strcasecmp(v->name, "adsi")) {
09721             user->adsi = ast_true(v->value);
09722          }/* else if (strcasecmp(v->name,"type")) */
09723          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09724          v = v->next;
09725          if (!v) {
09726             v = alt;
09727             alt = NULL;
09728          }
09729       }
09730       if (!user->authmethods) {
09731          if (!ast_strlen_zero(user->secret)) {
09732             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09733             if (!ast_strlen_zero(user->inkeys))
09734                user->authmethods |= IAX_AUTH_RSA;
09735          } else if (!ast_strlen_zero(user->inkeys)) {
09736             user->authmethods = IAX_AUTH_RSA;
09737          } else {
09738             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09739          }
09740       }
09741       ast_clear_flag(user, IAX_DELME);
09742    }
09743 cleanup:
09744    if (oldha)
09745       ast_free_ha(oldha);
09746    if (oldcon)
09747       free_context(oldcon);
09748    return user;
09749 }
09750 
09751 static int peer_delme_cb(void *obj, void *arg, int flags)
09752 {
09753    struct iax2_peer *peer = obj;
09754 
09755    ast_set_flag(peer, IAX_DELME);
09756 
09757    return 0;
09758 }
09759 
09760 static int user_delme_cb(void *obj, void *arg, int flags)
09761 {
09762    struct iax2_user *user = obj;
09763 
09764    ast_set_flag(user, IAX_DELME);
09765 
09766    return 0;
09767 }
09768 
09769 static void delete_users(void)
09770 {
09771    struct iax2_registry *reg;
09772 
09773    ao2_callback(users, 0, user_delme_cb, NULL);
09774 
09775    AST_LIST_LOCK(&registrations);
09776    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09777       ast_sched_del(sched, reg->expire);
09778       if (reg->callno) {
09779          ast_mutex_lock(&iaxsl[reg->callno]);
09780          if (iaxs[reg->callno]) {
09781             iaxs[reg->callno]->reg = NULL;
09782             iax2_destroy(reg->callno);
09783          }
09784          ast_mutex_unlock(&iaxsl[reg->callno]);
09785       }
09786       if (reg->dnsmgr)
09787          ast_dnsmgr_release(reg->dnsmgr);
09788       free(reg);
09789    }
09790    AST_LIST_UNLOCK(&registrations);
09791 
09792    ao2_callback(peers, 0, peer_delme_cb, NULL);
09793 }
09794 
09795 static void prune_users(void)
09796 {
09797    struct iax2_user *user;
09798    struct ao2_iterator i;
09799 
09800    i = ao2_iterator_init(users, 0);
09801    while ((user = ao2_iterator_next(&i))) {
09802       if (ast_test_flag(user, IAX_DELME))
09803          ao2_unlink(users, user);
09804       user_unref(user);
09805    }
09806 }
09807 
09808 /* Prune peers who still are supposed to be deleted */
09809 static void prune_peers(void)
09810 {
09811    struct iax2_peer *peer;
09812    struct ao2_iterator i;
09813 
09814    i = ao2_iterator_init(peers, 0);
09815    while ((peer = ao2_iterator_next(&i))) {
09816       if (ast_test_flag(peer, IAX_DELME))
09817          unlink_peer(peer);
09818       peer_unref(peer);
09819    }
09820 }
09821 
09822 static void set_timing(void)
09823 {
09824 #ifdef HAVE_ZAPTEL
09825    int bs = trunkfreq * 8;
09826    if (timingfd > -1) {
09827       if (
09828 #ifdef ZT_TIMERACK
09829          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09830 #endif         
09831          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09832          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09833    }
09834 #endif
09835 }
09836 
09837 static void set_config_destroy(void)
09838 {
09839    strcpy(accountcode, "");
09840    strcpy(language, "");
09841    strcpy(mohinterpret, "default");
09842    strcpy(mohsuggest, "");
09843    amaflags = 0;
09844    delayreject = 0;
09845    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09846    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09847    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09848    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09849    delete_users();
09850 }
09851 
09852 /*! \brief Load configuration */
09853 static int set_config(char *config_file, int reload)
09854 {
09855    struct ast_config *cfg, *ucfg;
09856    int capability=iax2_capability;
09857    struct ast_variable *v;
09858    char *cat;
09859    const char *utype;
09860    const char *tosval;
09861    int format;
09862    int portno = IAX_DEFAULT_PORTNO;
09863    int  x;
09864    struct iax2_user *user;
09865    struct iax2_peer *peer;
09866    struct ast_netsock *ns;
09867 #if 0
09868    static unsigned short int last_port=0;
09869 #endif
09870 
09871    cfg = ast_config_load(config_file);
09872    
09873    if (!cfg) {
09874       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09875       return -1;
09876    }
09877 
09878    if (reload) {
09879       set_config_destroy();
09880    }
09881 
09882    /* Reset global codec prefs */   
09883    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09884    
09885    /* Reset Global Flags */
09886    memset(&globalflags, 0, sizeof(globalflags));
09887    ast_set_flag(&globalflags, IAX_RTUPDATE);
09888 
09889 #ifdef SO_NO_CHECK
09890    nochecksums = 0;
09891 #endif
09892 
09893    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09894    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09895 
09896    maxauthreq = 3;
09897 
09898    v = ast_variable_browse(cfg, "general");
09899 
09900    /* Seed initial tos value */
09901    tosval = ast_variable_retrieve(cfg, "general", "tos");
09902    if (tosval) {
09903       if (ast_str2tos(tosval, &tos))
09904          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09905    }
09906    while(v) {
09907       if (!strcasecmp(v->name, "bindport")){ 
09908          if (reload)
09909             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09910          else
09911             portno = atoi(v->value);
09912       } else if (!strcasecmp(v->name, "pingtime")) 
09913          ping_time = atoi(v->value);
09914       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09915          if (reload) {
09916             if (atoi(v->value) != iaxthreadcount)
09917                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09918          } else {
09919             iaxthreadcount = atoi(v->value);
09920             if (iaxthreadcount < 1) {
09921                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09922                iaxthreadcount = 1;
09923             } else if (iaxthreadcount > 256) {
09924                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09925                iaxthreadcount = 256;
09926             }
09927          }
09928       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09929          if (reload) {
09930             AST_LIST_LOCK(&dynamic_list);
09931             iaxmaxthreadcount = atoi(v->value);
09932             AST_LIST_UNLOCK(&dynamic_list);
09933          } else {
09934             iaxmaxthreadcount = atoi(v->value);
09935             if (iaxmaxthreadcount < 0) {
09936                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09937                iaxmaxthreadcount = 0;
09938             } else if (iaxmaxthreadcount > 256) {
09939                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09940                iaxmaxthreadcount = 256;
09941             }
09942          }
09943       } else if (!strcasecmp(v->name, "nochecksums")) {
09944 #ifdef SO_NO_CHECK
09945          if (ast_true(v->value))
09946             nochecksums = 1;
09947          else
09948             nochecksums = 0;
09949 #else
09950          if (ast_true(v->value))
09951             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09952 #endif
09953       }
09954       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09955          maxjitterbuffer = atoi(v->value);
09956       else if (!strcasecmp(v->name, "resyncthreshold")) 
09957          resyncthreshold = atoi(v->value);
09958       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09959          maxjitterinterps = atoi(v->value);
09960       else if (!strcasecmp(v->name, "lagrqtime")) 
09961          lagrq_time = atoi(v->value);
09962       else if (!strcasecmp(v->name, "maxregexpire")) 
09963          max_reg_expire = atoi(v->value);
09964       else if (!strcasecmp(v->name, "minregexpire")) 
09965          min_reg_expire = atoi(v->value);
09966       else if (!strcasecmp(v->name, "bindaddr")) {
09967          if (reload) {
09968             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09969          } else {
09970             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09971                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09972             } else {
09973                if (option_verbose > 1) {
09974                   if (strchr(v->value, ':'))
09975                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09976                   else
09977                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09978                }
09979                if (defaultsockfd < 0) 
09980                   defaultsockfd = ast_netsock_sockfd(ns);
09981                ast_netsock_unref(ns);
09982             }
09983          }
09984       } else if (!strcasecmp(v->name, "authdebug"))
09985          authdebug = ast_true(v->value);
09986       else if (!strcasecmp(v->name, "encryption"))
09987          iax2_encryption = get_encrypt_methods(v->value);
09988       else if (!strcasecmp(v->name, "notransfer")) {
09989          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09990          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09991          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09992       } else if (!strcasecmp(v->name, "transfer")) {
09993          if (!strcasecmp(v->value, "mediaonly")) {
09994             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09995          } else if (ast_true(v->value)) {
09996             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09997          } else 
09998             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09999       } else if (!strcasecmp(v->name, "codecpriority")) {
10000          if(!strcasecmp(v->value, "caller"))
10001             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10002          else if(!strcasecmp(v->value, "disabled"))
10003             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10004          else if(!strcasecmp(v->value, "reqonly")) {
10005             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10006             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10007          }
10008       } else if (!strcasecmp(v->name, "jitterbuffer"))
10009          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10010       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10011          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10012       else if (!strcasecmp(v->name, "delayreject"))
10013          delayreject = ast_true(v->value);
10014       else if (!strcasecmp(v->name, "allowfwdownload"))
10015          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10016       else if (!strcasecmp(v->name, "rtcachefriends"))
10017          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10018       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10019          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10020       else if (!strcasecmp(v->name, "rtupdate"))
10021          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10022       else if (!strcasecmp(v->name, "trunktimestamps"))
10023          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10024       else if (!strcasecmp(v->name, "rtautoclear")) {
10025          int i = atoi(v->value);
10026          if(i > 0)
10027             global_rtautoclear = i;
10028          else
10029             i = 0;
10030          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10031       } else if (!strcasecmp(v->name, "trunkfreq")) {
10032          trunkfreq = atoi(v->value);
10033          if (trunkfreq < 10)
10034             trunkfreq = 10;
10035       } else if (!strcasecmp(v->name, "autokill")) {
10036          if (sscanf(v->value, "%d", &x) == 1) {
10037             if (x >= 0)
10038                autokill = x;
10039             else
10040                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10041          } else if (ast_true(v->value)) {
10042             autokill = DEFAULT_MAXMS;
10043          } else {
10044             autokill = 0;
10045          }
10046       } else if (!strcasecmp(v->name, "bandwidth")) {
10047          if (!strcasecmp(v->value, "low")) {
10048             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10049          } else if (!strcasecmp(v->value, "medium")) {
10050             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10051          } else if (!strcasecmp(v->value, "high")) {
10052             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10053          } else
10054             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10055       } else if (!strcasecmp(v->name, "allow")) {
10056          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10057       } else if (!strcasecmp(v->name, "disallow")) {
10058          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10059       } else if (!strcasecmp(v->name, "register")) {
10060          iax2_register(v->value, v->lineno);
10061       } else if (!strcasecmp(v->name, "iaxcompat")) {
10062          iaxcompat = ast_true(v->value);
10063       } else if (!strcasecmp(v->name, "regcontext")) {
10064          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10065          /* Create context if it doesn't exist already */
10066          if (!ast_context_find(regcontext))
10067             ast_context_create(NULL, regcontext, "IAX2");
10068       } else if (!strcasecmp(v->name, "tos")) {
10069          if (ast_str2tos(v->value, &tos))
10070             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10071       } else if (!strcasecmp(v->name, "accountcode")) {
10072          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10073       } else if (!strcasecmp(v->name, "mohinterpret")) {
10074          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10075       } else if (!strcasecmp(v->name, "mohsuggest")) {
10076          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10077       } else if (!strcasecmp(v->name, "amaflags")) {
10078          format = ast_cdr_amaflags2int(v->value);
10079          if (format < 0) {
10080             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10081          } else {
10082             amaflags = format;
10083          }
10084       } else if (!strcasecmp(v->name, "language")) {
10085          ast_copy_string(language, v->value, sizeof(language));
10086       } else if (!strcasecmp(v->name, "maxauthreq")) {
10087          maxauthreq = atoi(v->value);
10088          if (maxauthreq < 0)
10089             maxauthreq = 0;
10090       } else if (!strcasecmp(v->name, "adsi")) {
10091          adsi = ast_true(v->value);
10092       } /*else if (strcasecmp(v->name,"type")) */
10093       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10094       v = v->next;
10095    }
10096    
10097    if (defaultsockfd < 0) {
10098       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10099          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10100       } else {
10101          if (option_verbose > 1)
10102             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10103          defaultsockfd = ast_netsock_sockfd(ns);
10104          ast_netsock_unref(ns);
10105       }
10106    }
10107    if (reload) {
10108       ast_netsock_release(outsock);
10109       outsock = ast_netsock_list_alloc();
10110       if (!outsock) {
10111          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10112          return -1;
10113       }
10114       ast_netsock_init(outsock);
10115    }
10116 
10117    if (min_reg_expire > max_reg_expire) {
10118       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10119          min_reg_expire, max_reg_expire, max_reg_expire);
10120       min_reg_expire = max_reg_expire;
10121    }
10122    iax2_capability = capability;
10123    
10124    ucfg = ast_config_load("users.conf");
10125    if (ucfg) {
10126       struct ast_variable *gen;
10127       int genhasiax;
10128       int genregisteriax;
10129       const char *hasiax, *registeriax;
10130       
10131       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10132       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10133       gen = ast_variable_browse(ucfg, "general");
10134       cat = ast_category_browse(ucfg, NULL);
10135       while (cat) {
10136          if (strcasecmp(cat, "general")) {
10137             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10138             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10139             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10140                /* Start with general parameters, then specific parameters, user and peer */
10141                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10142                if (user) {
10143                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10144                   user = user_unref(user);
10145                }
10146                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10147                if (peer) {
10148                   if (ast_test_flag(peer, IAX_DYNAMIC))
10149                      reg_source_db(peer);
10150                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10151                   peer = peer_unref(peer);
10152                }
10153             }
10154             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10155                char tmp[256];
10156                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10157                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10158                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10159                if (!host)
10160                   host = ast_variable_retrieve(ucfg, "general", "host");
10161                if (!username)
10162                   username = ast_variable_retrieve(ucfg, "general", "username");
10163                if (!secret)
10164                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10165                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10166                   if (!ast_strlen_zero(secret))
10167                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10168                   else
10169                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10170                   iax2_register(tmp, 0);
10171                }
10172             }
10173          }
10174          cat = ast_category_browse(ucfg, cat);
10175       }
10176       ast_config_destroy(ucfg);
10177    }
10178    
10179    cat = ast_category_browse(cfg, NULL);
10180    while(cat) {
10181       if (strcasecmp(cat, "general")) {
10182          utype = ast_variable_retrieve(cfg, cat, "type");
10183          if (utype) {
10184             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10185                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10186                if (user) {
10187                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10188                   user = user_unref(user);
10189                }
10190             }
10191             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10192                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10193                if (peer) {
10194                   if (ast_test_flag(peer, IAX_DYNAMIC))
10195                      reg_source_db(peer);
10196                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10197                   peer = peer_unref(peer);
10198                }
10199             } else if (strcasecmp(utype, "user")) {
10200                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10201             }
10202          } else
10203             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10204       }
10205       cat = ast_category_browse(cfg, cat);
10206    }
10207    ast_config_destroy(cfg);
10208    set_timing();
10209    return 1;
10210 }
10211 
10212 static void poke_all_peers(void)
10213 {
10214    struct ao2_iterator i;
10215    struct iax2_peer *peer;
10216 
10217    i = ao2_iterator_init(peers, 0);
10218    while ((peer = ao2_iterator_next(&i))) {
10219       iax2_poke_peer(peer, 0);
10220       peer_unref(peer);
10221    }
10222 }
10223 static int reload_config(void)
10224 {
10225    char *config = "iax.conf";
10226    struct iax2_registry *reg;
10227 
10228    if (set_config(config, 1) > 0) {
10229       prune_peers();
10230       prune_users();
10231       AST_LIST_LOCK(&registrations);
10232       AST_LIST_TRAVERSE(&registrations, reg, entry)
10233          iax2_do_register(reg);
10234       AST_LIST_UNLOCK(&registrations);
10235       /* Qualify hosts, too */
10236       poke_all_peers();
10237    }
10238    reload_firmware(0);
10239    iax_provision_reload();
10240 
10241    return 0;
10242 }
10243 
10244 static int iax2_reload(int fd, int argc, char *argv[])
10245 {
10246    return reload_config();
10247 }
10248 
10249 static int reload(void)
10250 {
10251    return reload_config();
10252 }
10253 
10254 static int cache_get_callno_locked(const char *data)
10255 {
10256    struct sockaddr_in sin;
10257    int x;
10258    int callno;
10259    struct iax_ie_data ied;
10260    struct create_addr_info cai;
10261    struct parsed_dial_string pds;
10262    char *tmpstr;
10263 
10264    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10265       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10266          look up entries for a single context */
10267       if (!ast_mutex_trylock(&iaxsl[x])) {
10268          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10269             return x;
10270          ast_mutex_unlock(&iaxsl[x]);
10271       }
10272    }
10273 
10274    /* No match found, we need to create a new one */
10275 
10276    memset(&cai, 0, sizeof(cai));
10277    memset(&ied, 0, sizeof(ied));
10278    memset(&pds, 0, sizeof(pds));
10279 
10280    tmpstr = ast_strdupa(data);
10281    parse_dial_string(tmpstr, &pds);
10282 
10283    if (ast_strlen_zero(pds.peer)) {
10284       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10285       return -1;
10286    }
10287 
10288    /* Populate our address from the given */
10289    if (create_addr(pds.peer, NULL, &sin, &cai))
10290       return -1;
10291 
10292    if (option_debug)
10293       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10294          pds.peer, pds.username, pds.password, pds.context);
10295 
10296    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10297    if (callno < 1) {
10298       ast_log(LOG_WARNING, "Unable to create call\n");
10299       return -1;
10300    }
10301 
10302    ast_string_field_set(iaxs[callno], dproot, data);
10303    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10304 
10305    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10306    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10307    /* the string format is slightly different from a standard dial string,
10308       because the context appears in the 'exten' position
10309    */
10310    if (pds.exten)
10311       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10312    if (pds.username)
10313       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10314    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10315    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10316    /* Keep password handy */
10317    if (pds.password)
10318       ast_string_field_set(iaxs[callno], secret, pds.password);
10319    if (pds.key)
10320       ast_string_field_set(iaxs[callno], outkey, pds.key);
10321    /* Start the call going */
10322    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10323 
10324    return callno;
10325 }
10326 
10327 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10328 {
10329    struct iax2_dpcache *dp, *prev = NULL, *next;
10330    struct timeval tv;
10331    int x;
10332    int com[2];
10333    int timeout;
10334    int old=0;
10335    int outfd;
10336    int abort;
10337    int callno;
10338    struct ast_channel *c;
10339    struct ast_frame *f;
10340    gettimeofday(&tv, NULL);
10341    dp = dpcache;
10342    while(dp) {
10343       next = dp->next;
10344       /* Expire old caches */
10345       if (ast_tvcmp(tv, dp->expiry) > 0) {
10346             /* It's expired, let it disappear */
10347             if (prev)
10348                prev->next = dp->next;
10349             else
10350                dpcache = dp->next;
10351             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10352                /* Free memory and go again */
10353                free(dp);
10354             } else {
10355                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);
10356             }
10357             dp = next;
10358             continue;
10359       }
10360       /* We found an entry that matches us! */
10361       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10362          break;
10363       prev = dp;
10364       dp = next;
10365    }
10366    if (!dp) {
10367       /* No matching entry.  Create a new one. */
10368       /* First, can we make a callno? */
10369       callno = cache_get_callno_locked(data);
10370       if (callno < 0) {
10371          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10372          return NULL;
10373       }
10374       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10375          ast_mutex_unlock(&iaxsl[callno]);
10376          return NULL;
10377       }
10378       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10379       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10380       gettimeofday(&dp->expiry, NULL);
10381       dp->orig = dp->expiry;
10382       /* Expires in 30 mins by default */
10383       dp->expiry.tv_sec += iaxdefaultdpcache;
10384       dp->next = dpcache;
10385       dp->flags = CACHE_FLAG_PENDING;
10386       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10387          dp->waiters[x] = -1;
10388       dpcache = dp;
10389       dp->peer = iaxs[callno]->dpentries;
10390       iaxs[callno]->dpentries = dp;
10391       /* Send the request if we're already up */
10392       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10393          iax2_dprequest(dp, callno);
10394       ast_mutex_unlock(&iaxsl[callno]);
10395    }
10396    /* By here we must have a dp */
10397    if (dp->flags & CACHE_FLAG_PENDING) {
10398       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10399          for a reply to come back so long as it's pending */
10400       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10401          /* Find an empty slot */
10402          if (dp->waiters[x] < 0)
10403             break;
10404       }
10405       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10406          ast_log(LOG_WARNING, "No more waiter positions available\n");
10407          return NULL;
10408       }
10409       if (pipe(com)) {
10410          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10411          return NULL;
10412       }
10413       dp->waiters[x] = com[1];
10414       /* Okay, now we wait */
10415       timeout = iaxdefaulttimeout * 1000;
10416       /* Temporarily unlock */
10417       ast_mutex_unlock(&dpcache_lock);
10418       /* Defer any dtmf */
10419       if (chan)
10420          old = ast_channel_defer_dtmf(chan);
10421       abort = 0;
10422       while(timeout) {
10423          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10424          if (outfd > -1) {
10425             break;
10426          }
10427          if (c) {
10428             f = ast_read(c);
10429             if (f)
10430                ast_frfree(f);
10431             else {
10432                /* Got hung up on, abort! */
10433                break;
10434                abort = 1;
10435             }
10436          }
10437       }
10438       if (!timeout) {
10439          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10440       }
10441       ast_mutex_lock(&dpcache_lock);
10442       dp->waiters[x] = -1;
10443       close(com[1]);
10444       close(com[0]);
10445       if (abort) {
10446          /* Don't interpret anything, just abort.  Not sure what th epoint
10447            of undeferring dtmf on a hung up channel is but hey whatever */
10448          if (!old && chan)
10449             ast_channel_undefer_dtmf(chan);
10450          return NULL;
10451       }
10452       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10453          /* Now to do non-independent analysis the results of our wait */
10454          if (dp->flags & CACHE_FLAG_PENDING) {
10455             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10456                pending.  Don't let it take as long to timeout. */
10457             dp->flags &= ~CACHE_FLAG_PENDING;
10458             dp->flags |= CACHE_FLAG_TIMEOUT;
10459             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10460                systems without leaving it unavailable once the server comes back online */
10461             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10462             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10463                if (dp->waiters[x] > -1)
10464                   write(dp->waiters[x], "asdf", 4);
10465          }
10466       }
10467       /* Our caller will obtain the rest */
10468       if (!old && chan)
10469          ast_channel_undefer_dtmf(chan);
10470    }
10471    return dp;  
10472 }
10473 
10474 /*! \brief Part of the IAX2 switch interface */
10475 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10476 {
10477    struct iax2_dpcache *dp;
10478    int res = 0;
10479 #if 0
10480    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10481 #endif
10482    if ((priority != 1) && (priority != 2))
10483       return 0;
10484    ast_mutex_lock(&dpcache_lock);
10485    dp = find_cache(chan, data, context, exten, priority);
10486    if (dp) {
10487       if (dp->flags & CACHE_FLAG_EXISTS)
10488          res= 1;
10489    }
10490    ast_mutex_unlock(&dpcache_lock);
10491    if (!dp) {
10492       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10493    }
10494    return res;
10495 }
10496 
10497 /*! \brief part of the IAX2 dial plan switch interface */
10498 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10499 {
10500    int res = 0;
10501    struct iax2_dpcache *dp;
10502 #if 0
10503    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10504 #endif
10505    if ((priority != 1) && (priority != 2))
10506       return 0;
10507    ast_mutex_lock(&dpcache_lock);
10508    dp = find_cache(chan, data, context, exten, priority);
10509    if (dp) {
10510       if (dp->flags & CACHE_FLAG_CANEXIST)
10511          res= 1;
10512    }
10513    ast_mutex_unlock(&dpcache_lock);
10514    if (!dp) {
10515       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10516    }
10517    return res;
10518 }
10519 
10520 /*! \brief Part of the IAX2 Switch interface */
10521 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10522 {
10523    int res = 0;
10524    struct iax2_dpcache *dp;
10525 #if 0
10526    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10527 #endif
10528    if ((priority != 1) && (priority != 2))
10529       return 0;
10530    ast_mutex_lock(&dpcache_lock);
10531    dp = find_cache(chan, data, context, exten, priority);
10532    if (dp) {
10533       if (dp->flags & CACHE_FLAG_MATCHMORE)
10534          res= 1;
10535    }
10536    ast_mutex_unlock(&dpcache_lock);
10537    if (!dp) {
10538       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10539    }
10540    return res;
10541 }
10542 
10543 /*! \brief Execute IAX2 dialplan switch */
10544 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10545 {
10546    char odata[256];
10547    char req[256];
10548    char *ncontext;
10549    struct iax2_dpcache *dp;
10550    struct ast_app *dial;
10551 #if 0
10552    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);
10553 #endif
10554    if (priority == 2) {
10555       /* Indicate status, can be overridden in dialplan */
10556       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10557       if (dialstatus) {
10558          dial = pbx_findapp(dialstatus);
10559          if (dial) 
10560             pbx_exec(chan, dial, "");
10561       }
10562       return -1;
10563    } else if (priority != 1)
10564       return -1;
10565    ast_mutex_lock(&dpcache_lock);
10566    dp = find_cache(chan, data, context, exten, priority);
10567    if (dp) {
10568       if (dp->flags & CACHE_FLAG_EXISTS) {
10569          ast_copy_string(odata, data, sizeof(odata));
10570          ncontext = strchr(odata, '/');
10571          if (ncontext) {
10572             *ncontext = '\0';
10573             ncontext++;
10574             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10575          } else {
10576             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10577          }
10578          if (option_verbose > 2)
10579             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10580       } else {
10581          ast_mutex_unlock(&dpcache_lock);
10582          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10583          return -1;
10584       }
10585    }
10586    ast_mutex_unlock(&dpcache_lock);
10587    dial = pbx_findapp("Dial");
10588    if (dial) {
10589       return pbx_exec(chan, dial, req);
10590    } else {
10591       ast_log(LOG_WARNING, "No dial application registered\n");
10592    }
10593    return -1;
10594 }
10595 
10596 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10597 {
10598    struct iax2_peer *peer;
10599    char *peername, *colname;
10600 
10601    peername = ast_strdupa(data);
10602 
10603    /* if our channel, return the IP address of the endpoint of current channel */
10604    if (!strcmp(peername,"CURRENTCHANNEL")) {
10605            unsigned short callno;
10606       if (chan->tech != &iax2_tech)
10607          return -1;
10608       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10609       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10610       return 0;
10611    }
10612 
10613    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10614       *colname++ = '\0';
10615    else if ((colname = strchr(peername, '|')))
10616       *colname++ = '\0';
10617    else
10618       colname = "ip";
10619 
10620    if (!(peer = find_peer(peername, 1)))
10621       return -1;
10622 
10623    if (!strcasecmp(colname, "ip")) {
10624       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10625    } else  if (!strcasecmp(colname, "status")) {
10626       peer_status(peer, buf, len); 
10627    } else  if (!strcasecmp(colname, "mailbox")) {
10628       ast_copy_string(buf, peer->mailbox, len);
10629    } else  if (!strcasecmp(colname, "context")) {
10630       ast_copy_string(buf, peer->context, len);
10631    } else  if (!strcasecmp(colname, "expire")) {
10632       snprintf(buf, len, "%d", peer->expire);
10633    } else  if (!strcasecmp(colname, "dynamic")) {
10634       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10635    } else  if (!strcasecmp(colname, "callerid_name")) {
10636       ast_copy_string(buf, peer->cid_name, len);
10637    } else  if (!strcasecmp(colname, "callerid_num")) {
10638       ast_copy_string(buf, peer->cid_num, len);
10639    } else  if (!strcasecmp(colname, "codecs")) {
10640       ast_getformatname_multiple(buf, len -1, peer->capability);
10641    } else  if (!strncasecmp(colname, "codec[", 6)) {
10642       char *codecnum, *ptr;
10643       int index = 0, codec = 0;
10644       
10645       codecnum = strchr(colname, '[');
10646       *codecnum = '\0';
10647       codecnum++;
10648       if ((ptr = strchr(codecnum, ']'))) {
10649          *ptr = '\0';
10650       }
10651       index = atoi(codecnum);
10652       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10653          ast_copy_string(buf, ast_getformatname(codec), len);
10654       }
10655    }
10656 
10657    peer_unref(peer);
10658 
10659    return 0;
10660 }
10661 
10662 struct ast_custom_function iaxpeer_function = {
10663    .name = "IAXPEER",
10664    .synopsis = "Gets IAX peer information",
10665    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10666    .read = function_iaxpeer,
10667    .desc = "If peername specified, valid items are:\n"
10668    "- ip (default)          The IP address.\n"
10669    "- status                The peer's status (if qualify=yes)\n"
10670    "- mailbox               The configured mailbox.\n"
10671    "- context               The configured context.\n"
10672    "- expire                The epoch time of the next expire.\n"
10673    "- dynamic               Is it dynamic? (yes/no).\n"
10674    "- callerid_name         The configured Caller ID name.\n"
10675    "- callerid_num          The configured Caller ID number.\n"
10676    "- codecs                The configured codecs.\n"
10677    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10678    "\n"
10679    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10680    "\n"
10681 };
10682 
10683 
10684 /*! \brief Part of the device state notification system ---*/
10685 static int iax2_devicestate(void *data) 
10686 {
10687    struct parsed_dial_string pds;
10688    char *tmp = ast_strdupa(data);
10689    struct iax2_peer *p;
10690    int res = AST_DEVICE_INVALID;
10691 
10692    memset(&pds, 0, sizeof(pds));
10693    parse_dial_string(tmp, &pds);
10694 
10695    if (ast_strlen_zero(pds.peer)) {
10696       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10697       return res;
10698    }
10699    
10700    if (option_debug > 2)
10701       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10702 
10703    /* SLD: FIXME: second call to find_peer during registration */
10704    if (!(p = find_peer(pds.peer, 1)))
10705       return res;
10706 
10707    res = AST_DEVICE_UNAVAILABLE;
10708    if (option_debug > 2) 
10709       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10710          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10711    
10712    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10713        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10714       /* Peer is registered, or have default IP address
10715          and a valid registration */
10716       if (p->historicms == 0 || p->historicms <= p->maxms)
10717          /* let the core figure out whether it is in use or not */
10718          res = AST_DEVICE_UNKNOWN;  
10719    }
10720 
10721    peer_unref(p);
10722 
10723    return res;
10724 }
10725 
10726 static struct ast_switch iax2_switch = 
10727 {
10728    name:          "IAX2",
10729    description:      "IAX Remote Dialplan Switch",
10730    exists:        iax2_exists,
10731    canmatch:      iax2_canmatch,
10732    exec:       iax2_exec,
10733    matchmore:     iax2_matchmore,
10734 };
10735 
10736 static char show_stats_usage[] =
10737 "Usage: iax2 show stats\n"
10738 "       Display statistics on IAX channel driver.\n";
10739 
10740 static char show_cache_usage[] =
10741 "Usage: iax2 show cache\n"
10742 "       Display currently cached IAX Dialplan results.\n";
10743 
10744 static char show_peer_usage[] =
10745 "Usage: iax2 show peer <name>\n"
10746 "       Display details on specific IAX peer\n";
10747 
10748 static char prune_realtime_usage[] =
10749 "Usage: iax2 prune realtime [<peername>|all]\n"
10750 "       Prunes object(s) from the cache\n";
10751 
10752 static char iax2_reload_usage[] =
10753 "Usage: iax2 reload\n"
10754 "       Reloads IAX configuration from iax.conf\n";
10755 
10756 static char show_prov_usage[] =
10757 "Usage: iax2 provision <host> <template> [forced]\n"
10758 "       Provisions the given peer or IP address using a template\n"
10759 "       matching either 'template' or '*' if the template is not\n"
10760 "       found.  If 'forced' is specified, even empty provisioning\n"
10761 "       fields will be provisioned as empty fields.\n";
10762 
10763 static char show_users_usage[] = 
10764 "Usage: iax2 show users [like <pattern>]\n"
10765 "       Lists all known IAX2 users.\n"
10766 "       Optional regular expression pattern is used to filter the user list.\n";
10767 
10768 static char show_channels_usage[] = 
10769 "Usage: iax2 show channels\n"
10770 "       Lists all currently active IAX channels.\n";
10771 
10772 static char show_netstats_usage[] = 
10773 "Usage: iax2 show netstats\n"
10774 "       Lists network status for all currently active IAX channels.\n";
10775 
10776 static char show_threads_usage[] = 
10777 "Usage: iax2 show threads\n"
10778 "       Lists status of IAX helper threads\n";
10779 
10780 static char show_peers_usage[] = 
10781 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10782 "       Lists all known IAX2 peers.\n"
10783 "       Optional 'registered' argument lists only peers with known addresses.\n"
10784 "       Optional regular expression pattern is used to filter the peer list.\n";
10785 
10786 static char show_firmware_usage[] = 
10787 "Usage: iax2 show firmware\n"
10788 "       Lists all known IAX firmware images.\n";
10789 
10790 static char show_reg_usage[] =
10791 "Usage: iax2 show registry\n"
10792 "       Lists all registration requests and status.\n";
10793 
10794 static char debug_usage[] = 
10795 "Usage: iax2 set debug\n"
10796 "       Enables dumping of IAX packets for debugging purposes\n";
10797 
10798 static char no_debug_usage[] = 
10799 "Usage: iax2 set debug off\n"
10800 "       Disables dumping of IAX packets for debugging purposes\n";
10801 
10802 static char debug_trunk_usage[] =
10803 "Usage: iax2 set debug trunk\n"
10804 "       Requests current status of IAX trunking\n";
10805 
10806 static char no_debug_trunk_usage[] =
10807 "Usage: iax2 set debug trunk off\n"
10808 "       Requests current status of IAX trunking\n";
10809 
10810 static char debug_jb_usage[] =
10811 "Usage: iax2 set debug jb\n"
10812 "       Enables jitterbuffer debugging information\n";
10813 
10814 static char no_debug_jb_usage[] =
10815 "Usage: iax2 set debug jb off\n"
10816 "       Disables jitterbuffer debugging information\n";
10817 
10818 static char iax2_test_losspct_usage[] =
10819 "Usage: iax2 test losspct <percentage>\n"
10820 "       For testing, throws away <percentage> percent of incoming packets\n";
10821 
10822 #ifdef IAXTESTS
10823 static char iax2_test_late_usage[] =
10824 "Usage: iax2 test late <ms>\n"
10825 "       For testing, count the next frame as <ms> ms late\n";
10826 
10827 static char iax2_test_resync_usage[] =
10828 "Usage: iax2 test resync <ms>\n"
10829 "       For testing, adjust all future frames by <ms> ms\n";
10830 
10831 static char iax2_test_jitter_usage[] =
10832 "Usage: iax2 test jitter <ms> <pct>\n"
10833 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10834 #endif /* IAXTESTS */
10835 
10836 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10837    { "iax2", "trunk", "debug", NULL },
10838    iax2_do_trunk_debug, NULL,
10839    NULL };
10840 
10841 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10842    { "iax2", "jb", "debug", NULL },
10843    iax2_do_jb_debug, NULL,
10844    NULL };
10845 
10846 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10847    { "iax2", "no", "debug", NULL },
10848    iax2_no_debug, NULL,
10849    NULL };
10850 
10851 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10852    { "iax2", "no", "trunk", "debug", NULL },
10853    iax2_no_trunk_debug, NULL,
10854    NULL };
10855 
10856 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10857    { "iax2", "no", "jb", "debug", NULL },
10858    iax2_no_jb_debug, NULL,
10859    NULL };
10860 
10861 static struct ast_cli_entry cli_iax2[] = {
10862    { { "iax2", "show", "cache", NULL },
10863    iax2_show_cache, "Display IAX cached dialplan",
10864    show_cache_usage, NULL, },
10865 
10866    { { "iax2", "show", "channels", NULL },
10867    iax2_show_channels, "List active IAX channels",
10868    show_channels_usage, NULL, },
10869 
10870    { { "iax2", "show", "firmware", NULL },
10871    iax2_show_firmware, "List available IAX firmwares",
10872    show_firmware_usage, NULL, },
10873 
10874    { { "iax2", "show", "netstats", NULL },
10875    iax2_show_netstats, "List active IAX channel netstats",
10876    show_netstats_usage, NULL, },
10877 
10878    { { "iax2", "show", "peers", NULL },
10879    iax2_show_peers, "List defined IAX peers",
10880    show_peers_usage, NULL, },
10881 
10882    { { "iax2", "show", "registry", NULL },
10883    iax2_show_registry, "Display IAX registration status",
10884    show_reg_usage, NULL, },
10885 
10886    { { "iax2", "show", "stats", NULL },
10887    iax2_show_stats, "Display IAX statistics",
10888    show_stats_usage, NULL, },
10889 
10890    { { "iax2", "show", "threads", NULL },
10891    iax2_show_threads, "Display IAX helper thread info",
10892    show_threads_usage, NULL, },
10893 
10894    { { "iax2", "show", "users", NULL },
10895    iax2_show_users, "List defined IAX users",
10896    show_users_usage, NULL, },
10897 
10898    { { "iax2", "prune", "realtime", NULL },
10899    iax2_prune_realtime, "Prune a cached realtime lookup",
10900    prune_realtime_usage, complete_iax2_show_peer },
10901 
10902    { { "iax2", "reload", NULL },
10903    iax2_reload, "Reload IAX configuration",
10904    iax2_reload_usage },
10905 
10906    { { "iax2", "show", "peer", NULL },
10907    iax2_show_peer, "Show details on specific IAX peer",
10908    show_peer_usage, complete_iax2_show_peer },
10909 
10910    { { "iax2", "set", "debug", NULL },
10911    iax2_do_debug, "Enable IAX debugging",
10912    debug_usage },
10913 
10914    { { "iax2", "set", "debug", "trunk", NULL },
10915    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10916    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10917 
10918    { { "iax2", "set", "debug", "jb", NULL },
10919    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10920    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10921 
10922    { { "iax2", "set", "debug", "off", NULL },
10923    iax2_no_debug, "Disable IAX debugging",
10924    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10925 
10926    { { "iax2", "set", "debug", "trunk", "off", NULL },
10927    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10928    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10929 
10930    { { "iax2", "set", "debug", "jb", "off", NULL },
10931    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10932    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10933 
10934    { { "iax2", "test", "losspct", NULL },
10935    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10936    iax2_test_losspct_usage },
10937 
10938    { { "iax2", "provision", NULL },
10939    iax2_prov_cmd, "Provision an IAX device",
10940    show_prov_usage, iax2_prov_complete_template_3rd },
10941 
10942 #ifdef IAXTESTS
10943    { { "iax2", "test", "late", NULL },
10944    iax2_test_late, "Test the receipt of a late frame",
10945    iax2_test_late_usage },
10946 
10947    { { "iax2", "test", "resync", NULL },
10948    iax2_test_resync, "Test a resync in received timestamps",
10949    iax2_test_resync_usage },
10950 
10951    { { "iax2", "test", "jitter", NULL },
10952    iax2_test_jitter, "Simulates jitter for testing",
10953    iax2_test_jitter_usage },
10954 #endif /* IAXTESTS */
10955 };
10956 
10957 static int __unload_module(void)
10958 {
10959    struct iax2_thread *thread = NULL;
10960    int x;
10961 
10962    /* Make sure threads do not hold shared resources when they are canceled */
10963    
10964    /* Grab the sched lock resource to keep it away from threads about to die */
10965    /* Cancel the network thread, close the net socket */
10966    if (netthreadid != AST_PTHREADT_NULL) {
10967       AST_LIST_LOCK(&iaxq.queue);
10968       ast_mutex_lock(&sched_lock);
10969       pthread_cancel(netthreadid);
10970       ast_cond_signal(&sched_cond);
10971       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10972       AST_LIST_UNLOCK(&iaxq.queue);
10973       pthread_join(netthreadid, NULL);
10974    }
10975    if (schedthreadid != AST_PTHREADT_NULL) {
10976       ast_mutex_lock(&sched_lock);  
10977       pthread_cancel(schedthreadid);
10978       ast_cond_signal(&sched_cond);
10979       ast_mutex_unlock(&sched_lock);   
10980       pthread_join(schedthreadid, NULL);
10981    }
10982    
10983    /* Call for all threads to halt */
10984    AST_LIST_LOCK(&idle_list);
10985    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10986       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10987       pthread_cancel(thread->threadid);
10988    }
10989    AST_LIST_TRAVERSE_SAFE_END
10990    AST_LIST_UNLOCK(&idle_list);
10991 
10992    AST_LIST_LOCK(&active_list);
10993    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10994       AST_LIST_REMOVE_CURRENT(&active_list, list);
10995       pthread_cancel(thread->threadid);
10996    }
10997    AST_LIST_TRAVERSE_SAFE_END
10998    AST_LIST_UNLOCK(&active_list);
10999 
11000    AST_LIST_LOCK(&dynamic_list);
11001         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11002       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11003       pthread_cancel(thread->threadid);
11004         }
11005    AST_LIST_TRAVERSE_SAFE_END
11006         AST_LIST_UNLOCK(&dynamic_list);
11007 
11008    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11009 
11010    /* Wait for threads to exit */
11011    while(0 < iaxactivethreadcount)
11012       usleep(10000);
11013    
11014    ast_netsock_release(netsock);
11015    ast_netsock_release(outsock);
11016    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11017       if (iaxs[x]) {
11018          iax2_destroy(x);
11019       }
11020    }
11021    ast_manager_unregister( "IAXpeers" );
11022    ast_manager_unregister( "IAXnetstats" );
11023    ast_unregister_application(papp);
11024    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11025    ast_unregister_switch(&iax2_switch);
11026    ast_channel_unregister(&iax2_tech);
11027    delete_users();
11028    iax_provision_unload();
11029    sched_context_destroy(sched);
11030    reload_firmware(1);
11031 
11032    ast_mutex_destroy(&waresl.lock);
11033 
11034    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11035       ast_mutex_destroy(&iaxsl[x]);
11036    }
11037 
11038    ao2_ref(peers, -1);
11039    ao2_ref(users, -1);
11040    ao2_ref(iax_peercallno_pvts, -1);
11041 
11042    return 0;
11043 }
11044 
11045 static int unload_module(void)
11046 {
11047    ast_custom_function_unregister(&iaxpeer_function);
11048    return __unload_module();
11049 }
11050 
11051 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11052 {
11053    struct iax2_peer *peer = obj;
11054 
11055    if (peer->sockfd < 0)
11056       peer->sockfd = defaultsockfd;
11057 
11058    return 0;
11059 }
11060 
11061 static int pvt_hash_cb(const void *obj, const int flags)
11062 {
11063    const struct chan_iax2_pvt *pvt = obj;
11064 
11065    return pvt->peercallno;
11066 }
11067 
11068 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11069 {
11070    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11071 
11072    /* The frames_received field is used to hold whether we're matching
11073     * against a full frame or not ... */
11074 
11075    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11076       pvt2->frames_received) ? CMP_MATCH : 0;
11077 }
11078 
11079 /*! \brief Load IAX2 module, load configuraiton ---*/
11080 static int load_module(void)
11081 {
11082    char *config = "iax.conf";
11083    int res = 0;
11084    int x;
11085    struct iax2_registry *reg = NULL;
11086 
11087    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11088    if (!peers)
11089       return AST_MODULE_LOAD_FAILURE;
11090    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11091    if (!users) {
11092       ao2_ref(peers, -1);
11093       return AST_MODULE_LOAD_FAILURE;
11094    }
11095    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11096    if (!iax_peercallno_pvts) {
11097       ao2_ref(peers, -1);
11098       ao2_ref(users, -1);
11099       return AST_MODULE_LOAD_FAILURE;
11100    }
11101 
11102    ast_custom_function_register(&iaxpeer_function);
11103 
11104    iax_set_output(iax_debug_output);
11105    iax_set_error(iax_error_output);
11106    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11107    
11108 #ifdef HAVE_ZAPTEL
11109 #ifdef ZT_TIMERACK
11110    timingfd = open("/dev/zap/timer", O_RDWR);
11111    if (timingfd < 0)
11112 #endif
11113       timingfd = open("/dev/zap/pseudo", O_RDWR);
11114    if (timingfd < 0) 
11115       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11116 #endif      
11117 
11118    memset(iaxs, 0, sizeof(iaxs));
11119 
11120    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11121       ast_mutex_init(&iaxsl[x]);
11122    }
11123    
11124    ast_cond_init(&sched_cond, NULL);
11125 
11126    io = io_context_create();
11127    sched = sched_context_create();
11128    
11129    if (!io || !sched) {
11130       ast_log(LOG_ERROR, "Out of memory\n");
11131       return -1;
11132    }
11133 
11134    netsock = ast_netsock_list_alloc();
11135    if (!netsock) {
11136       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11137       return -1;
11138    }
11139    ast_netsock_init(netsock);
11140 
11141    outsock = ast_netsock_list_alloc();
11142    if (!outsock) {
11143       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11144       return -1;
11145    }
11146    ast_netsock_init(outsock);
11147 
11148    ast_mutex_init(&waresl.lock);
11149 
11150    AST_LIST_HEAD_INIT(&iaxq.queue);
11151    
11152    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11153 
11154    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11155    
11156    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11157    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11158 
11159    if(set_config(config, 0) == -1)
11160       return AST_MODULE_LOAD_DECLINE;
11161 
11162    if (ast_channel_register(&iax2_tech)) {
11163       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11164       __unload_module();
11165       return -1;
11166    }
11167 
11168    if (ast_register_switch(&iax2_switch)) 
11169       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11170 
11171    res = start_network_thread();
11172    if (!res) {
11173       if (option_verbose > 1) 
11174          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11175    } else {
11176       ast_log(LOG_ERROR, "Unable to start network thread\n");
11177       ast_netsock_release(netsock);
11178       ast_netsock_release(outsock);
11179    }
11180 
11181    AST_LIST_LOCK(&registrations);
11182    AST_LIST_TRAVERSE(&registrations, reg, entry)
11183       iax2_do_register(reg);
11184    AST_LIST_UNLOCK(&registrations); 
11185 
11186    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11187    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11188 
11189    reload_firmware(0);
11190    iax_provision_reload();
11191    return res;
11192 }
11193 
11194 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11195       .load = load_module,
11196       .unload = unload_module,
11197       .reload = reload,
11198           );

Generated on Tue Sep 30 01:19:33 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.6