Sun Dec 18 20:55:38 2011

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * Hangup cause signalling implementation by
00015  * Levent Guendogdu <levon@feature-it.com>
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Implementation of Inter-Asterisk eXchange Version 2
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  *
00028  * \par See also
00029  * \arg \ref Config_iax
00030  *
00031  * \ingroup channel_drivers
00032  */
00033 
00034 /*** MODULEINFO
00035    <use>zaptel</use>
00036         <depend>res_features</depend>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <sys/types.h>
00046 #include <sys/mman.h>
00047 #include <dirent.h>
00048 #include <sys/socket.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #include <netinet/in_systm.h>
00052 #include <netinet/ip.h>
00053 #include <sys/time.h>
00054 #include <sys/signal.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include <strings.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netdb.h>
00061 #include <fcntl.h>
00062 #include <sys/stat.h>
00063 #include <regex.h>
00064 
00065 #ifdef HAVE_ZAPTEL
00066 #include <sys/ioctl.h>
00067 #include <zaptel/zaptel.h>
00068 #endif
00069 
00070 #include "asterisk/lock.h"
00071 #include "asterisk/frame.h" 
00072 #include "asterisk/channel.h"
00073 #include "asterisk/logger.h"
00074 #include "asterisk/module.h"
00075 #include "asterisk/pbx.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/io.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/options.h"
00080 #include "asterisk/cli.h"
00081 #include "asterisk/translate.h"
00082 #include "asterisk/md5.h"
00083 #include "asterisk/cdr.h"
00084 #include "asterisk/crypto.h"
00085 #include "asterisk/acl.h"
00086 #include "asterisk/manager.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/app.h"
00089 #include "asterisk/astdb.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/utils.h"
00093 #include "asterisk/causes.h"
00094 #include "asterisk/localtime.h"
00095 #include "asterisk/aes.h"
00096 #include "asterisk/dnsmgr.h"
00097 #include "asterisk/devicestate.h"
00098 #include "asterisk/netsock.h"
00099 #include "asterisk/stringfields.h"
00100 #include "asterisk/linkedlists.h"
00101 #include "asterisk/astobj2.h"
00102 
00103 #include "iax2.h"
00104 #include "iax2-parser.h"
00105 #include "iax2-provision.h"
00106 #include "jitterbuf.h"
00107 
00108 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00109    multithreaded mode. */
00110 #define SCHED_MULTITHREADED
00111 
00112 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00113    thread is actually doing. */
00114 #define DEBUG_SCHED_MULTITHREAD
00115 
00116 #ifndef IPTOS_MINCOST
00117 #define IPTOS_MINCOST 0x02
00118 #endif
00119 
00120 #ifdef SO_NO_CHECK
00121 static int nochecksums = 0;
00122 #endif
00123 
00124 
00125 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00126 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00127 
00128 #define DEFAULT_THREAD_COUNT 10
00129 #define DEFAULT_MAX_THREAD_COUNT 100
00130 #define DEFAULT_RETRY_TIME 1000
00131 #define MEMORY_SIZE 100
00132 #define DEFAULT_DROP 3
00133 
00134 #define DEBUG_SUPPORT
00135 
00136 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00137 
00138 /* Sample over last 100 units to determine historic jitter */
00139 #define GAMMA (0.01)
00140 
00141 static struct ast_codec_pref prefs;
00142 
00143 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00144 
00145 static char context[80] = "default";
00146 
00147 static char language[MAX_LANGUAGE] = "";
00148 static char regcontext[AST_MAX_CONTEXT] = "";
00149 
00150 static int maxauthreq = 3;
00151 static int max_retries = 4;
00152 static int ping_time = 21;
00153 static int lagrq_time = 10;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 static int last_authmethod = 0;
00162 
00163 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00164 
00165 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00166 
00167 static unsigned int tos = 0;
00168 
00169 static int min_reg_expire;
00170 static int max_reg_expire;
00171 
00172 static int timingfd = -1;           /* Timing file descriptor */
00173 
00174 static struct ast_netsock_list *netsock;
00175 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00176 static int defaultsockfd = -1;
00177 
00178 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00179 
00180 /* Ethernet, etc */
00181 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00182 /* T1, maybe ISDN */
00183 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00184                 ~AST_FORMAT_SLINEAR &        \
00185                 ~AST_FORMAT_ULAW &        \
00186                 ~AST_FORMAT_ALAW &        \
00187                 ~AST_FORMAT_G722) 
00188 /* A modem */
00189 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00190                 ~AST_FORMAT_G726 &        \
00191                 ~AST_FORMAT_G726_AAL2 &      \
00192                 ~AST_FORMAT_ADPCM)
00193 
00194 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00195                 ~AST_FORMAT_G723_1)
00196 
00197 
00198 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00199 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00200 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00201 
00202 static   struct io_context *io;
00203 static   struct sched_context *sched;
00204 
00205 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00206 
00207 static int iaxdebug = 0;
00208 
00209 static int iaxtrunkdebug = 0;
00210 
00211 static int test_losspct = 0;
00212 #ifdef IAXTESTS
00213 static int test_late = 0;
00214 static int test_resync = 0;
00215 static int test_jit = 0;
00216 static int test_jitpct = 0;
00217 #endif /* IAXTESTS */
00218 
00219 static char accountcode[AST_MAX_ACCOUNT_CODE];
00220 static char mohinterpret[MAX_MUSICCLASS];
00221 static char mohsuggest[MAX_MUSICCLASS];
00222 static int amaflags = 0;
00223 static int adsi = 0;
00224 static int delayreject = 0;
00225 static int iax2_encryption = 0;
00226 
00227 static struct ast_flags globalflags = { 0 };
00228 
00229 static pthread_t netthreadid = AST_PTHREADT_NULL;
00230 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00231 AST_MUTEX_DEFINE_STATIC(sched_lock);
00232 static ast_cond_t sched_cond;
00233 
00234 enum {
00235    IAX_STATE_STARTED =        (1 << 0),
00236    IAX_STATE_AUTHENTICATED =  (1 << 1),
00237    IAX_STATE_TBD =            (1 << 2),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00272                        response, so that we've achieved a three-way handshake with
00273                        them before sending voice or anything else*/
00274    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00275 } iax2_flags;
00276 
00277 static int global_rtautoclear = 120;
00278 
00279 static int reload_config(void);
00280 static int iax2_reload(int fd, int argc, char *argv[]);
00281 
00282 
00283 struct iax2_user {
00284    AST_DECLARE_STRING_FIELDS(
00285       AST_STRING_FIELD(name);
00286       AST_STRING_FIELD(secret);
00287       AST_STRING_FIELD(dbsecret);
00288       AST_STRING_FIELD(accountcode);
00289       AST_STRING_FIELD(mohinterpret);
00290       AST_STRING_FIELD(mohsuggest);
00291       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00292       AST_STRING_FIELD(language);
00293       AST_STRING_FIELD(cid_num);
00294       AST_STRING_FIELD(cid_name);
00295    );
00296    
00297    int authmethods;
00298    int encmethods;
00299    int amaflags;
00300    int adsi;
00301    unsigned int flags;
00302    int capability;
00303    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00304    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00305    struct ast_codec_pref prefs;
00306    struct ast_ha *ha;
00307    struct iax2_context *contexts;
00308    struct ast_variable *vars;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361 };
00362 
00363 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00364 
00365 static struct iax2_trunk_peer {
00366    ast_mutex_t lock;
00367    int sockfd;
00368    struct sockaddr_in addr;
00369    struct timeval txtrunktime;      /*!< Transmit trunktime */
00370    struct timeval rxtrunktime;      /*!< Receive trunktime */
00371    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00372    struct timeval trunkact;      /*!< Last trunk activity */
00373    unsigned int lastsent;        /*!< Last sent time */
00374    /* Trunk data and length */
00375    unsigned char *trunkdata;
00376    unsigned int trunkdatalen;
00377    unsigned int trunkdataalloc;
00378    struct iax2_trunk_peer *next;
00379    int trunkerror;
00380    int calls;
00381 } *tpeers = NULL;
00382 
00383 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00384 
00385 struct iax_firmware {
00386    struct iax_firmware *next;
00387    int fd;
00388    int mmaplen;
00389    int dead;
00390    struct ast_iax2_firmware_header *fwh;
00391    unsigned char *buf;
00392 };
00393 
00394 enum iax_reg_state {
00395    REG_STATE_UNREGISTERED = 0,
00396    REG_STATE_REGSENT,
00397    REG_STATE_AUTHSENT,
00398    REG_STATE_REGISTERED,
00399    REG_STATE_REJECTED,
00400    REG_STATE_TIMEOUT,
00401    REG_STATE_NOAUTH
00402 };
00403 
00404 enum iax_transfer_state {
00405    TRANSFER_NONE = 0,
00406    TRANSFER_BEGIN,
00407    TRANSFER_READY,
00408    TRANSFER_RELEASED,
00409    TRANSFER_PASSTHROUGH,
00410    TRANSFER_MBEGIN,
00411    TRANSFER_MREADY,
00412    TRANSFER_MRELEASED,
00413    TRANSFER_MPASSTHROUGH,
00414    TRANSFER_MEDIA,
00415    TRANSFER_MEDIAPASS
00416 };
00417 
00418 struct iax2_registry {
00419    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00420    char username[80];
00421    char secret[80];        /*!< Password or key name in []'s */
00422    char random[80];
00423    int expire;          /*!< Sched ID of expiration */
00424    int refresh;            /*!< How often to refresh */
00425    enum iax_reg_state regstate;
00426    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00427    int callno;          /*!< Associated call number if applicable */
00428    struct sockaddr_in us;        /*!< Who the server thinks we are */
00429    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00430    AST_LIST_ENTRY(iax2_registry) entry;
00431 };
00432 
00433 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00434 
00435 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00436 #define MIN_RETRY_TIME     100
00437 #define MAX_RETRY_TIME     10000
00438 
00439 #define MAX_JITTER_BUFFER  50
00440 #define MIN_JITTER_BUFFER  10
00441 
00442 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00443 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00444 
00445 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00446 
00447 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00448 #define TS_GAP_FOR_JB_RESYNC  5000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxactivethreadcount = 0;
00454 
00455 struct iax_rr {
00456    int jitter;
00457    int losspct;
00458    int losscnt;
00459    int packets;
00460    int delay;
00461    int dropped;
00462    int ooo;
00463 };
00464 
00465 struct chan_iax2_pvt {
00466    /*! Socket to send/receive on for this call */
00467    int sockfd;
00468    /*! Last received voice format */
00469    int voiceformat;
00470    /*! Last received video format */
00471    int videoformat;
00472    /*! Last sent voice format */
00473    int svoiceformat;
00474    /*! Last sent video format */
00475    int svideoformat;
00476    /*! What we are capable of sending */
00477    int capability;
00478    /*! Last received timestamp */
00479    unsigned int last;
00480    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00481    unsigned int lastsent;
00482    /*! Timestamp of the last video frame sent */
00483    unsigned int lastvsent;
00484    /*! Next outgoing timestamp if everything is good */
00485    unsigned int nextpred;
00486    /*! True if the last voice we transmitted was not silence/CNG */
00487    int notsilenttx;
00488    /*! Ping time */
00489    unsigned int pingtime;
00490    /*! Max time for initial response */
00491    int maxtime;
00492    /*! Peer Address */
00493    struct sockaddr_in addr;
00494    /*! Actual used codec preferences */
00495    struct ast_codec_pref prefs;
00496    /*! Requested codec preferences */
00497    struct ast_codec_pref rprefs;
00498    /*! Our call number */
00499    unsigned short callno;
00500    /*! Peer callno */
00501    unsigned short peercallno;
00502    /*! Negotiated format, this is only used to remember what format was
00503        chosen for an unauthenticated call so that the channel can get
00504        created later using the right format */
00505    int chosenformat;
00506    /*! Peer selected format */
00507    int peerformat;
00508    /*! Peer capability */
00509    int peercapability;
00510    /*! timeval that we base our transmission on */
00511    struct timeval offset;
00512    /*! timeval that we base our delivery on */
00513    struct timeval rxcore;
00514    /*! The jitterbuffer */
00515         jitterbuf *jb;
00516    /*! active jb read scheduler id */
00517         int jbid;
00518    /*! LAG */
00519    int lag;
00520    /*! Error, as discovered by the manager */
00521    int error;
00522    /*! Owner if we have one */
00523    struct ast_channel *owner;
00524    /*! What's our state? */
00525    struct ast_flags state;
00526    /*! Expiry (optional) */
00527    int expiry;
00528    /*! Next outgoing sequence number */
00529    unsigned char oseqno;
00530    /*! Next sequence number they have not yet acknowledged */
00531    unsigned char rseqno;
00532    /*! Next incoming sequence number */
00533    unsigned char iseqno;
00534    /*! Last incoming sequence number we have acknowledged */
00535    unsigned char aseqno;
00536 
00537    AST_DECLARE_STRING_FIELDS(
00538       /*! Peer name */
00539       AST_STRING_FIELD(peer);
00540       /*! Default Context */
00541       AST_STRING_FIELD(context);
00542       /*! Caller ID if available */
00543       AST_STRING_FIELD(cid_num);
00544       AST_STRING_FIELD(cid_name);
00545       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00546       AST_STRING_FIELD(ani);
00547       /*! DNID */
00548       AST_STRING_FIELD(dnid);
00549       /*! RDNIS */
00550       AST_STRING_FIELD(rdnis);
00551       /*! Requested Extension */
00552       AST_STRING_FIELD(exten);
00553       /*! Expected Username */
00554       AST_STRING_FIELD(username);
00555       /*! Expected Secret */
00556       AST_STRING_FIELD(secret);
00557       /*! MD5 challenge */
00558       AST_STRING_FIELD(challenge);
00559       /*! Public keys permitted keys for incoming authentication */
00560       AST_STRING_FIELD(inkeys);
00561       /*! Private key for outgoing authentication */
00562       AST_STRING_FIELD(outkey);
00563       /*! Preferred language */
00564       AST_STRING_FIELD(language);
00565       /*! Hostname/peername for naming purposes */
00566       AST_STRING_FIELD(host);
00567 
00568       AST_STRING_FIELD(dproot);
00569       AST_STRING_FIELD(accountcode);
00570       AST_STRING_FIELD(mohinterpret);
00571       AST_STRING_FIELD(mohsuggest);
00572    );
00573    /*! AUTHREJ all AUTHREP frames */
00574    int authrej;
00575    /*! permitted authentication methods */
00576    int authmethods;
00577    /*! permitted encryption methods */
00578    int encmethods;
00579    /*! Encryption AES-128 Key */
00580    aes_encrypt_ctx ecx;
00581    /*! Decryption AES-128 Key */
00582    aes_decrypt_ctx dcx;
00583    /*! 32 bytes of semi-random data */
00584    unsigned char semirand[32];
00585    /*! Associated registry */
00586    struct iax2_registry *reg;
00587    /*! Associated peer for poking */
00588    struct iax2_peer *peerpoke;
00589    /*! IAX_ flags */
00590    unsigned int flags;
00591    int adsi;
00592 
00593    /*! Transferring status */
00594    enum iax_transfer_state transferring;
00595    /*! Transfer identifier */
00596    int transferid;
00597    /*! Who we are IAX transfering to */
00598    struct sockaddr_in transfer;
00599    /*! What's the new call number for the transfer */
00600    unsigned short transfercallno;
00601    /*! Transfer decrypt AES-128 Key */
00602    aes_encrypt_ctx tdcx;
00603 
00604    /*! Status of knowledge of peer ADSI capability */
00605    int peeradsicpe;
00606 
00607    /*! Who we are bridged to */
00608    unsigned short bridgecallno;
00609    
00610    int pingid;       /*!< Transmit PING request */
00611    int lagid;        /*!< Retransmit lag request */
00612    int autoid;       /*!< Auto hangup for Dialplan requestor */
00613    int authid;       /*!< Authentication rejection ID */
00614    int authfail;        /*!< Reason to report failure */
00615    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00616    int calling_ton;
00617    int calling_tns;
00618    int calling_pres;
00619    int amaflags;
00620    struct iax2_dpcache *dpentries;
00621    struct ast_variable *vars;
00622    /*! last received remote rr */
00623    struct iax_rr remote_rr;
00624    /*! Current base time: (just for stats) */
00625    int min;
00626    /*! Dropped frame count: (just for stats) */
00627    int frames_dropped;
00628    /*! received frame count: (just for stats) */
00629    int frames_received;
00630 };
00631 
00632 static struct ast_iax2_queue {
00633    AST_LIST_HEAD(, iax_frame) queue;
00634    int count;
00635 } iaxq;
00636 
00637 /*!
00638  * This module will get much higher performance when doing a lot of
00639  * user and peer lookups if the number of buckets is increased from 1.
00640  * However, to maintain old behavior for Asterisk 1.4, these are set to
00641  * 1 by default.  When using multiple buckets, search order through these
00642  * containers is considered random, so you will not be able to depend on
00643  * the order the entires are specified in iax.conf for matching order. */
00644 #ifdef LOW_MEMORY
00645 #define MAX_PEER_BUCKETS 1
00646 /* #define MAX_PEER_BUCKETS 17 */
00647 #else
00648 #define MAX_PEER_BUCKETS 1
00649 /* #define MAX_PEER_BUCKETS 563 */
00650 #endif
00651 static struct ao2_container *peers;
00652 
00653 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00654 static struct ao2_container *users;
00655 
00656 static struct ast_firmware_list {
00657    struct iax_firmware *wares;
00658    ast_mutex_t lock;
00659 } waresl;
00660 
00661 /*! Extension exists */
00662 #define CACHE_FLAG_EXISTS     (1 << 0)
00663 /*! Extension is nonexistent */
00664 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00665 /*! Extension can exist */
00666 #define CACHE_FLAG_CANEXIST      (1 << 2)
00667 /*! Waiting to hear back response */
00668 #define CACHE_FLAG_PENDING    (1 << 3)
00669 /*! Timed out */
00670 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00671 /*! Request transmitted */
00672 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00673 /*! Timeout */
00674 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00675 /*! Matchmore */
00676 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00677 
00678 static struct iax2_dpcache {
00679    char peercontext[AST_MAX_CONTEXT];
00680    char exten[AST_MAX_EXTENSION];
00681    struct timeval orig;
00682    struct timeval expiry;
00683    int flags;
00684    unsigned short callno;
00685    int waiters[256];
00686    struct iax2_dpcache *next;
00687    struct iax2_dpcache *peer; /*!< For linking in peers */
00688 } *dpcache;
00689 
00690 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00691 
00692 static void reg_source_db(struct iax2_peer *p);
00693 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00694 
00695 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00696 
00697 #define IAX_IOSTATE_IDLE      0
00698 #define IAX_IOSTATE_READY     1
00699 #define IAX_IOSTATE_PROCESSING   2
00700 #define IAX_IOSTATE_SCHEDREADY   3
00701 
00702 #define IAX_TYPE_POOL    1
00703 #define IAX_TYPE_DYNAMIC 2
00704 
00705 struct iax2_pkt_buf {
00706    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00707    size_t len;
00708    unsigned char buf[1];
00709 };
00710 
00711 struct iax2_thread {
00712    AST_LIST_ENTRY(iax2_thread) list;
00713    int type;
00714    int iostate;
00715 #ifdef SCHED_MULTITHREADED
00716    void (*schedfunc)(const void *);
00717    const void *scheddata;
00718 #endif
00719 #ifdef DEBUG_SCHED_MULTITHREAD
00720    char curfunc[80];
00721 #endif   
00722    int actions;
00723    pthread_t threadid;
00724    int threadnum;
00725    struct sockaddr_in iosin;
00726    unsigned char readbuf[4096]; 
00727    unsigned char *buf;
00728    ssize_t buf_len;
00729    size_t buf_size;
00730    int iofd;
00731    time_t checktime;
00732    ast_mutex_t lock;
00733    ast_cond_t cond;
00734    unsigned int ready_for_signal:1;
00735    /*! if this thread is processing a full frame,
00736      some information about that frame will be stored
00737      here, so we can avoid dispatching any more full
00738      frames for that callno to other threads */
00739    struct {
00740       unsigned short callno;
00741       struct sockaddr_in sin;
00742       unsigned char type;
00743       unsigned char csub;
00744    } ffinfo;
00745    /*! Queued up full frames for processing.  If more full frames arrive for
00746     *  a call which this thread is already processing a full frame for, they
00747     *  are queued up here. */
00748    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00749 };
00750 
00751 /* Thread lists */
00752 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00753 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00754 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00755 
00756 static void *iax2_process_thread(void *data);
00757 
00758 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00759 {
00760    ast_mutex_lock(lock);
00761    ast_cond_signal(cond);
00762    ast_mutex_unlock(lock);
00763 }
00764 
00765 static void iax_debug_output(const char *data)
00766 {
00767    if (iaxdebug)
00768       ast_verbose("%s", data);
00769 }
00770 
00771 static void iax_error_output(const char *data)
00772 {
00773    ast_log(LOG_WARNING, "%s", data);
00774 }
00775 
00776 static void jb_error_output(const char *fmt, ...)
00777 {
00778    va_list args;
00779    char buf[1024];
00780 
00781    va_start(args, fmt);
00782    vsnprintf(buf, 1024, fmt, args);
00783    va_end(args);
00784 
00785    ast_log(LOG_ERROR, buf);
00786 }
00787 
00788 static void jb_warning_output(const char *fmt, ...)
00789 {
00790    va_list args;
00791    char buf[1024];
00792 
00793    va_start(args, fmt);
00794    vsnprintf(buf, 1024, fmt, args);
00795    va_end(args);
00796 
00797    ast_log(LOG_WARNING, buf);
00798 }
00799 
00800 static void jb_debug_output(const char *fmt, ...)
00801 {
00802    va_list args;
00803    char buf[1024];
00804 
00805    va_start(args, fmt);
00806    vsnprintf(buf, 1024, fmt, args);
00807    va_end(args);
00808 
00809    ast_verbose(buf);
00810 }
00811 
00812 /* XXX We probably should use a mutex when working with this XXX */
00813 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00814 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00815 static struct timeval lastused[ARRAY_LEN(iaxs)];
00816 
00817 /*!
00818  * \brief Another container of iax2_pvt structures
00819  *
00820  * Active IAX2 pvt structs are also stored in this container, if they are a part
00821  * of an active call where we know the remote side's call number.  The reason
00822  * for this is that incoming media frames do not contain our call number.  So,
00823  * instead of having to iterate the entire iaxs array, we use this container to
00824  * look up calls where the remote side is using a given call number.
00825  */
00826 static struct ao2_container *iax_peercallno_pvts;
00827 
00828 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00829    but keeps the division between trunked and non-trunked better. */
00830 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00831 
00832 static int maxtrunkcall = TRUNK_CALL_START;
00833 static int maxnontrunkcall = 1;
00834 
00835 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);
00836 static int expire_registry(const void *data);
00837 static int iax2_answer(struct ast_channel *c);
00838 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00839 static int iax2_devicestate(void *data);
00840 static int iax2_digit_begin(struct ast_channel *c, char digit);
00841 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00842 static int iax2_do_register(struct iax2_registry *reg);
00843 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00844 static int iax2_hangup(struct ast_channel *c);
00845 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00846 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00847 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00848 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00849 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00850 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00851 static int iax2_sendtext(struct ast_channel *c, const char *text);
00852 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00853 static int iax2_transfer(struct ast_channel *c, const char *dest);
00854 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00855 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00856 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00857 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00858 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00859 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00860 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00861 static struct ast_frame *iax2_read(struct ast_channel *c);
00862 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00863 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00864 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00865 static void prune_peers(void);
00866 
00867 static const struct ast_channel_tech iax2_tech = {
00868    .type = "IAX2",
00869    .description = tdesc,
00870    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00871    .properties = AST_CHAN_TP_WANTSJITTER,
00872    .requester = iax2_request,
00873    .devicestate = iax2_devicestate,
00874    .send_digit_begin = iax2_digit_begin,
00875    .send_digit_end = iax2_digit_end,
00876    .send_text = iax2_sendtext,
00877    .send_image = iax2_sendimage,
00878    .send_html = iax2_sendhtml,
00879    .call = iax2_call,
00880    .hangup = iax2_hangup,
00881    .answer = iax2_answer,
00882    .read = iax2_read,
00883    .write = iax2_write,
00884    .write_video = iax2_write,
00885    .indicate = iax2_indicate,
00886    .setoption = iax2_setoption,
00887    .bridge = iax2_bridge,
00888    .transfer = iax2_transfer,
00889    .fixup = iax2_fixup,
00890 };
00891 
00892 /* WARNING: insert_idle_thread should only ever be called within the
00893  * context of an iax2_process_thread() thread.
00894  */
00895 static void insert_idle_thread(struct iax2_thread *thread)
00896 {
00897    if (thread->type == IAX_TYPE_DYNAMIC) {
00898       AST_LIST_LOCK(&dynamic_list);
00899       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00900       AST_LIST_UNLOCK(&dynamic_list);
00901    } else {
00902       AST_LIST_LOCK(&idle_list);
00903       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00904       AST_LIST_UNLOCK(&idle_list);
00905    }
00906 
00907    return;
00908 }
00909 
00910 static struct iax2_thread *find_idle_thread(void)
00911 {
00912    pthread_attr_t attr;
00913    struct iax2_thread *thread = NULL;
00914 
00915    /* Pop the head of the list off */
00916    AST_LIST_LOCK(&idle_list);
00917    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00918    AST_LIST_UNLOCK(&idle_list);
00919 
00920    /* If no idle thread is available from the regular list, try dynamic */
00921    if (thread == NULL) {
00922       AST_LIST_LOCK(&dynamic_list);
00923       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00924       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00925       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00926          /* We need to MAKE a thread! */
00927          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00928             thread->threadnum = iaxdynamicthreadcount;
00929             thread->type = IAX_TYPE_DYNAMIC;
00930             ast_mutex_init(&thread->lock);
00931             ast_cond_init(&thread->cond, NULL);
00932             pthread_attr_init(&attr);
00933             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00934             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00935                free(thread);
00936                thread = NULL;
00937             } else {
00938                /* All went well and the thread is up, so increment our count */
00939                iaxdynamicthreadcount++;
00940                
00941                /* Wait for the thread to be ready before returning it to the caller */
00942                while (!thread->ready_for_signal)
00943                   usleep(1);
00944             }
00945          }
00946       }
00947       AST_LIST_UNLOCK(&dynamic_list);
00948    }
00949 
00950    /* this thread is not processing a full frame (since it is idle),
00951       so ensure that the field for the full frame call number is empty */
00952    if (thread)
00953       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00954 
00955    return thread;
00956 }
00957 
00958 #ifdef SCHED_MULTITHREADED
00959 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00960 {
00961    struct iax2_thread *thread = NULL;
00962    static time_t lasterror;
00963    static time_t t;
00964 
00965    thread = find_idle_thread();
00966 
00967    if (thread != NULL) {
00968       thread->schedfunc = func;
00969       thread->scheddata = data;
00970       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00971 #ifdef DEBUG_SCHED_MULTITHREAD
00972       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00973 #endif
00974       signal_condition(&thread->lock, &thread->cond);
00975       return 0;
00976    }
00977    time(&t);
00978    if (t != lasterror && option_debug) 
00979       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00980    lasterror = t;
00981 
00982    return -1;
00983 }
00984 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00985 #endif
00986 
00987 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00988 {
00989    int res;
00990 
00991    res = ast_sched_add(con, when, callback, data);
00992    signal_condition(&sched_lock, &sched_cond);
00993 
00994    return res;
00995 }
00996 
00997 static int send_ping(const void *data);
00998 
00999 static void __send_ping(const void *data)
01000 {
01001    int callno = (long) data;
01002 
01003    ast_mutex_lock(&iaxsl[callno]);
01004 
01005    while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01006       if (iaxs[callno]->peercallno) {
01007          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01008       }
01009       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01010       break;
01011    }
01012 
01013    ast_mutex_unlock(&iaxsl[callno]);
01014 }
01015 
01016 static int send_ping(const void *data)
01017 {
01018 #ifdef SCHED_MULTITHREADED
01019    if (schedule_action(__send_ping, data))
01020 #endif      
01021       __send_ping(data);
01022    return 0;
01023 }
01024 
01025 static int get_encrypt_methods(const char *s)
01026 {
01027    int e;
01028    if (!strcasecmp(s, "aes128"))
01029       e = IAX_ENCRYPT_AES128;
01030    else if (ast_true(s))
01031       e = IAX_ENCRYPT_AES128;
01032    else
01033       e = 0;
01034    return e;
01035 }
01036 
01037 static int send_lagrq(const void *data);
01038 
01039 static void __send_lagrq(const void *data)
01040 {
01041    int callno = (long) data;
01042 
01043    ast_mutex_lock(&iaxsl[callno]);
01044 
01045    while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01046       if (iaxs[callno]->peercallno) {
01047          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01048       }
01049       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01050       break;
01051    }
01052 
01053    ast_mutex_unlock(&iaxsl[callno]);
01054 }
01055 
01056 static int send_lagrq(const void *data)
01057 {
01058 #ifdef SCHED_MULTITHREADED
01059    if (schedule_action(__send_lagrq, data))
01060 #endif      
01061       __send_lagrq(data);
01062    return 0;
01063 }
01064 
01065 static unsigned char compress_subclass(int subclass)
01066 {
01067    int x;
01068    int power=-1;
01069    /* If it's 128 or smaller, just return it */
01070    if (subclass < IAX_FLAG_SC_LOG)
01071       return subclass;
01072    /* Otherwise find its power */
01073    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01074       if (subclass & (1 << x)) {
01075          if (power > -1) {
01076             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01077             return 0;
01078          } else
01079             power = x;
01080       }
01081    }
01082    return power | IAX_FLAG_SC_LOG;
01083 }
01084 
01085 static int uncompress_subclass(unsigned char csub)
01086 {
01087    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01088    if (csub & IAX_FLAG_SC_LOG) {
01089       /* special case for 'compressed' -1 */
01090       if (csub == 0xff)
01091          return -1;
01092       else
01093          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01094    }
01095    else
01096       return csub;
01097 }
01098 
01099 /*!
01100  * \note The only member of the peer passed here guaranteed to be set is the name field
01101  */
01102 static int peer_hash_cb(const void *obj, const int flags)
01103 {
01104    const struct iax2_peer *peer = obj;
01105 
01106    return ast_str_hash(peer->name);
01107 }
01108 
01109 /*!
01110  * \note The only member of the peer passed here guaranteed to be set is the name field
01111  */
01112 static int peer_cmp_cb(void *obj, void *arg, int flags)
01113 {
01114    struct iax2_peer *peer = obj, *peer2 = arg;
01115 
01116    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01117 }
01118 
01119 /*!
01120  * \note The only member of the user passed here guaranteed to be set is the name field
01121  */
01122 static int user_hash_cb(const void *obj, const int flags)
01123 {
01124    const struct iax2_user *user = obj;
01125 
01126    return ast_str_hash(user->name);
01127 }
01128 
01129 /*!
01130  * \note The only member of the user passed here guaranteed to be set is the name field
01131  */
01132 static int user_cmp_cb(void *obj, void *arg, int flags)
01133 {
01134    struct iax2_user *user = obj, *user2 = arg;
01135 
01136    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01137 }
01138 
01139 /*!
01140  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01141  *       so do not call it with a pvt lock held.
01142  */
01143 static struct iax2_peer *find_peer(const char *name, int realtime) 
01144 {
01145    struct iax2_peer *peer = NULL;
01146    struct iax2_peer tmp_peer = {
01147       .name = name,
01148    };
01149 
01150    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01151 
01152    /* Now go for realtime if applicable */
01153    if(!peer && realtime)
01154       peer = realtime_peer(name, NULL);
01155 
01156    return peer;
01157 }
01158 
01159 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01160 {
01161    ao2_ref(peer, +1);
01162    return peer;
01163 }
01164 
01165 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01166 {
01167    ao2_ref(peer, -1);
01168    return NULL;
01169 }
01170 
01171 static inline struct iax2_user *user_ref(struct iax2_user *user)
01172 {
01173    ao2_ref(user, +1);
01174    return user;
01175 }
01176 
01177 static inline struct iax2_user *user_unref(struct iax2_user *user)
01178 {
01179    ao2_ref(user, -1);
01180    return NULL;
01181 }
01182 
01183 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01184 {
01185    struct iax2_peer *peer = NULL;
01186    int res = 0;
01187    struct ao2_iterator i;
01188 
01189    i = ao2_iterator_init(peers, 0);
01190    while ((peer = ao2_iterator_next(&i))) {
01191       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01192           (peer->addr.sin_port == sin.sin_port)) {
01193          ast_copy_string(host, peer->name, len);
01194          peer_unref(peer);
01195          res = 1;
01196          break;
01197       }
01198       peer_unref(peer);
01199    }
01200 
01201    if (!peer) {
01202       peer = realtime_peer(NULL, &sin);
01203       if (peer) {
01204          ast_copy_string(host, peer->name, len);
01205          peer_unref(peer);
01206          res = 1;
01207       }
01208    }
01209 
01210    return res;
01211 }
01212 
01213 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01214 {
01215    /* Decrement AUTHREQ count if needed */
01216    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01217       struct iax2_user *user;
01218       struct iax2_user tmp_user = {
01219          .name = pvt->username,
01220       };
01221 
01222       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01223       if (user) {
01224          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01225          user = user_unref(user);       
01226       }
01227 
01228       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01229    }
01230 
01231    /* No more pings or lagrq's */
01232    AST_SCHED_DEL(sched, pvt->pingid);
01233    AST_SCHED_DEL(sched, pvt->lagid);
01234    AST_SCHED_DEL(sched, pvt->autoid);
01235    AST_SCHED_DEL(sched, pvt->authid);
01236    AST_SCHED_DEL(sched, pvt->initid);
01237    AST_SCHED_DEL(sched, pvt->jbid);
01238 }
01239 
01240 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01241 {
01242    if (!pvt->peercallno) {
01243       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01244       return;
01245    }
01246 
01247    ao2_link(iax_peercallno_pvts, pvt);
01248 }
01249 
01250 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01251 {
01252    if (!pvt->peercallno) {
01253       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01254       return;
01255    }
01256 
01257    ao2_unlink(iax_peercallno_pvts, pvt);
01258 }
01259 
01260 static void update_max_trunk(void)
01261 {
01262    int max = TRUNK_CALL_START;
01263    int x;
01264 
01265    /* XXX Prolly don't need locks here XXX */
01266    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01267       if (iaxs[x]) {
01268          max = x + 1;
01269       }
01270    }
01271 
01272    maxtrunkcall = max;
01273    if (option_debug && iaxdebug)
01274       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01275 }
01276 
01277 static void iax2_frame_free(struct iax_frame *fr)
01278 {
01279    AST_SCHED_DEL(sched, fr->retrans);
01280    iax_frame_free(fr);
01281 }
01282 
01283 static void iax2_destroy(int callno)
01284 {
01285    struct chan_iax2_pvt *pvt;
01286    struct ast_channel *owner;
01287 
01288 retry:
01289    pvt = iaxs[callno];
01290    gettimeofday(&lastused[callno], NULL);
01291    
01292    owner = pvt ? pvt->owner : NULL;
01293 
01294    if (owner) {
01295       if (ast_mutex_trylock(&owner->lock)) {
01296          if (option_debug > 2)
01297             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01298          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01299          goto retry;
01300       }
01301    }
01302    if (!owner) {
01303       iaxs[callno] = NULL;
01304    }
01305 
01306    if (pvt) {
01307       if (!owner) {
01308          pvt->owner = NULL;
01309       } else {
01310          /* If there's an owner, prod it to give up */
01311          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01312           * because we already hold the owner channel lock. */
01313          ast_queue_hangup(owner);
01314       }
01315 
01316       if (pvt->peercallno) {
01317          remove_by_peercallno(pvt);
01318       }
01319 
01320       if (!owner) {
01321          ao2_ref(pvt, -1);
01322          pvt = NULL;
01323       }
01324    }
01325 
01326    if (owner) {
01327       ast_mutex_unlock(&owner->lock);
01328    }
01329 
01330    if (callno & 0x4000) {
01331       update_max_trunk();
01332    }
01333 }
01334 
01335 static void pvt_destructor(void *obj)
01336 {
01337    struct chan_iax2_pvt *pvt = obj;
01338    struct iax_frame *cur = NULL;
01339 
01340    iax2_destroy_helper(pvt);
01341 
01342    /* Already gone */
01343    ast_set_flag(pvt, IAX_ALREADYGONE); 
01344 
01345    AST_LIST_LOCK(&iaxq.queue);
01346    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01347       /* Cancel any pending transmissions */
01348       if (cur->callno == pvt->callno) { 
01349          cur->retries = -1;
01350       }
01351    }
01352    AST_LIST_UNLOCK(&iaxq.queue);
01353 
01354    if (pvt->reg) {
01355       pvt->reg->callno = 0;
01356    }
01357 
01358    if (!pvt->owner) {
01359       jb_frame frame;
01360       if (pvt->vars) {
01361           ast_variables_destroy(pvt->vars);
01362           pvt->vars = NULL;
01363       }
01364 
01365       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01366          iax2_frame_free(frame.data);
01367       }
01368 
01369       jb_destroy(pvt->jb);
01370       ast_string_field_free_memory(pvt);
01371    }
01372 }
01373 
01374 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01375 {
01376    struct chan_iax2_pvt *tmp;
01377    jb_conf jbconf;
01378 
01379    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01380       return NULL;
01381    }
01382 
01383    if (ast_string_field_init(tmp, 32)) {
01384       ao2_ref(tmp, -1);
01385       tmp = NULL;
01386       return NULL;
01387    }
01388       
01389    tmp->prefs = prefs;
01390    tmp->callno = 0;
01391    tmp->peercallno = 0;
01392    tmp->transfercallno = 0;
01393    tmp->bridgecallno = 0;
01394    tmp->pingid = -1;
01395    tmp->lagid = -1;
01396    tmp->autoid = -1;
01397    tmp->authid = -1;
01398    tmp->initid = -1;
01399 
01400    ast_string_field_set(tmp,exten, "s");
01401    ast_string_field_set(tmp,host, host);
01402 
01403    tmp->jb = jb_new();
01404    tmp->jbid = -1;
01405    jbconf.max_jitterbuf = maxjitterbuffer;
01406    jbconf.resync_threshold = resyncthreshold;
01407    jbconf.max_contig_interp = maxjitterinterps;
01408    jb_setconf(tmp->jb,&jbconf);
01409 
01410    return tmp;
01411 }
01412 
01413 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01414 {
01415    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01416    if (new) {
01417       size_t afdatalen = new->afdatalen;
01418       memcpy(new, fr, sizeof(*new));
01419       iax_frame_wrap(new, &fr->af);
01420       new->afdatalen = afdatalen;
01421       new->data = NULL;
01422       new->datalen = 0;
01423       new->direction = DIRECTION_INGRESS;
01424       new->retrans = -1;
01425    }
01426    return new;
01427 }
01428 
01429 #define NEW_PREVENT  0
01430 #define NEW_ALLOW    1
01431 #define NEW_FORCE    2
01432 
01433 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01434 {
01435    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01436       (cur->addr.sin_port == sin->sin_port)) {
01437       /* This is the main host */
01438       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01439           (check_dcallno ? dcallno == cur->callno : 1) ) {
01440          /* That's us.  Be sure we keep track of the peer call number */
01441          return 1;
01442       }
01443    }
01444    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01445        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01446       /* We're transferring */
01447       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01448          return 1;
01449    }
01450    return 0;
01451 }
01452 
01453 static void update_max_nontrunk(void)
01454 {
01455    int max = 1;
01456    int x;
01457    /* XXX Prolly don't need locks here XXX */
01458    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01459       if (iaxs[x])
01460          max = x + 1;
01461    }
01462    maxnontrunkcall = max;
01463    if (option_debug && iaxdebug)
01464       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01465 }
01466 
01467 static int make_trunk(unsigned short callno, int locked)
01468 {
01469    int x;
01470    int res= 0;
01471    struct timeval now;
01472    if (iaxs[callno]->oseqno) {
01473       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01474       return -1;
01475    }
01476    if (callno & TRUNK_CALL_START) {
01477       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01478       return -1;
01479    }
01480    gettimeofday(&now, NULL);
01481    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01482       ast_mutex_lock(&iaxsl[x]);
01483       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01484          iaxs[x] = iaxs[callno];
01485          iaxs[x]->callno = x;
01486          iaxs[callno] = NULL;
01487          /* Update the two timers that should have been started */
01488          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01489          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01490          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01491          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01492          if (locked)
01493             ast_mutex_unlock(&iaxsl[callno]);
01494          res = x;
01495          if (!locked)
01496             ast_mutex_unlock(&iaxsl[x]);
01497          break;
01498       }
01499       ast_mutex_unlock(&iaxsl[x]);
01500    }
01501    if (x >= ARRAY_LEN(iaxs) - 1) {
01502       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01503       return -1;
01504    }
01505    if (option_debug)
01506       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01507    /* We move this call from a non-trunked to a trunked call */
01508    update_max_trunk();
01509    update_max_nontrunk();
01510    return res;
01511 }
01512 
01513 /*!
01514  * \note Calling this function while holding another pvt lock can cause a deadlock.
01515  */
01516 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01517 {
01518    int res = 0;
01519    int x;
01520    struct timeval now;
01521    char host[80];
01522 
01523    if (new <= NEW_ALLOW) {
01524       if (callno) {
01525          struct chan_iax2_pvt *pvt;
01526          struct chan_iax2_pvt tmp_pvt = {
01527             .callno = dcallno,
01528             .peercallno = callno,
01529             /* hack!! */
01530             .frames_received = check_dcallno,
01531          };
01532  
01533          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01534  
01535          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01536             if (return_locked) {
01537                ast_mutex_lock(&iaxsl[pvt->callno]);
01538             }
01539             res = pvt->callno;
01540             ao2_ref(pvt, -1);
01541             pvt = NULL;
01542             return res;
01543          }
01544       }
01545 
01546       /* Look for an existing connection first */
01547       for (x = 1; !res && x < maxnontrunkcall; x++) {
01548          ast_mutex_lock(&iaxsl[x]);
01549          if (iaxs[x]) {
01550             /* Look for an exact match */
01551             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01552                res = x;
01553             }
01554          }
01555          if (!res || !return_locked)
01556             ast_mutex_unlock(&iaxsl[x]);
01557       }
01558       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01559          ast_mutex_lock(&iaxsl[x]);
01560          if (iaxs[x]) {
01561             /* Look for an exact match */
01562             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01563                res = x;
01564             }
01565          }
01566          if (!res || !return_locked)
01567             ast_mutex_unlock(&iaxsl[x]);
01568       }
01569    }
01570    if (!res && (new >= NEW_ALLOW)) {
01571       int start, found = 0;
01572 
01573       /* It may seem odd that we look through the peer list for a name for
01574        * this *incoming* call.  Well, it is weird.  However, users don't
01575        * have an IP address/port number that we can match against.  So,
01576        * this is just checking for a peer that has that IP/port and
01577        * assuming that we have a user of the same name.  This isn't always
01578        * correct, but it will be changed if needed after authentication. */
01579       if (!iax2_getpeername(*sin, host, sizeof(host)))
01580          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01581 
01582       now = ast_tvnow();
01583       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01584       for (x = start; 1; x++) {
01585          if (x == TRUNK_CALL_START) {
01586             x = 1;
01587             continue;
01588          }
01589 
01590          /* Find first unused call number that hasn't been used in a while */
01591          ast_mutex_lock(&iaxsl[x]);
01592          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01593             found = 1;
01594             break;
01595          }
01596          ast_mutex_unlock(&iaxsl[x]);
01597          
01598          if (x == start - 1) {
01599             break;
01600          }
01601       }
01602       /* We've still got lock held if we found a spot */
01603       if (x == start - 1 && !found) {
01604          ast_log(LOG_WARNING, "No more space\n");
01605          return 0;
01606       }
01607       iaxs[x] = new_iax(sin, host);
01608       update_max_nontrunk();
01609       if (iaxs[x]) {
01610          if (option_debug && iaxdebug)
01611             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01612          iaxs[x]->sockfd = sockfd;
01613          iaxs[x]->addr.sin_port = sin->sin_port;
01614          iaxs[x]->addr.sin_family = sin->sin_family;
01615          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01616          iaxs[x]->peercallno = callno;
01617          iaxs[x]->callno = x;
01618          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01619          iaxs[x]->expiry = min_reg_expire;
01620          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01621          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01622          iaxs[x]->amaflags = amaflags;
01623          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01624          
01625          ast_string_field_set(iaxs[x], accountcode, accountcode);
01626          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01627          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01628 
01629          if (iaxs[x]->peercallno) {
01630             store_by_peercallno(iaxs[x]);
01631          }
01632       } else {
01633          ast_log(LOG_WARNING, "Out of resources\n");
01634          ast_mutex_unlock(&iaxsl[x]);
01635          return 0;
01636       }
01637       if (!return_locked)
01638          ast_mutex_unlock(&iaxsl[x]);
01639       res = x;
01640    }
01641    return res;
01642 }
01643 
01644 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01645 
01646    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01647 }
01648 
01649 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01650 
01651    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01652 }
01653 
01654 /*!
01655  * \brief Queue a frame to a call's owning asterisk channel
01656  *
01657  * \pre This function assumes that iaxsl[callno] is locked when called.
01658  *
01659  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01660  * was valid before calling it, it may no longer be valid after calling it.
01661  * This function may unlock and lock the mutex associated with this callno,
01662  * meaning that another thread may grab it and destroy the call.
01663  */
01664 static int iax2_queue_frame(int callno, struct ast_frame *f)
01665 {
01666    for (;;) {
01667       if (iaxs[callno] && iaxs[callno]->owner) {
01668          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01669             /* Avoid deadlock by pausing and trying again */
01670             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01671          } else {
01672             ast_queue_frame(iaxs[callno]->owner, f);
01673             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01674             break;
01675          }
01676       } else
01677          break;
01678    }
01679    return 0;
01680 }
01681 
01682 /*!
01683  * \brief Queue a hangup frame on the ast_channel owner
01684  *
01685  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01686  * is active for the given call number.
01687  *
01688  * \pre Assumes lock for callno is already held.
01689  *
01690  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01691  * was valid before calling it, it may no longer be valid after calling it.
01692  * This function may unlock and lock the mutex associated with this callno,
01693  * meaning that another thread may grab it and destroy the call.
01694  */
01695 static int iax2_queue_hangup(int callno)
01696 {
01697    for (;;) {
01698       if (iaxs[callno] && iaxs[callno]->owner) {
01699          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01700             /* Avoid deadlock by pausing and trying again */
01701             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01702          } else {
01703             ast_queue_hangup(iaxs[callno]->owner);
01704             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01705             break;
01706          }
01707       } else
01708          break;
01709    }
01710    return 0;
01711 }
01712 
01713 /*!
01714  * \brief Queue a control frame on the ast_channel owner
01715  *
01716  * This function queues a control frame on the owner of the IAX2 pvt struct that
01717  * is active for the given call number.
01718  *
01719  * \pre Assumes lock for callno is already held.
01720  *
01721  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01722  * was valid before calling it, it may no longer be valid after calling it.
01723  * This function may unlock and lock the mutex associated with this callno,
01724  * meaning that another thread may grab it and destroy the call.
01725  */
01726 static int iax2_queue_control_data(int callno, 
01727    enum ast_control_frame_type control, const void *data, size_t datalen)
01728 {
01729    for (;;) {
01730       if (iaxs[callno] && iaxs[callno]->owner) {
01731          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01732             /* Avoid deadlock by pausing and trying again */
01733             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01734          } else {
01735             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01736             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01737             break;
01738          }
01739       } else
01740          break;
01741    }
01742    return 0;
01743 }
01744 static void destroy_firmware(struct iax_firmware *cur)
01745 {
01746    /* Close firmware */
01747    if (cur->fwh) {
01748       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01749    }
01750    close(cur->fd);
01751    free(cur);
01752 }
01753 
01754 static int try_firmware(char *s)
01755 {
01756    struct stat stbuf;
01757    struct iax_firmware *cur;
01758    int ifd;
01759    int fd;
01760    int res;
01761    
01762    struct ast_iax2_firmware_header *fwh, fwh2;
01763    struct MD5Context md5;
01764    unsigned char sum[16];
01765    unsigned char buf[1024];
01766    int len, chunk;
01767    char *s2;
01768    char *last;
01769    s2 = alloca(strlen(s) + 100);
01770    if (!s2) {
01771       ast_log(LOG_WARNING, "Alloca failed!\n");
01772       return -1;
01773    }
01774    last = strrchr(s, '/');
01775    if (last)
01776       last++;
01777    else
01778       last = s;
01779    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01780    res = stat(s, &stbuf);
01781    if (res < 0) {
01782       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01783       return -1;
01784    }
01785    /* Make sure it's not a directory */
01786    if (S_ISDIR(stbuf.st_mode))
01787       return -1;
01788    ifd = open(s, O_RDONLY);
01789    if (ifd < 0) {
01790       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01791       return -1;
01792    }
01793    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01794    if (fd < 0) {
01795       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01796       close(ifd);
01797       return -1;
01798    }
01799    /* Unlink our newly created file */
01800    unlink(s2);
01801    
01802    /* Now copy the firmware into it */
01803    len = stbuf.st_size;
01804    while(len) {
01805       chunk = len;
01806       if (chunk > sizeof(buf))
01807          chunk = sizeof(buf);
01808       res = read(ifd, buf, chunk);
01809       if (res != chunk) {
01810          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01811          close(ifd);
01812          close(fd);
01813          return -1;
01814       }
01815       res = write(fd, buf, chunk);
01816       if (res != chunk) {
01817          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01818          close(ifd);
01819          close(fd);
01820          return -1;
01821       }
01822       len -= chunk;
01823    }
01824    close(ifd);
01825    /* Return to the beginning */
01826    lseek(fd, 0, SEEK_SET);
01827    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01828       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01829       close(fd);
01830       return -1;
01831    }
01832    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01833       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01834       close(fd);
01835       return -1;
01836    }
01837    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01838       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01839       close(fd);
01840       return -1;
01841    }
01842    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01843       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01844       close(fd);
01845       return -1;
01846    }
01847    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01848    if (fwh == (void *) -1) {
01849       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01850       close(fd);
01851       return -1;
01852    }
01853    MD5Init(&md5);
01854    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01855    MD5Final(sum, &md5);
01856    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01857       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01858       munmap((void*)fwh, stbuf.st_size);
01859       close(fd);
01860       return -1;
01861    }
01862    cur = waresl.wares;
01863    while(cur) {
01864       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01865          /* Found a candidate */
01866          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01867             /* The version we have on loaded is older, load this one instead */
01868             break;
01869          /* This version is no newer than what we have.  Don't worry about it.
01870             We'll consider it a proper load anyhow though */
01871          munmap((void*)fwh, stbuf.st_size);
01872          close(fd);
01873          return 0;
01874       }
01875       cur = cur->next;
01876    }
01877    if (!cur) {
01878       /* Allocate a new one and link it */
01879       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01880          cur->fd = -1;
01881          cur->next = waresl.wares;
01882          waresl.wares = cur;
01883       }
01884    }
01885    if (cur) {
01886       if (cur->fwh) {
01887          munmap((void*)cur->fwh, cur->mmaplen);
01888       }
01889       if (cur->fd > -1)
01890          close(cur->fd);
01891       cur->fwh = fwh;
01892       cur->fd = fd;
01893       cur->mmaplen = stbuf.st_size;
01894       cur->dead = 0;
01895    }
01896    return 0;
01897 }
01898 
01899 static int iax_check_version(char *dev)
01900 {
01901    int res = 0;
01902    struct iax_firmware *cur;
01903    if (!ast_strlen_zero(dev)) {
01904       ast_mutex_lock(&waresl.lock);
01905       cur = waresl.wares;
01906       while(cur) {
01907          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01908             res = ntohs(cur->fwh->version);
01909             break;
01910          }
01911          cur = cur->next;
01912       }
01913       ast_mutex_unlock(&waresl.lock);
01914    }
01915    return res;
01916 }
01917 
01918 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01919 {
01920    int res = -1;
01921    unsigned int bs = desc & 0xff;
01922    unsigned int start = (desc >> 8) & 0xffffff;
01923    unsigned int bytes;
01924    struct iax_firmware *cur;
01925    if (!ast_strlen_zero((char *)dev) && bs) {
01926       start *= bs;
01927       ast_mutex_lock(&waresl.lock);
01928       cur = waresl.wares;
01929       while(cur) {
01930          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01931             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01932             if (start < ntohl(cur->fwh->datalen)) {
01933                bytes = ntohl(cur->fwh->datalen) - start;
01934                if (bytes > bs)
01935                   bytes = bs;
01936                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01937             } else {
01938                bytes = 0;
01939                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01940             }
01941             if (bytes == bs)
01942                res = 0;
01943             else
01944                res = 1;
01945             break;
01946          }
01947          cur = cur->next;
01948       }
01949       ast_mutex_unlock(&waresl.lock);
01950    }
01951    return res;
01952 }
01953 
01954 
01955 static void reload_firmware(int unload)
01956 {
01957    struct iax_firmware *cur, *curl, *curp;
01958    DIR *fwd;
01959    struct dirent *de;
01960    char dir[256];
01961    char fn[256];
01962    /* Mark all as dead */
01963    ast_mutex_lock(&waresl.lock);
01964    cur = waresl.wares;
01965    while(cur) {
01966       cur->dead = 1;
01967       cur = cur->next;
01968    }
01969 
01970    /* Now that we've freed them, load the new ones */
01971    if (!unload) {
01972       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01973       fwd = opendir(dir);
01974       if (fwd) {
01975          while((de = readdir(fwd))) {
01976             if (de->d_name[0] != '.') {
01977                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01978                if (!try_firmware(fn)) {
01979                   if (option_verbose > 1)
01980                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01981                }
01982             }
01983          }
01984          closedir(fwd);
01985       } else 
01986          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01987    }
01988 
01989    /* Clean up leftovers */
01990    cur = waresl.wares;
01991    curp = NULL;
01992    while(cur) {
01993       curl = cur;
01994       cur = cur->next;
01995       if (curl->dead) {
01996          if (curp) {
01997             curp->next = cur;
01998          } else {
01999             waresl.wares = cur;
02000          }
02001          destroy_firmware(curl);
02002       } else {
02003          curp = cur;
02004       }
02005    }
02006    ast_mutex_unlock(&waresl.lock);
02007 }
02008 
02009 /*!
02010  * \note This function assumes that iaxsl[callno] is locked when called.
02011  *
02012  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02013  * was valid before calling it, it may no longer be valid after calling it.
02014  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02015  * associated with this callno, meaning that another thread may grab it and destroy the call.
02016  */
02017 static int __do_deliver(void *data)
02018 {
02019    /* Just deliver the packet by using queueing.  This is called by
02020      the IAX thread with the iaxsl lock held. */
02021    struct iax_frame *fr = data;
02022    fr->retrans = -1;
02023    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02024    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02025       iax2_queue_frame(fr->callno, &fr->af);
02026    /* Free our iax frame */
02027    iax2_frame_free(fr);
02028    /* And don't run again */
02029    return 0;
02030 }
02031 
02032 static int handle_error(void)
02033 {
02034    /* XXX Ideally we should figure out why an error occured and then abort those
02035       rather than continuing to try.  Unfortunately, the published interface does
02036       not seem to work XXX */
02037 #if 0
02038    struct sockaddr_in *sin;
02039    int res;
02040    struct msghdr m;
02041    struct sock_extended_err e;
02042    m.msg_name = NULL;
02043    m.msg_namelen = 0;
02044    m.msg_iov = NULL;
02045    m.msg_control = &e;
02046    m.msg_controllen = sizeof(e);
02047    m.msg_flags = 0;
02048    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02049    if (res < 0)
02050       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02051    else {
02052       if (m.msg_controllen) {
02053          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02054          if (sin) 
02055             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02056          else
02057             ast_log(LOG_WARNING, "No address detected??\n");
02058       } else {
02059          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02060       }
02061    }
02062 #endif
02063    return 0;
02064 }
02065 
02066 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02067 {
02068    int res;
02069    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02070                sizeof(*sin));
02071    if (res < 0) {
02072       if (option_debug)
02073          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02074       handle_error();
02075    } else
02076       res = 0;
02077    return res;
02078 }
02079 
02080 static int send_packet(struct iax_frame *f)
02081 {
02082    int res;
02083    int callno = f->callno;
02084 
02085    /* Don't send if there was an error, but return error instead */
02086    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02087        return -1;
02088    
02089    /* Called with iaxsl held */
02090    if (option_debug > 2 && iaxdebug)
02091       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));
02092    if (f->transfer) {
02093       if (iaxdebug)
02094          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02095       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02096                sizeof(iaxs[callno]->transfer));
02097    } else {
02098       if (iaxdebug)
02099          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02100       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02101                sizeof(iaxs[callno]->addr));
02102    }
02103    if (res < 0) {
02104       if (option_debug && iaxdebug)
02105          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02106       handle_error();
02107    } else
02108       res = 0;
02109    return res;
02110 }
02111 
02112 /*!
02113  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02114  *       for the given call number may disappear during its execution.
02115  */
02116 static int iax2_predestroy(int callno)
02117 {
02118    struct ast_channel *c;
02119    struct chan_iax2_pvt *pvt = iaxs[callno];
02120 
02121    if (!pvt)
02122       return -1;
02123    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02124       iax2_destroy_helper(pvt);
02125       ast_set_flag(pvt, IAX_ALREADYGONE); 
02126    }
02127    c = pvt->owner;
02128    if (c) {
02129       c->tech_pvt = NULL;
02130       iax2_queue_hangup(callno);
02131       pvt->owner = NULL;
02132       ast_module_unref(ast_module_info->self);
02133    }
02134    return 0;
02135 }
02136 
02137 static int update_packet(struct iax_frame *f)
02138 {
02139    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02140    struct ast_iax2_full_hdr *fh = f->data;
02141    /* Mark this as a retransmission */
02142    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02143    /* Update iseqno */
02144    f->iseqno = iaxs[f->callno]->iseqno;
02145    fh->iseqno = f->iseqno;
02146    return 0;
02147 }
02148 
02149 static int attempt_transmit(const void *data);
02150 static void __attempt_transmit(const void *data)
02151 {
02152    /* Attempt to transmit the frame to the remote peer...
02153       Called without iaxsl held. */
02154    struct iax_frame *f = (struct iax_frame *)data;
02155    int freeme=0;
02156    int callno = f->callno;
02157    /* Make sure this call is still active */
02158    if (callno) 
02159       ast_mutex_lock(&iaxsl[callno]);
02160    if (callno && iaxs[callno]) {
02161       if ((f->retries < 0) /* Already ACK'd */ ||
02162           (f->retries >= max_retries) /* Too many attempts */) {
02163             /* Record an error if we've transmitted too many times */
02164             if (f->retries >= max_retries) {
02165                if (f->transfer) {
02166                   /* Transfer timeout */
02167                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02168                } else if (f->final) {
02169                   if (f->final) 
02170                      iax2_destroy(callno);
02171                } else {
02172                   if (iaxs[callno]->owner)
02173                      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);
02174                   iaxs[callno]->error = ETIMEDOUT;
02175                   if (iaxs[callno]->owner) {
02176                      struct ast_frame fr = { 0, };
02177                      /* Hangup the fd */
02178                      fr.frametype = AST_FRAME_CONTROL;
02179                      fr.subclass = AST_CONTROL_HANGUP;
02180                      iax2_queue_frame(callno, &fr); // XXX
02181                      /* Remember, owner could disappear */
02182                      if (iaxs[callno] && iaxs[callno]->owner)
02183                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02184                   } else {
02185                      if (iaxs[callno]->reg) {
02186                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02187                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02188                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02189                      }
02190                      iax2_destroy(callno);
02191                   }
02192                }
02193 
02194             }
02195             freeme++;
02196       } else {
02197          /* Update it if it needs it */
02198          update_packet(f);
02199          /* Attempt transmission */
02200          send_packet(f);
02201          f->retries++;
02202          /* Try again later after 10 times as long */
02203          f->retrytime *= 10;
02204          if (f->retrytime > MAX_RETRY_TIME)
02205             f->retrytime = MAX_RETRY_TIME;
02206          /* Transfer messages max out at one second */
02207          if (f->transfer && (f->retrytime > 1000))
02208             f->retrytime = 1000;
02209          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02210       }
02211    } else {
02212       /* Make sure it gets freed */
02213       f->retries = -1;
02214       freeme++;
02215    }
02216    if (callno)
02217       ast_mutex_unlock(&iaxsl[callno]);
02218    /* Do not try again */
02219    if (freeme) {
02220       /* Don't attempt delivery, just remove it from the queue */
02221       AST_LIST_LOCK(&iaxq.queue);
02222       AST_LIST_REMOVE(&iaxq.queue, f, list);
02223       iaxq.count--;
02224       AST_LIST_UNLOCK(&iaxq.queue);
02225       f->retrans = -1;
02226       /* Free the IAX frame */
02227       iax2_frame_free(f);
02228    }
02229 }
02230 
02231 static int attempt_transmit(const void *data)
02232 {
02233 #ifdef SCHED_MULTITHREADED
02234    if (schedule_action(__attempt_transmit, data))
02235 #endif      
02236       __attempt_transmit(data);
02237    return 0;
02238 }
02239 
02240 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02241 {
02242    struct iax2_peer *peer;
02243 
02244    if (argc != 4)
02245         return RESULT_SHOWUSAGE;
02246    if (!strcmp(argv[3],"all")) {
02247       reload_config();
02248       ast_cli(fd, "OK cache is flushed.\n");
02249    } else if ((peer = find_peer(argv[3], 0))) {
02250       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02251          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02252          expire_registry(peer_ref(peer));
02253          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02254       } else {
02255          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02256       }
02257       peer_unref(peer);
02258    } else {
02259       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02260    }
02261    
02262    return RESULT_SUCCESS;
02263 }
02264 
02265 static int iax2_test_losspct(int fd, int argc, char *argv[])
02266 {
02267        if (argc != 4)
02268                return RESULT_SHOWUSAGE;
02269 
02270        test_losspct = atoi(argv[3]);
02271 
02272        return RESULT_SUCCESS;
02273 }
02274 
02275 #ifdef IAXTESTS
02276 static int iax2_test_late(int fd, int argc, char *argv[])
02277 {
02278    if (argc != 4)
02279       return RESULT_SHOWUSAGE;
02280 
02281    test_late = atoi(argv[3]);
02282 
02283    return RESULT_SUCCESS;
02284 }
02285 
02286 static int iax2_test_resync(int fd, int argc, char *argv[])
02287 {
02288    if (argc != 4)
02289       return RESULT_SHOWUSAGE;
02290 
02291    test_resync = atoi(argv[3]);
02292 
02293    return RESULT_SUCCESS;
02294 }
02295 
02296 static int iax2_test_jitter(int fd, int argc, char *argv[])
02297 {
02298    if (argc < 4 || argc > 5)
02299       return RESULT_SHOWUSAGE;
02300 
02301    test_jit = atoi(argv[3]);
02302    if (argc == 5) 
02303       test_jitpct = atoi(argv[4]);
02304 
02305    return RESULT_SUCCESS;
02306 }
02307 #endif /* IAXTESTS */
02308 
02309 /*! \brief  peer_status: Report Peer status in character string */
02310 /*    returns 1 if peer is online, -1 if unmonitored */
02311 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02312 {
02313    int res = 0;
02314    if (peer->maxms) {
02315       if (peer->lastms < 0) {
02316          ast_copy_string(status, "UNREACHABLE", statuslen);
02317       } else if (peer->lastms > peer->maxms) {
02318          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02319          res = 1;
02320       } else if (peer->lastms) {
02321          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02322          res = 1;
02323       } else {
02324          ast_copy_string(status, "UNKNOWN", statuslen);
02325       }
02326    } else { 
02327       ast_copy_string(status, "Unmonitored", statuslen);
02328       res = -1;
02329    }
02330    return res;
02331 }
02332 
02333 /*! \brief Show one peer in detail */
02334 static int iax2_show_peer(int fd, int argc, char *argv[])
02335 {
02336    char status[30];
02337    char cbuf[256];
02338    struct iax2_peer *peer;
02339    char codec_buf[512];
02340    int x = 0, codec = 0, load_realtime = 0;
02341 
02342    if (argc < 4)
02343       return RESULT_SHOWUSAGE;
02344 
02345    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02346 
02347    peer = find_peer(argv[3], load_realtime);
02348    if (peer) {
02349       ast_cli(fd,"\n\n");
02350       ast_cli(fd, "  * Name       : %s\n", peer->name);
02351       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02352       ast_cli(fd, "  Context      : %s\n", peer->context);
02353       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02354       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02355       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02356       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02357       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02358       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));
02359       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02360       ast_cli(fd, "  Username     : %s\n", peer->username);
02361       ast_cli(fd, "  Codecs       : ");
02362       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02363       ast_cli(fd, "%s\n", codec_buf);
02364 
02365       ast_cli(fd, "  Codec Order  : (");
02366       for(x = 0; x < 32 ; x++) {
02367          codec = ast_codec_pref_index(&peer->prefs,x);
02368          if(!codec)
02369             break;
02370          ast_cli(fd, "%s", ast_getformatname(codec));
02371          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02372             ast_cli(fd, "|");
02373       }
02374 
02375       if (!x)
02376          ast_cli(fd, "none");
02377       ast_cli(fd, ")\n");
02378 
02379       ast_cli(fd, "  Status       : ");
02380       peer_status(peer, status, sizeof(status));   
02381       ast_cli(fd, "%s\n",status);
02382       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02383       ast_cli(fd,"\n");
02384       peer_unref(peer);
02385    } else {
02386       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02387       ast_cli(fd,"\n");
02388    }
02389 
02390    return RESULT_SUCCESS;
02391 }
02392 
02393 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02394 {
02395    int which = 0;
02396    struct iax2_peer *peer;
02397    char *res = NULL;
02398    int wordlen = strlen(word);
02399    struct ao2_iterator i;
02400 
02401    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02402    if (pos != 3)
02403       return NULL;
02404 
02405    i = ao2_iterator_init(peers, 0);
02406    while ((peer = ao2_iterator_next(&i))) {
02407       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02408          res = ast_strdup(peer->name);
02409          peer_unref(peer);
02410          break;
02411       }
02412       peer_unref(peer);
02413    }
02414 
02415    return res;
02416 }
02417 
02418 static int iax2_show_stats(int fd, int argc, char *argv[])
02419 {
02420    struct iax_frame *cur;
02421    int cnt = 0, dead=0, final=0;
02422 
02423    if (argc != 3)
02424       return RESULT_SHOWUSAGE;
02425 
02426    AST_LIST_LOCK(&iaxq.queue);
02427    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02428       if (cur->retries < 0)
02429          dead++;
02430       if (cur->final)
02431          final++;
02432       cnt++;
02433    }
02434    AST_LIST_UNLOCK(&iaxq.queue);
02435 
02436    ast_cli(fd, "    IAX Statistics\n");
02437    ast_cli(fd, "---------------------\n");
02438    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02439    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02440    
02441    return RESULT_SUCCESS;
02442 }
02443 
02444 static int iax2_show_cache(int fd, int argc, char *argv[])
02445 {
02446    struct iax2_dpcache *dp;
02447    char tmp[1024], *pc;
02448    int s;
02449    int x,y;
02450    struct timeval tv;
02451    gettimeofday(&tv, NULL);
02452    ast_mutex_lock(&dpcache_lock);
02453    dp = dpcache;
02454    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02455    while(dp) {
02456       s = dp->expiry.tv_sec - tv.tv_sec;
02457       tmp[0] = '\0';
02458       if (dp->flags & CACHE_FLAG_EXISTS)
02459          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02460       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02461          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02462       if (dp->flags & CACHE_FLAG_CANEXIST)
02463          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02464       if (dp->flags & CACHE_FLAG_PENDING)
02465          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02466       if (dp->flags & CACHE_FLAG_TIMEOUT)
02467          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02468       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02469          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02470       if (dp->flags & CACHE_FLAG_MATCHMORE)
02471          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02472       if (dp->flags & CACHE_FLAG_UNKNOWN)
02473          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02474       /* Trim trailing pipe */
02475       if (!ast_strlen_zero(tmp))
02476          tmp[strlen(tmp) - 1] = '\0';
02477       else
02478          ast_copy_string(tmp, "(none)", sizeof(tmp));
02479       y=0;
02480       pc = strchr(dp->peercontext, '@');
02481       if (!pc)
02482          pc = dp->peercontext;
02483       else
02484          pc++;
02485       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02486          if (dp->waiters[x] > -1)
02487             y++;
02488       if (s > 0)
02489          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02490       else
02491          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02492       dp = dp->next;
02493    }
02494    ast_mutex_unlock(&dpcache_lock);
02495    return RESULT_SUCCESS;
02496 }
02497 
02498 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02499 
02500 static void unwrap_timestamp(struct iax_frame *fr)
02501 {
02502    int x;
02503 
02504    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02505       x = fr->ts - iaxs[fr->callno]->last;
02506       if (x < -50000) {
02507          /* Sudden big jump backwards in timestamp:
02508             What likely happened here is that miniframe timestamp has circled but we haven't
02509             gotten the update from the main packet.  We'll just pretend that we did, and
02510             update the timestamp appropriately. */
02511          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02512          if (option_debug && iaxdebug)
02513             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02514       }
02515       if (x > 50000) {
02516          /* Sudden apparent big jump forwards in timestamp:
02517             What's likely happened is this is an old miniframe belonging to the previous
02518             top-16-bit timestamp that has turned up out of order.
02519             Adjust the timestamp appropriately. */
02520          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02521          if (option_debug && iaxdebug)
02522             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02523       }
02524    }
02525 }
02526 
02527 static int get_from_jb(const void *p);
02528 
02529 static void update_jbsched(struct chan_iax2_pvt *pvt)
02530 {
02531    int when;
02532    
02533    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02534    
02535    when = jb_next(pvt->jb) - when;
02536 
02537    AST_SCHED_DEL(sched, pvt->jbid);
02538 
02539    if(when <= 0) {
02540       /* XXX should really just empty until when > 0.. */
02541       when = 1;
02542    }
02543    
02544    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02545 }
02546 
02547 static void __get_from_jb(const void *p) 
02548 {
02549    int callno = PTR_TO_CALLNO(p);
02550    struct chan_iax2_pvt *pvt = NULL;
02551    struct iax_frame *fr;
02552    jb_frame frame;
02553    int ret;
02554    long now;
02555    long next;
02556    struct timeval tv;
02557    
02558    /* Make sure we have a valid private structure before going on */
02559    ast_mutex_lock(&iaxsl[callno]);
02560    pvt = iaxs[callno];
02561    if (!pvt) {
02562       /* No go! */
02563       ast_mutex_unlock(&iaxsl[callno]);
02564       return;
02565    }
02566 
02567    pvt->jbid = -1;
02568    
02569    gettimeofday(&tv,NULL);
02570    /* round up a millisecond since ast_sched_runq does; */
02571    /* prevents us from spinning while waiting for our now */
02572    /* to catch up with runq's now */
02573    tv.tv_usec += 1000;
02574    
02575    now = ast_tvdiff_ms(tv, pvt->rxcore);
02576    
02577    if(now >= (next = jb_next(pvt->jb))) {
02578       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02579       switch(ret) {
02580       case JB_OK:
02581          fr = frame.data;
02582          __do_deliver(fr);
02583          /* __do_deliver() can cause the call to disappear */
02584          pvt = iaxs[callno];
02585          break;
02586       case JB_INTERP:
02587       {
02588          struct ast_frame af = { 0, };
02589          
02590          /* create an interpolation frame */
02591          af.frametype = AST_FRAME_VOICE;
02592          af.subclass = pvt->voiceformat;
02593          af.samples  = frame.ms * 8;
02594          af.src  = "IAX2 JB interpolation";
02595          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02596          af.offset = AST_FRIENDLY_OFFSET;
02597          
02598          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02599           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02600          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02601             iax2_queue_frame(callno, &af);
02602             /* iax2_queue_frame() could cause the call to disappear */
02603             pvt = iaxs[callno];
02604          }
02605       }
02606          break;
02607       case JB_DROP:
02608          iax2_frame_free(frame.data);
02609          break;
02610       case JB_NOFRAME:
02611       case JB_EMPTY:
02612          /* do nothing */
02613          break;
02614       default:
02615          /* shouldn't happen */
02616          break;
02617       }
02618    }
02619    if (pvt)
02620       update_jbsched(pvt);
02621    ast_mutex_unlock(&iaxsl[callno]);
02622 }
02623 
02624 static int get_from_jb(const void *data)
02625 {
02626 #ifdef SCHED_MULTITHREADED
02627    if (schedule_action(__get_from_jb, data))
02628 #endif      
02629       __get_from_jb(data);
02630    return 0;
02631 }
02632 
02633 /*!
02634  * \note This function assumes fr->callno is locked
02635  *
02636  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02637  * was valid before calling it, it may no longer be valid after calling it.
02638  */
02639 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02640 {
02641    int type, len;
02642    int ret;
02643    int needfree = 0;
02644    struct ast_channel *owner = NULL;
02645    struct ast_channel *bridge = NULL;
02646    
02647    /* Attempt to recover wrapped timestamps */
02648    unwrap_timestamp(fr);
02649 
02650    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02651    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02652       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02653    else {
02654 #if 0
02655       if (option_debug)
02656          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02657 #endif
02658       fr->af.delivery = ast_tv(0,0);
02659    }
02660 
02661    type = JB_TYPE_CONTROL;
02662    len = 0;
02663 
02664    if(fr->af.frametype == AST_FRAME_VOICE) {
02665       type = JB_TYPE_VOICE;
02666       len = ast_codec_get_samples(&fr->af) / 8;
02667    } else if(fr->af.frametype == AST_FRAME_CNG) {
02668       type = JB_TYPE_SILENCE;
02669    }
02670 
02671    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02672       if (tsout)
02673          *tsout = fr->ts;
02674       __do_deliver(fr);
02675       return -1;
02676    }
02677 
02678    if ((owner = iaxs[fr->callno]->owner))
02679       bridge = ast_bridged_channel(owner);
02680 
02681    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02682     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02683    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02684       jb_frame frame;
02685 
02686       /* deliver any frames in the jb */
02687       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02688          __do_deliver(frame.data);
02689          /* __do_deliver() can make the call disappear */
02690          if (!iaxs[fr->callno])
02691             return -1;
02692       }
02693 
02694       jb_reset(iaxs[fr->callno]->jb);
02695 
02696       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02697 
02698       /* deliver this frame now */
02699       if (tsout)
02700          *tsout = fr->ts;
02701       __do_deliver(fr);
02702       return -1;
02703    }
02704 
02705    /* insert into jitterbuffer */
02706    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02707    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02708          calc_rxstamp(iaxs[fr->callno],fr->ts));
02709    if (ret == JB_DROP) {
02710       needfree++;
02711    } else if (ret == JB_SCHED) {
02712       update_jbsched(iaxs[fr->callno]);
02713    }
02714    if (tsout)
02715       *tsout = fr->ts;
02716    if (needfree) {
02717       /* Free our iax frame */
02718       iax2_frame_free(fr);
02719       return -1;
02720    }
02721    return 0;
02722 }
02723 
02724 static int iax2_transmit(struct iax_frame *fr)
02725 {
02726    /* Lock the queue and place this packet at the end */
02727    /* By setting this to 0, the network thread will send it for us, and
02728       queue retransmission if necessary */
02729    fr->sentyet = 0;
02730    AST_LIST_LOCK(&iaxq.queue);
02731    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02732    iaxq.count++;
02733    AST_LIST_UNLOCK(&iaxq.queue);
02734    /* Wake up the network and scheduler thread */
02735    if (netthreadid != AST_PTHREADT_NULL)
02736       pthread_kill(netthreadid, SIGURG);
02737    signal_condition(&sched_lock, &sched_cond);
02738    return 0;
02739 }
02740 
02741 
02742 
02743 static int iax2_digit_begin(struct ast_channel *c, char digit)
02744 {
02745    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02746 }
02747 
02748 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02749 {
02750    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02751 }
02752 
02753 static int iax2_sendtext(struct ast_channel *c, const char *text)
02754 {
02755    
02756    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02757       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02758 }
02759 
02760 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02761 {
02762    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02763 }
02764 
02765 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02766 {
02767    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02768 }
02769 
02770 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02771 {
02772    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02773    ast_mutex_lock(&iaxsl[callno]);
02774    if (iaxs[callno])
02775       iaxs[callno]->owner = newchan;
02776    else
02777       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02778    ast_mutex_unlock(&iaxsl[callno]);
02779    return 0;
02780 }
02781 
02782 /*!
02783  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02784  *       so do not call this with a pvt lock held.
02785  */
02786 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02787 {
02788    struct ast_variable *var = NULL;
02789    struct ast_variable *tmp;
02790    struct iax2_peer *peer=NULL;
02791    time_t regseconds = 0, nowtime;
02792    int dynamic=0;
02793 
02794    if (peername) {
02795       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02796       if (!var && sin)
02797          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02798    } else if (sin) {
02799       char porta[25];
02800       sprintf(porta, "%d", ntohs(sin->sin_port));
02801       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02802       if (var) {
02803          /* We'll need the peer name in order to build the structure! */
02804          for (tmp = var; tmp; tmp = tmp->next) {
02805             if (!strcasecmp(tmp->name, "name"))
02806                peername = tmp->value;
02807          }
02808       }
02809    }
02810    if (!var && peername) { /* Last ditch effort */
02811       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02812       /*!\note
02813        * If this one loaded something, then we need to ensure that the host
02814        * field matched.  The only reason why we can't have this as a criteria
02815        * is because we only have the IP address and the host field might be
02816        * set as a name (and the reverse PTR might not match).
02817        */
02818       if (var && sin) {
02819          for (tmp = var; tmp; tmp = tmp->next) {
02820             if (!strcasecmp(tmp->name, "host")) {
02821                struct ast_hostent ahp;
02822                struct hostent *hp;
02823                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02824                   /* No match */
02825                   ast_variables_destroy(var);
02826                   var = NULL;
02827                }
02828                break;
02829             }
02830          }
02831       }
02832    }
02833    if (!var)
02834       return NULL;
02835 
02836    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02837    
02838    if (!peer) {
02839       ast_variables_destroy(var);
02840       return NULL;
02841    }
02842 
02843    for (tmp = var; tmp; tmp = tmp->next) {
02844       /* Make sure it's not a user only... */
02845       if (!strcasecmp(tmp->name, "type")) {
02846          if (strcasecmp(tmp->value, "friend") &&
02847              strcasecmp(tmp->value, "peer")) {
02848             /* Whoops, we weren't supposed to exist! */
02849             peer = peer_unref(peer);
02850             break;
02851          } 
02852       } else if (!strcasecmp(tmp->name, "regseconds")) {
02853          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02854       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02855          inet_aton(tmp->value, &(peer->addr.sin_addr));
02856       } else if (!strcasecmp(tmp->name, "port")) {
02857          peer->addr.sin_port = htons(atoi(tmp->value));
02858       } else if (!strcasecmp(tmp->name, "host")) {
02859          if (!strcasecmp(tmp->value, "dynamic"))
02860             dynamic = 1;
02861       }
02862    }
02863 
02864    ast_variables_destroy(var);
02865 
02866    if (!peer)
02867       return NULL;
02868 
02869    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02870       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02871       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02872          if (peer->expire > -1) {
02873             if (!ast_sched_del(sched, peer->expire)) {
02874                peer->expire = -1;
02875                peer_unref(peer);
02876             }
02877          }
02878          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02879          if (peer->expire == -1)
02880             peer_unref(peer);
02881       }
02882       ao2_link(peers, peer);
02883       if (ast_test_flag(peer, IAX_DYNAMIC))
02884          reg_source_db(peer);
02885    } else {
02886       ast_set_flag(peer, IAX_TEMPONLY);   
02887    }
02888 
02889    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02890       time(&nowtime);
02891       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02892          memset(&peer->addr, 0, sizeof(peer->addr));
02893          realtime_update_peer(peer->name, &peer->addr, 0);
02894          if (option_debug)
02895             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02896                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02897       }
02898       else {
02899          if (option_debug)
02900             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02901                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02902       }
02903    }
02904 
02905    return peer;
02906 }
02907 
02908 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02909 {
02910    struct ast_variable *var;
02911    struct ast_variable *tmp;
02912    struct iax2_user *user=NULL;
02913 
02914    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02915    if (!var)
02916       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02917    if (!var && sin) {
02918       char porta[6];
02919       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02920       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02921       if (!var)
02922          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02923    }
02924    if (!var) { /* Last ditch effort */
02925       var = ast_load_realtime("iaxusers", "name", username, NULL);
02926       /*!\note
02927        * If this one loaded something, then we need to ensure that the host
02928        * field matched.  The only reason why we can't have this as a criteria
02929        * is because we only have the IP address and the host field might be
02930        * set as a name (and the reverse PTR might not match).
02931        */
02932       if (var) {
02933          for (tmp = var; tmp; tmp = tmp->next) {
02934             if (!strcasecmp(tmp->name, "host")) {
02935                struct ast_hostent ahp;
02936                struct hostent *hp;
02937                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02938                   /* No match */
02939                   ast_variables_destroy(var);
02940                   var = NULL;
02941                }
02942                break;
02943             }
02944          }
02945       }
02946    }
02947    if (!var)
02948       return NULL;
02949 
02950    tmp = var;
02951    while(tmp) {
02952       /* Make sure it's not a peer only... */
02953       if (!strcasecmp(tmp->name, "type")) {
02954          if (strcasecmp(tmp->value, "friend") &&
02955              strcasecmp(tmp->value, "user")) {
02956             return NULL;
02957          } 
02958       }
02959       tmp = tmp->next;
02960    }
02961 
02962    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02963 
02964    ast_variables_destroy(var);
02965 
02966    if (!user)
02967       return NULL;
02968 
02969    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02970       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02971       ao2_link(users, user);
02972    } else {
02973       ast_set_flag(user, IAX_TEMPONLY);   
02974    }
02975 
02976    return user;
02977 }
02978 
02979 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02980 {
02981    char port[10];
02982    char regseconds[20];
02983    
02984    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02985    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02986    ast_update_realtime("iaxpeers", "name", peername, 
02987       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02988       "regseconds", regseconds, NULL);
02989 }
02990 
02991 struct create_addr_info {
02992    int capability;
02993    unsigned int flags;
02994    int maxtime;
02995    int encmethods;
02996    int found;
02997    int sockfd;
02998    int adsi;
02999    char username[80];
03000    char secret[80];
03001    char outkey[80];
03002    char timezone[80];
03003    char prefs[32];
03004    char context[AST_MAX_CONTEXT];
03005    char peercontext[AST_MAX_CONTEXT];
03006    char mohinterpret[MAX_MUSICCLASS];
03007    char mohsuggest[MAX_MUSICCLASS];
03008 };
03009 
03010 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03011 {
03012    struct ast_hostent ahp;
03013    struct hostent *hp;
03014    struct iax2_peer *peer;
03015    int res = -1;
03016    struct ast_codec_pref ourprefs;
03017 
03018    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03019    cai->sockfd = defaultsockfd;
03020    cai->maxtime = 0;
03021    sin->sin_family = AF_INET;
03022 
03023    if (!(peer = find_peer(peername, 1))) {
03024       cai->found = 0;
03025 
03026       hp = ast_gethostbyname(peername, &ahp);
03027       if (hp) {
03028          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03029          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03030          /* use global iax prefs for unknown peer/user */
03031          /* But move the calling channel's native codec to the top of the preference list */
03032          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03033          if (c)
03034             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03035          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03036          return 0;
03037       } else {
03038          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03039          return -1;
03040       }
03041    }
03042 
03043    cai->found = 1;
03044    
03045    /* if the peer has no address (current or default), return failure */
03046    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03047       goto return_unref;
03048 
03049    /* if the peer is being monitored and is currently unreachable, return failure */
03050    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03051       goto return_unref;
03052 
03053    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03054    cai->maxtime = peer->maxms;
03055    cai->capability = peer->capability;
03056    cai->encmethods = peer->encmethods;
03057    cai->sockfd = peer->sockfd;
03058    cai->adsi = peer->adsi;
03059    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03060    /* Move the calling channel's native codec to the top of the preference list */
03061    if (c) {
03062       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03063       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03064    }
03065    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03066    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03067    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03068    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03069    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03070    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03071    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03072    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03073    if (ast_strlen_zero(peer->dbsecret)) {
03074       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03075    } else {
03076       char *family;
03077       char *key = NULL;
03078 
03079       family = ast_strdupa(peer->dbsecret);
03080       key = strchr(family, '/');
03081       if (key)
03082          *key++ = '\0';
03083       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03084          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03085          goto return_unref;
03086       }
03087    }
03088 
03089    if (peer->addr.sin_addr.s_addr) {
03090       sin->sin_addr = peer->addr.sin_addr;
03091       sin->sin_port = peer->addr.sin_port;
03092    } else {
03093       sin->sin_addr = peer->defaddr.sin_addr;
03094       sin->sin_port = peer->defaddr.sin_port;
03095    }
03096 
03097    res = 0;
03098 
03099 return_unref:
03100    peer_unref(peer);
03101 
03102    return res;
03103 }
03104 
03105 static void __auto_congest(const void *nothing)
03106 {
03107    int callno = PTR_TO_CALLNO(nothing);
03108    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03109    ast_mutex_lock(&iaxsl[callno]);
03110    if (iaxs[callno]) {
03111       iaxs[callno]->initid = -1;
03112       iax2_queue_frame(callno, &f);
03113       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03114    }
03115    ast_mutex_unlock(&iaxsl[callno]);
03116 }
03117 
03118 static int auto_congest(const void *data)
03119 {
03120 #ifdef SCHED_MULTITHREADED
03121    if (schedule_action(__auto_congest, data))
03122 #endif      
03123       __auto_congest(data);
03124    return 0;
03125 }
03126 
03127 static unsigned int iax2_datetime(const char *tz)
03128 {
03129    time_t t;
03130    struct tm tm;
03131    unsigned int tmp;
03132    time(&t);
03133    if (!ast_strlen_zero(tz))
03134       ast_localtime(&t, &tm, tz);
03135    else
03136       ast_localtime(&t, &tm, NULL);
03137    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03138    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03139    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03140    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03141    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03142    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03143    return tmp;
03144 }
03145 
03146 struct parsed_dial_string {
03147    char *username;
03148    char *password;
03149    char *key;
03150    char *peer;
03151    char *port;
03152    char *exten;
03153    char *context;
03154    char *options;
03155 };
03156 
03157 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03158 {
03159    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03160       .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03161       .csub = compress_subclass(command) };
03162 
03163    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03164 }
03165 
03166 /*!
03167  * \brief Parses an IAX dial string into its component parts.
03168  * \param data the string to be parsed
03169  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03170  * \return nothing
03171  *
03172  * This function parses the string and fills the structure
03173  * with pointers to its component parts. The input string
03174  * will be modified.
03175  *
03176  * \note This function supports both plaintext passwords and RSA
03177  * key names; if the password string is formatted as '[keyname]',
03178  * then the keyname will be placed into the key field, and the
03179  * password field will be set to NULL.
03180  *
03181  * \note The dial string format is:
03182  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03183  */
03184 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03185 {
03186    if (ast_strlen_zero(data))
03187       return;
03188 
03189    pds->peer = strsep(&data, "/");
03190    pds->exten = strsep(&data, "/");
03191    pds->options = data;
03192 
03193    if (pds->exten) {
03194       data = pds->exten;
03195       pds->exten = strsep(&data, "@");
03196       pds->context = data;
03197    }
03198 
03199    if (strchr(pds->peer, '@')) {
03200       data = pds->peer;
03201       pds->username = strsep(&data, "@");
03202       pds->peer = data;
03203    }
03204 
03205    if (pds->username) {
03206       data = pds->username;
03207       pds->username = strsep(&data, ":");
03208       pds->password = data;
03209    }
03210 
03211    data = pds->peer;
03212    pds->peer = strsep(&data, ":");
03213    pds->port = data;
03214 
03215    /* check for a key name wrapped in [] in the secret position, if found,
03216       move it to the key field instead
03217    */
03218    if (pds->password && (pds->password[0] == '[')) {
03219       pds->key = ast_strip_quoted(pds->password, "[", "]");
03220       pds->password = NULL;
03221    }
03222 }
03223 
03224 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03225 {
03226    struct sockaddr_in sin;
03227    char *l=NULL, *n=NULL, *tmpstr;
03228    struct iax_ie_data ied;
03229    char *defaultrdest = "s";
03230    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03231    struct parsed_dial_string pds;
03232    struct create_addr_info cai;
03233 
03234    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03235       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03236       return -1;
03237    }
03238 
03239    memset(&cai, 0, sizeof(cai));
03240    cai.encmethods = iax2_encryption;
03241 
03242    memset(&pds, 0, sizeof(pds));
03243    tmpstr = ast_strdupa(dest);
03244    parse_dial_string(tmpstr, &pds);
03245 
03246    if (ast_strlen_zero(pds.peer)) {
03247       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03248       return -1;
03249    }
03250 
03251    if (!pds.exten) {
03252       pds.exten = defaultrdest;
03253    }
03254 
03255    if (create_addr(pds.peer, c, &sin, &cai)) {
03256       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03257       return -1;
03258    }
03259 
03260    if (!pds.username && !ast_strlen_zero(cai.username))
03261       pds.username = cai.username;
03262    if (!pds.password && !ast_strlen_zero(cai.secret))
03263       pds.password = cai.secret;
03264    if (!pds.key && !ast_strlen_zero(cai.outkey))
03265       pds.key = cai.outkey;
03266    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03267       pds.context = cai.peercontext;
03268 
03269    /* Keep track of the context for outgoing calls too */
03270    ast_copy_string(c->context, cai.context, sizeof(c->context));
03271 
03272    if (pds.port)
03273       sin.sin_port = htons(atoi(pds.port));
03274 
03275    l = c->cid.cid_num;
03276    n = c->cid.cid_name;
03277 
03278    /* Now build request */ 
03279    memset(&ied, 0, sizeof(ied));
03280 
03281    /* On new call, first IE MUST be IAX version of caller */
03282    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03283    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03284    if (pds.options && strchr(pds.options, 'a')) {
03285       /* Request auto answer */
03286       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03287    }
03288 
03289    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03290 
03291    if (l) {
03292       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03293       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03294    } else {
03295       if (n)
03296          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03297       else
03298          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03299    }
03300 
03301    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03302    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03303 
03304    if (n)
03305       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03306    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03307       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03308 
03309    if (!ast_strlen_zero(c->language))
03310       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03311    if (!ast_strlen_zero(c->cid.cid_dnid))
03312       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03313    if (!ast_strlen_zero(c->cid.cid_rdnis))
03314       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03315 
03316    if (pds.context)
03317       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03318 
03319    if (pds.username)
03320       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03321 
03322    if (cai.encmethods)
03323       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03324 
03325    ast_mutex_lock(&iaxsl[callno]);
03326 
03327    if (!ast_strlen_zero(c->context))
03328       ast_string_field_set(iaxs[callno], context, c->context);
03329 
03330    if (pds.username)
03331       ast_string_field_set(iaxs[callno], username, pds.username);
03332 
03333    iaxs[callno]->encmethods = cai.encmethods;
03334 
03335    iaxs[callno]->adsi = cai.adsi;
03336    
03337    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03338    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03339 
03340    if (pds.key)
03341       ast_string_field_set(iaxs[callno], outkey, pds.key);
03342    if (pds.password)
03343       ast_string_field_set(iaxs[callno], secret, pds.password);
03344 
03345    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03346    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03347    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03348    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03349 
03350    if (iaxs[callno]->maxtime) {
03351       /* Initialize pingtime and auto-congest time */
03352       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03353       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03354    } else if (autokill) {
03355       iaxs[callno]->pingtime = autokill / 2;
03356       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03357    }
03358 
03359    /* send the command using the appropriate socket for this peer */
03360    iaxs[callno]->sockfd = cai.sockfd;
03361 
03362    /* Transmit the string in a "NEW" request */
03363    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03364 
03365    ast_mutex_unlock(&iaxsl[callno]);
03366    ast_setstate(c, AST_STATE_RINGING);
03367    
03368    return 0;
03369 }
03370 
03371 static int iax2_hangup(struct ast_channel *c) 
03372 {
03373    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03374    int alreadygone;
03375    struct iax_ie_data ied;
03376    memset(&ied, 0, sizeof(ied));
03377    ast_mutex_lock(&iaxsl[callno]);
03378    if (callno && iaxs[callno]) {
03379       if (option_debug)
03380          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03381       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03382       /* Send the hangup unless we have had a transmission error or are already gone */
03383       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03384       if (!iaxs[callno]->error && !alreadygone) {
03385          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03386          if (!iaxs[callno]) {
03387             ast_mutex_unlock(&iaxsl[callno]);
03388             return 0;
03389          }
03390       }
03391       /* Explicitly predestroy it */
03392       iax2_predestroy(callno);
03393       /* If we were already gone to begin with, destroy us now */
03394       if (alreadygone && iaxs[callno]) {
03395          if (option_debug)
03396             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03397          iax2_destroy(callno);
03398       }
03399    }
03400    ast_mutex_unlock(&iaxsl[callno]);
03401    if (option_verbose > 2) 
03402       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03403    return 0;
03404 }
03405 
03406 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03407 {
03408    struct ast_option_header *h;
03409    int res;
03410 
03411    switch (option) {
03412    case AST_OPTION_TXGAIN:
03413    case AST_OPTION_RXGAIN:
03414       /* these two cannot be sent, because they require a result */
03415       errno = ENOSYS;
03416       return -1;
03417    /* These options are sent to the other side across the network where
03418     * they will be passed to whatever channel is bridged there. Don't
03419     * do anything silly like pass an option that transmits pointers to
03420     * memory on this machine to a remote machine to use */
03421    case AST_OPTION_TONE_VERIFY:
03422    case AST_OPTION_TDD:
03423    case AST_OPTION_RELAXDTMF:
03424    case AST_OPTION_AUDIO_MODE:
03425       if (!(h = ast_malloc(datalen + sizeof(*h))))
03426          return -1;
03427 
03428       h->flag = AST_OPTION_FLAG_REQUEST;
03429       h->option = htons(option);
03430       memcpy(h->data, data, datalen);
03431       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03432                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03433                  datalen + sizeof(*h), -1);
03434       free(h);
03435       return res;
03436    default:
03437       return -1;
03438    }
03439 
03440    /* Just in case someone does a break instead of a return */
03441    return -1;
03442 }
03443 
03444 static struct ast_frame *iax2_read(struct ast_channel *c) 
03445 {
03446    if (option_verbose > 3)
03447        ast_log(LOG_NOTICE, "I should never be called!\n");
03448    return &ast_null_frame;
03449 }
03450 
03451 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03452 {
03453    int res;
03454    struct iax_ie_data ied0;
03455    struct iax_ie_data ied1;
03456    unsigned int transferid = (unsigned int)ast_random();
03457    memset(&ied0, 0, sizeof(ied0));
03458    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03459    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03460    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03461 
03462    memset(&ied1, 0, sizeof(ied1));
03463    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03464    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03465    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03466    
03467    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03468    if (res)
03469       return -1;
03470    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03471    if (res)
03472       return -1;
03473    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03474    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03475    return 0;
03476 }
03477 
03478 static void lock_both(unsigned short callno0, unsigned short callno1)
03479 {
03480    ast_mutex_lock(&iaxsl[callno0]);
03481    while (ast_mutex_trylock(&iaxsl[callno1])) {
03482       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03483    }
03484 }
03485 
03486 static void unlock_both(unsigned short callno0, unsigned short callno1)
03487 {
03488    ast_mutex_unlock(&iaxsl[callno1]);
03489    ast_mutex_unlock(&iaxsl[callno0]);
03490 }
03491 
03492 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)
03493 {
03494    struct ast_channel *cs[3];
03495    struct ast_channel *who, *other;
03496    int to = -1;
03497    int res = -1;
03498    int transferstarted=0;
03499    struct ast_frame *f;
03500    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03501    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03502    struct timeval waittimer = {0, 0}, tv;
03503 
03504    lock_both(callno0, callno1);
03505    if (!iaxs[callno0] || !iaxs[callno1]) {
03506       unlock_both(callno0, callno1);
03507       return AST_BRIDGE_FAILED;
03508    }
03509    /* Put them in native bridge mode */
03510    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03511       iaxs[callno0]->bridgecallno = callno1;
03512       iaxs[callno1]->bridgecallno = callno0;
03513    }
03514    unlock_both(callno0, callno1);
03515 
03516    /* If not, try to bridge until we can execute a transfer, if we can */
03517    cs[0] = c0;
03518    cs[1] = c1;
03519    for (/* ever */;;) {
03520       /* Check in case we got masqueraded into */
03521       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03522          if (option_verbose > 2)
03523             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03524          /* Remove from native mode */
03525          if (c0->tech == &iax2_tech) {
03526             ast_mutex_lock(&iaxsl[callno0]);
03527             iaxs[callno0]->bridgecallno = 0;
03528             ast_mutex_unlock(&iaxsl[callno0]);
03529          }
03530          if (c1->tech == &iax2_tech) {
03531             ast_mutex_lock(&iaxsl[callno1]);
03532             iaxs[callno1]->bridgecallno = 0;
03533             ast_mutex_unlock(&iaxsl[callno1]);
03534          }
03535          return AST_BRIDGE_FAILED_NOWARN;
03536       }
03537       if (c0->nativeformats != c1->nativeformats) {
03538          if (option_verbose > 2) {
03539             char buf0[255];
03540             char buf1[255];
03541             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03542             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03543             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03544          }
03545          /* Remove from native mode */
03546          lock_both(callno0, callno1);
03547          if (iaxs[callno0])
03548             iaxs[callno0]->bridgecallno = 0;
03549          if (iaxs[callno1])
03550             iaxs[callno1]->bridgecallno = 0;
03551          unlock_both(callno0, callno1);
03552          return AST_BRIDGE_FAILED_NOWARN;
03553       }
03554       /* check if transfered and if we really want native bridging */
03555       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03556          /* Try the transfer */
03557          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03558                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03559             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03560          transferstarted = 1;
03561       }
03562       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03563          /* Call has been transferred.  We're no longer involved */
03564          gettimeofday(&tv, NULL);
03565          if (ast_tvzero(waittimer)) {
03566             waittimer = tv;
03567          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03568             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03569             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03570             *fo = NULL;
03571             *rc = c0;
03572             res = AST_BRIDGE_COMPLETE;
03573             break;
03574          }
03575       }
03576       to = 1000;
03577       who = ast_waitfor_n(cs, 2, &to);
03578       if (timeoutms > -1) {
03579          timeoutms -= (1000 - to);
03580          if (timeoutms < 0)
03581             timeoutms = 0;
03582       }
03583       if (!who) {
03584          if (!timeoutms) {
03585             res = AST_BRIDGE_RETRY;
03586             break;
03587          }
03588          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03589             res = AST_BRIDGE_FAILED;
03590             break;
03591          }
03592          continue;
03593       }
03594       f = ast_read(who);
03595       if (!f) {
03596          *fo = NULL;
03597          *rc = who;
03598          res = AST_BRIDGE_COMPLETE;
03599          break;
03600       }
03601       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03602          *fo = f;
03603          *rc = who;
03604          res =  AST_BRIDGE_COMPLETE;
03605          break;
03606       }
03607       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03608       if ((f->frametype == AST_FRAME_VOICE) ||
03609           (f->frametype == AST_FRAME_TEXT) ||
03610           (f->frametype == AST_FRAME_VIDEO) || 
03611           (f->frametype == AST_FRAME_IMAGE) ||
03612           (f->frametype == AST_FRAME_DTMF)) {
03613          /* monitored dtmf take out of the bridge.
03614           * check if we monitor the specific source.
03615           */
03616          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03617          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03618             *rc = who;
03619             *fo = f;
03620             res = AST_BRIDGE_COMPLETE;
03621             /* Remove from native mode */
03622             break;
03623          }
03624          /* everything else goes to the other side */
03625          ast_write(other, f);
03626       }
03627       ast_frfree(f);
03628       /* Swap who gets priority */
03629       cs[2] = cs[0];
03630       cs[0] = cs[1];
03631       cs[1] = cs[2];
03632    }
03633    lock_both(callno0, callno1);
03634    if(iaxs[callno0])
03635       iaxs[callno0]->bridgecallno = 0;
03636    if(iaxs[callno1])
03637       iaxs[callno1]->bridgecallno = 0;
03638    unlock_both(callno0, callno1);
03639    return res;
03640 }
03641 
03642 static int iax2_answer(struct ast_channel *c)
03643 {
03644    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03645    if (option_debug)
03646       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03647    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03648 }
03649 
03650 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03651 {
03652    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03653    struct chan_iax2_pvt *pvt;
03654    int res = 0;
03655 
03656    if (option_debug && iaxdebug)
03657       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03658 
03659    ast_mutex_lock(&iaxsl[callno]);
03660    pvt = iaxs[callno];
03661 
03662    if (!pvt->peercallno) {
03663       /* We don't know the remote side's call number, yet.  :( */
03664       int count = 10;
03665       while (count-- && pvt && !pvt->peercallno) {
03666          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03667          pvt = iaxs[callno];
03668       }
03669       if (!pvt->peercallno) {
03670          res = -1;
03671          goto done;
03672       }
03673    }
03674 
03675    switch (condition) {
03676    case AST_CONTROL_HOLD:
03677       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03678          ast_moh_start(c, data, pvt->mohinterpret);
03679          goto done;
03680       }
03681       break;
03682    case AST_CONTROL_UNHOLD:
03683       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03684          ast_moh_stop(c);
03685          goto done;
03686       }
03687    }
03688 
03689    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03690 
03691 done:
03692    ast_mutex_unlock(&iaxsl[callno]);
03693 
03694    return res;
03695 }
03696    
03697 static int iax2_transfer(struct ast_channel *c, const char *dest)
03698 {
03699    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03700    struct iax_ie_data ied;
03701    char tmp[256], *context;
03702    ast_copy_string(tmp, dest, sizeof(tmp));
03703    context = strchr(tmp, '@');
03704    if (context) {
03705       *context = '\0';
03706       context++;
03707    }
03708    memset(&ied, 0, sizeof(ied));
03709    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03710    if (context)
03711       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03712    if (option_debug)
03713       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03714    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03715 }
03716    
03717 static int iax2_getpeertrunk(struct sockaddr_in sin)
03718 {
03719    struct iax2_peer *peer;
03720    int res = 0;
03721    struct ao2_iterator i;
03722 
03723    i = ao2_iterator_init(peers, 0);
03724    while ((peer = ao2_iterator_next(&i))) {
03725       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03726           (peer->addr.sin_port == sin.sin_port)) {
03727          res = ast_test_flag(peer, IAX_TRUNK);
03728          peer_unref(peer);
03729          break;
03730       }
03731       peer_unref(peer);
03732    }
03733 
03734    return res;
03735 }
03736 
03737 /*! \brief  Create new call, interface with the PBX core */
03738 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03739 {
03740    struct ast_channel *tmp;
03741    struct chan_iax2_pvt *i;
03742    struct ast_variable *v = NULL;
03743 
03744    if (!(i = iaxs[callno])) {
03745       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03746       return NULL;
03747    }
03748 
03749    /* Don't hold call lock */
03750    ast_mutex_unlock(&iaxsl[callno]);
03751    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);
03752    ast_mutex_lock(&iaxsl[callno]);
03753    if (!iaxs[callno]) {
03754       if (tmp) {
03755          ast_channel_free(tmp);
03756       }
03757       ast_mutex_unlock(&iaxsl[callno]);
03758       return NULL;
03759    }
03760 
03761    if (!tmp)
03762       return NULL;
03763    tmp->tech = &iax2_tech;
03764    /* We can support any format by default, until we get restricted */
03765    tmp->nativeformats = capability;
03766    tmp->readformat = ast_best_codec(capability);
03767    tmp->writeformat = ast_best_codec(capability);
03768    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03769 
03770    /* Don't use ast_set_callerid() here because it will
03771     * generate a NewCallerID event before the NewChannel event */
03772    if (!ast_strlen_zero(i->ani))
03773       tmp->cid.cid_ani = ast_strdup(i->ani);
03774    else
03775       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03776    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03777    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03778    tmp->cid.cid_pres = i->calling_pres;
03779    tmp->cid.cid_ton = i->calling_ton;
03780    tmp->cid.cid_tns = i->calling_tns;
03781    if (!ast_strlen_zero(i->language))
03782       ast_string_field_set(tmp, language, i->language);
03783    if (!ast_strlen_zero(i->accountcode))
03784       ast_string_field_set(tmp, accountcode, i->accountcode);
03785    if (i->amaflags)
03786       tmp->amaflags = i->amaflags;
03787    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03788    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03789    if (i->adsi)
03790       tmp->adsicpe = i->peeradsicpe;
03791    else
03792       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03793    i->owner = tmp;
03794    i->capability = capability;
03795 
03796    for (v = i->vars ; v ; v = v->next)
03797       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03798 
03799    if (state != AST_STATE_DOWN) {
03800       if (ast_pbx_start(tmp)) {
03801          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03802          ast_hangup(tmp);
03803          i->owner = NULL;
03804          return NULL;
03805       }
03806    }
03807 
03808    ast_module_ref(ast_module_info->self);
03809    
03810    return tmp;
03811 }
03812 
03813 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03814 {
03815    unsigned long int mssincetx; /* unsigned to handle overflows */
03816    long int ms, pred;
03817 
03818    tpeer->trunkact = *tv;
03819    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03820    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03821       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03822       tpeer->txtrunktime = *tv;
03823       tpeer->lastsent = 999999;
03824    }
03825    /* Update last transmit time now */
03826    tpeer->lasttxtime = *tv;
03827    
03828    /* Calculate ms offset */
03829    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03830    /* Predict from last value */
03831    pred = tpeer->lastsent + sampms;
03832    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03833       ms = pred;
03834    
03835    /* We never send the same timestamp twice, so fudge a little if we must */
03836    if (ms == tpeer->lastsent)
03837       ms = tpeer->lastsent + 1;
03838    tpeer->lastsent = ms;
03839    return ms;
03840 }
03841 
03842 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03843 {
03844    long ms; /* NOT unsigned */
03845    if (ast_tvzero(iaxs[callno]->rxcore)) {
03846       /* Initialize rxcore time if appropriate */
03847       gettimeofday(&iaxs[callno]->rxcore, NULL);
03848       /* Round to nearest 20ms so traces look pretty */
03849       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03850    }
03851    /* Calculate difference between trunk and channel */
03852    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03853    /* Return as the sum of trunk time and the difference between trunk and real time */
03854    return ms + ts;
03855 }
03856 
03857 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03858 {
03859    int ms;
03860    int voice = 0;
03861    int genuine = 0;
03862    int adjust;
03863    struct timeval *delivery = NULL;
03864 
03865 
03866    /* What sort of frame do we have?: voice is self-explanatory
03867       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03868       non-genuine frames are CONTROL frames [ringing etc], DTMF
03869       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03870       the others need a timestamp slaved to the voice frames so that they go in sequence
03871    */
03872    if (f) {
03873       if (f->frametype == AST_FRAME_VOICE) {
03874          voice = 1;
03875          delivery = &f->delivery;
03876       } else if (f->frametype == AST_FRAME_IAX) {
03877          genuine = 1;
03878       } else if (f->frametype == AST_FRAME_CNG) {
03879          p->notsilenttx = 0;  
03880       }
03881    }
03882    if (ast_tvzero(p->offset)) {
03883       gettimeofday(&p->offset, NULL);
03884       /* Round to nearest 20ms for nice looking traces */
03885       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03886    }
03887    /* If the timestamp is specified, just send it as is */
03888    if (ts)
03889       return ts;
03890    /* If we have a time that the frame arrived, always use it to make our timestamp */
03891    if (delivery && !ast_tvzero(*delivery)) {
03892       ms = ast_tvdiff_ms(*delivery, p->offset);
03893       if (option_debug > 2 && iaxdebug)
03894          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03895    } else {
03896       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03897       if (ms < 0)
03898          ms = 0;
03899       if (voice) {
03900          /* On a voice frame, use predicted values if appropriate */
03901          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03902             /* Adjust our txcore, keeping voice and non-voice synchronized */
03903             /* AN EXPLANATION:
03904                When we send voice, we usually send "calculated" timestamps worked out
03905                on the basis of the number of samples sent. When we send other frames,
03906                we usually send timestamps worked out from the real clock.
03907                The problem is that they can tend to drift out of step because the 
03908                   source channel's clock and our clock may not be exactly at the same rate.
03909                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03910                for this call.  Moving it adjusts timestamps for non-voice frames.
03911                We make the adjustment in the style of a moving average.  Each time we
03912                adjust p->offset by 10% of the difference between our clock-derived
03913                timestamp and the predicted timestamp.  That's why you see "10000"
03914                below even though IAX2 timestamps are in milliseconds.
03915                The use of a moving average avoids offset moving too radically.
03916                Generally, "adjust" roams back and forth around 0, with offset hardly
03917                changing at all.  But if a consistent different starts to develop it
03918                will be eliminated over the course of 10 frames (200-300msecs) 
03919             */
03920             adjust = (ms - p->nextpred);
03921             if (adjust < 0)
03922                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03923             else if (adjust > 0)
03924                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03925 
03926             if (!p->nextpred) {
03927                p->nextpred = ms; /*f->samples / 8;*/
03928                if (p->nextpred <= p->lastsent)
03929                   p->nextpred = p->lastsent + 3;
03930             }
03931             ms = p->nextpred;
03932          } else {
03933                 /* in this case, just use the actual
03934             * time, since we're either way off
03935             * (shouldn't happen), or we're  ending a
03936             * silent period -- and seed the next
03937             * predicted time.  Also, round ms to the
03938             * next multiple of frame size (so our
03939             * silent periods are multiples of
03940             * frame size too) */
03941 
03942             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03943                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03944                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03945 
03946             if (f->samples >= 8) /* check to make sure we dont core dump */
03947             {
03948                int diff = ms % (f->samples / 8);
03949                if (diff)
03950                    ms += f->samples/8 - diff;
03951             }
03952 
03953             p->nextpred = ms;
03954             p->notsilenttx = 1;
03955          }
03956       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03957          /*
03958          * IAX2 draft 03 says that timestamps MUST be in order.
03959          * It does not say anything about several frames having the same timestamp
03960          * When transporting video, we can have a frame that spans multiple iax packets
03961          * (so called slices), so it would make sense to use the same timestamp for all of
03962          * them
03963          * We do want to make sure that frames don't go backwards though
03964          */
03965          if ( (unsigned int)ms < p->lastsent )
03966             ms = p->lastsent;
03967       } else {
03968          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03969             it's a genuine frame */
03970          if (genuine) {
03971             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03972             if (ms <= p->lastsent)
03973                ms = p->lastsent + 3;
03974          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03975             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03976             ms = p->lastsent + 3;
03977          }
03978       }
03979    }
03980    p->lastsent = ms;
03981    if (voice)
03982       p->nextpred = p->nextpred + f->samples / 8;
03983    return ms;
03984 }
03985 
03986 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03987 {
03988    /* Returns where in "receive time" we are.  That is, how many ms
03989       since we received (or would have received) the frame with timestamp 0 */
03990    int ms;
03991 #ifdef IAXTESTS
03992    int jit;
03993 #endif /* IAXTESTS */
03994    /* Setup rxcore if necessary */
03995    if (ast_tvzero(p->rxcore)) {
03996       p->rxcore = ast_tvnow();
03997       if (option_debug && iaxdebug)
03998          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03999                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04000       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04001 #if 1
04002       if (option_debug && iaxdebug)
04003          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04004                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04005 #endif
04006    }
04007 
04008    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04009 #ifdef IAXTESTS
04010    if (test_jit) {
04011       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04012          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04013          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04014             jit = -jit;
04015          ms += jit;
04016       }
04017    }
04018    if (test_late) {
04019       ms += test_late;
04020       test_late = 0;
04021    }
04022 #endif /* IAXTESTS */
04023    return ms;
04024 }
04025 
04026 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04027 {
04028    struct iax2_trunk_peer *tpeer;
04029    
04030    /* Finds and locks trunk peer */
04031    ast_mutex_lock(&tpeerlock);
04032    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04033       /* We don't lock here because tpeer->addr *never* changes */
04034       if (!inaddrcmp(&tpeer->addr, sin)) {
04035          ast_mutex_lock(&tpeer->lock);
04036          break;
04037       }
04038    }
04039    if (!tpeer) {
04040       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04041          ast_mutex_init(&tpeer->lock);
04042          tpeer->lastsent = 9999;
04043          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04044          tpeer->trunkact = ast_tvnow();
04045          ast_mutex_lock(&tpeer->lock);
04046          tpeer->next = tpeers;
04047          tpeer->sockfd = fd;
04048          tpeers = tpeer;
04049 #ifdef SO_NO_CHECK
04050          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04051 #endif
04052          if (option_debug)
04053             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04054       }
04055    }
04056    ast_mutex_unlock(&tpeerlock);
04057    return tpeer;
04058 }
04059 
04060 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04061 {
04062    struct ast_frame *f;
04063    struct iax2_trunk_peer *tpeer;
04064    void *tmp, *ptr;
04065    struct ast_iax2_meta_trunk_entry *met;
04066    struct ast_iax2_meta_trunk_mini *mtm;
04067 
04068    f = &fr->af;
04069    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04070    if (tpeer) {
04071       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04072          /* Need to reallocate space */
04073          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04074             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04075                ast_mutex_unlock(&tpeer->lock);
04076                return -1;
04077             }
04078             
04079             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04080             tpeer->trunkdata = tmp;
04081             if (option_debug)
04082                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);
04083          } else {
04084             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));
04085             ast_mutex_unlock(&tpeer->lock);
04086             return -1;
04087          }
04088       }
04089 
04090       /* Append to meta frame */
04091       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04092       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04093          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04094          mtm->len = htons(f->datalen);
04095          mtm->mini.callno = htons(pvt->callno);
04096          mtm->mini.ts = htons(0xffff & fr->ts);
04097          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04098          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04099       } else {
04100          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04101          /* Store call number and length in meta header */
04102          met->callno = htons(pvt->callno);
04103          met->len = htons(f->datalen);
04104          /* Advance pointers/decrease length past trunk entry header */
04105          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04106          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04107       }
04108       /* Copy actual trunk data */
04109       memcpy(ptr, f->data, f->datalen);
04110       tpeer->trunkdatalen += f->datalen;
04111 
04112       tpeer->calls++;
04113       ast_mutex_unlock(&tpeer->lock);
04114    }
04115    return 0;
04116 }
04117 
04118 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04119 {
04120    aes_encrypt_key128(digest, ecx);
04121    aes_decrypt_key128(digest, dcx);
04122 }
04123 
04124 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04125 {
04126 #if 0
04127    /* Debug with "fake encryption" */
04128    int x;
04129    if (len % 16)
04130       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04131    for (x=0;x<len;x++)
04132       dst[x] = src[x] ^ 0xff;
04133 #else 
04134    unsigned char lastblock[16] = { 0 };
04135    int x;
04136    while(len > 0) {
04137       aes_decrypt(src, dst, dcx);
04138       for (x=0;x<16;x++)
04139          dst[x] ^= lastblock[x];
04140       memcpy(lastblock, src, sizeof(lastblock));
04141       dst += 16;
04142       src += 16;
04143       len -= 16;
04144    }
04145 #endif
04146 }
04147 
04148 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04149 {
04150 #if 0
04151    /* Debug with "fake encryption" */
04152    int x;
04153    if (len % 16)
04154       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04155    for (x=0;x<len;x++)
04156       dst[x] = src[x] ^ 0xff;
04157 #else
04158    unsigned char curblock[16] = { 0 };
04159    int x;
04160    while(len > 0) {
04161       for (x=0;x<16;x++)
04162          curblock[x] ^= src[x];
04163       aes_encrypt(curblock, dst, ecx);
04164       memcpy(curblock, dst, sizeof(curblock)); 
04165       dst += 16;
04166       src += 16;
04167       len -= 16;
04168    }
04169 #endif
04170 }
04171 
04172 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04173 {
04174    int padding;
04175    unsigned char *workspace;
04176 
04177    workspace = alloca(*datalen);
04178    memset(f, 0, sizeof(*f));
04179    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04180       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04181       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04182          return -1;
04183       /* Decrypt */
04184       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04185 
04186       padding = 16 + (workspace[15] & 0xf);
04187       if (option_debug && iaxdebug)
04188          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04189       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04190          return -1;
04191 
04192       *datalen -= padding;
04193       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04194       f->frametype = fh->type;
04195       if (f->frametype == AST_FRAME_VIDEO) {
04196          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04197       } else {
04198          f->subclass = uncompress_subclass(fh->csub);
04199       }
04200    } else {
04201       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04202       if (option_debug && iaxdebug)
04203          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04204       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04205          return -1;
04206       /* Decrypt */
04207       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04208       padding = 16 + (workspace[15] & 0x0f);
04209       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04210          return -1;
04211       *datalen -= padding;
04212       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04213    }
04214    return 0;
04215 }
04216 
04217 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04218 {
04219    int padding;
04220    unsigned char *workspace;
04221    workspace = alloca(*datalen + 32);
04222    if (!workspace)
04223       return -1;
04224    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04225       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04226       if (option_debug && iaxdebug)
04227          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04228       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04229       padding = 16 + (padding & 0xf);
04230       memcpy(workspace, poo, padding);
04231       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04232       workspace[15] &= 0xf0;
04233       workspace[15] |= (padding & 0xf);
04234       if (option_debug && iaxdebug)
04235          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]);
04236       *datalen += padding;
04237       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04238       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04239          memcpy(poo, workspace + *datalen - 32, 32);
04240    } else {
04241       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04242       if (option_debug && iaxdebug)
04243          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04244       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04245       padding = 16 + (padding & 0xf);
04246       memcpy(workspace, poo, padding);
04247       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04248       workspace[15] &= 0xf0;
04249       workspace[15] |= (padding & 0x0f);
04250       *datalen += padding;
04251       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04252       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04253          memcpy(poo, workspace + *datalen - 32, 32);
04254    }
04255    return 0;
04256 }
04257 
04258 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04259 {
04260    int res=-1;
04261    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04262       /* Search for possible keys, given secrets */
04263       struct MD5Context md5;
04264       unsigned char digest[16];
04265       char *tmppw, *stringp;
04266       
04267       tmppw = ast_strdupa(iaxs[callno]->secret);
04268       stringp = tmppw;
04269       while ((tmppw = strsep(&stringp, ";"))) {
04270          MD5Init(&md5);
04271          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04272          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04273          MD5Final(digest, &md5);
04274          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04275          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04276          if (!res) {
04277             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04278             break;
04279          }
04280       }
04281    } else 
04282       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04283    return res;
04284 }
04285 
04286 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04287 {
04288    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04289       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04290       or delayed, with retransmission */
04291    struct ast_iax2_full_hdr *fh;
04292    struct ast_iax2_mini_hdr *mh;
04293    struct ast_iax2_video_hdr *vh;
04294    struct {
04295       struct iax_frame fr2;
04296       unsigned char buffer[4096];
04297    } frb;
04298    struct iax_frame *fr;
04299    int res;
04300    int sendmini=0;
04301    unsigned int lastsent;
04302    unsigned int fts;
04303 
04304    frb.fr2.afdatalen = sizeof(frb.buffer);
04305 
04306    if (!pvt) {
04307       ast_log(LOG_WARNING, "No private structure for packet?\n");
04308       return -1;
04309    }
04310    
04311    lastsent = pvt->lastsent;
04312 
04313    /* Calculate actual timestamp */
04314    fts = calc_timestamp(pvt, ts, f);
04315 
04316    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04317     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04318     * increment the "predicted timestamps" for voice, if we're predecting */
04319    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04320        return 0;
04321 
04322 
04323    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04324          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04325          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04326       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04327        (f->frametype == AST_FRAME_VOICE) 
04328       /* is a voice frame */ &&
04329       (f->subclass == pvt->svoiceformat) 
04330       /* is the same type */ ) {
04331          /* Force immediate rather than delayed transmission */
04332          now = 1;
04333          /* Mark that mini-style frame is appropriate */
04334          sendmini = 1;
04335    }
04336    if ( f->frametype == AST_FRAME_VIDEO ) {
04337       /*
04338        * If the lower 15 bits of the timestamp roll over, or if
04339        * the video format changed then send a full frame.
04340        * Otherwise send a mini video frame
04341        */
04342       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04343           ((f->subclass & ~0x1) == pvt->svideoformat)
04344          ) {
04345          now = 1;
04346          sendmini = 1;
04347       } else {
04348          now = 0;
04349          sendmini = 0;
04350       }
04351       pvt->lastvsent = fts;
04352    }
04353    /* Allocate an iax_frame */
04354    if (now) {
04355       fr = &frb.fr2;
04356    } else
04357       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));
04358    if (!fr) {
04359       ast_log(LOG_WARNING, "Out of memory\n");
04360       return -1;
04361    }
04362    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04363    iax_frame_wrap(fr, f);
04364 
04365    fr->ts = fts;
04366    fr->callno = pvt->callno;
04367    fr->transfer = transfer;
04368    fr->final = final;
04369    if (!sendmini) {
04370       /* We need a full frame */
04371       if (seqno > -1)
04372          fr->oseqno = seqno;
04373       else
04374          fr->oseqno = pvt->oseqno++;
04375       fr->iseqno = pvt->iseqno;
04376       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04377       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04378       fh->ts = htonl(fr->ts);
04379       fh->oseqno = fr->oseqno;
04380       if (transfer) {
04381          fh->iseqno = 0;
04382       } else
04383          fh->iseqno = fr->iseqno;
04384       /* Keep track of the last thing we've acknowledged */
04385       if (!transfer)
04386          pvt->aseqno = fr->iseqno;
04387       fh->type = fr->af.frametype & 0xFF;
04388       if (fr->af.frametype == AST_FRAME_VIDEO)
04389          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04390       else
04391          fh->csub = compress_subclass(fr->af.subclass);
04392       if (transfer) {
04393          fr->dcallno = pvt->transfercallno;
04394       } else
04395          fr->dcallno = pvt->peercallno;
04396       fh->dcallno = htons(fr->dcallno);
04397       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04398       fr->data = fh;
04399       fr->retries = 0;
04400       /* Retry after 2x the ping time has passed */
04401       fr->retrytime = pvt->pingtime * 2;
04402       if (fr->retrytime < MIN_RETRY_TIME)
04403          fr->retrytime = MIN_RETRY_TIME;
04404       if (fr->retrytime > MAX_RETRY_TIME)
04405          fr->retrytime = MAX_RETRY_TIME;
04406       /* Acks' don't get retried */
04407       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04408          fr->retries = -1;
04409       else if (f->frametype == AST_FRAME_VOICE)
04410          pvt->svoiceformat = f->subclass;
04411       else if (f->frametype == AST_FRAME_VIDEO)
04412          pvt->svideoformat = f->subclass & ~0x1;
04413       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04414          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04415             if (iaxdebug) {
04416                if (fr->transfer)
04417                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04418                else
04419                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04420             }
04421             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04422          } else
04423             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04424       }
04425    
04426       if (now) {
04427          res = send_packet(fr);
04428       } else
04429          res = iax2_transmit(fr);
04430    } else {
04431       if (ast_test_flag(pvt, IAX_TRUNK)) {
04432          iax2_trunk_queue(pvt, fr);
04433          res = 0;
04434       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04435          /* Video frame have no sequence number */
04436          fr->oseqno = -1;
04437          fr->iseqno = -1;
04438          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04439          vh->zeros = 0;
04440          vh->callno = htons(0x8000 | fr->callno);
04441          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04442          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04443          fr->data = vh;
04444          fr->retries = -1;
04445          res = send_packet(fr);        
04446       } else {
04447          /* Mini-frames have no sequence number */
04448          fr->oseqno = -1;
04449          fr->iseqno = -1;
04450          /* Mini frame will do */
04451          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04452          mh->callno = htons(fr->callno);
04453          mh->ts = htons(fr->ts & 0xFFFF);
04454          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04455          fr->data = mh;
04456          fr->retries = -1;
04457          if (pvt->transferring == TRANSFER_MEDIAPASS)
04458             fr->transfer = 1;
04459          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04460             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04461                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04462             } else
04463                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04464          }
04465          res = send_packet(fr);
04466       }
04467    }
04468    return res;
04469 }
04470 
04471 static int iax2_show_users(int fd, int argc, char *argv[])
04472 {
04473    regex_t regexbuf;
04474    int havepattern = 0;
04475 
04476 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04477 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04478 
04479    struct iax2_user *user = NULL;
04480    char auth[90];
04481    char *pstr = "";
04482    struct ao2_iterator i;
04483 
04484    switch (argc) {
04485    case 5:
04486       if (!strcasecmp(argv[3], "like")) {
04487          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04488             return RESULT_SHOWUSAGE;
04489          havepattern = 1;
04490       } else
04491          return RESULT_SHOWUSAGE;
04492    case 3:
04493       break;
04494    default:
04495       return RESULT_SHOWUSAGE;
04496    }
04497 
04498    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04499    i = ao2_iterator_init(users, 0);
04500    for (user = ao2_iterator_next(&i); user; 
04501       user_unref(user), user = ao2_iterator_next(&i)) {
04502       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04503          continue;
04504       
04505       if (!ast_strlen_zero(user->secret)) {
04506          ast_copy_string(auth,user->secret,sizeof(auth));
04507       } else if (!ast_strlen_zero(user->inkeys)) {
04508          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04509       } else
04510          ast_copy_string(auth, "-no secret-", sizeof(auth));
04511       
04512       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04513          pstr = "REQ Only";
04514       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04515          pstr = "Disabled";
04516       else
04517          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04518       
04519       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04520          user->contexts ? user->contexts->context : context,
04521          user->ha ? "Yes" : "No", pstr);
04522    }
04523 
04524    if (havepattern)
04525       regfree(&regexbuf);
04526 
04527    return RESULT_SUCCESS;
04528 #undef FORMAT
04529 #undef FORMAT2
04530 }
04531 
04532 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04533 {
04534    regex_t regexbuf;
04535    int havepattern = 0;
04536    int total_peers = 0;
04537    int online_peers = 0;
04538    int offline_peers = 0;
04539    int unmonitored_peers = 0;
04540    struct ao2_iterator i;
04541 
04542 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04543 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04544 
04545    struct iax2_peer *peer = NULL;
04546    char name[256];
04547    int registeredonly=0;
04548    char *term = manager ? "\r\n" : "\n";
04549 
04550    switch (argc) {
04551    case 6:
04552       if (!strcasecmp(argv[3], "registered"))
04553          registeredonly = 1;
04554       else
04555          return RESULT_SHOWUSAGE;
04556       if (!strcasecmp(argv[4], "like")) {
04557          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04558             return RESULT_SHOWUSAGE;
04559          havepattern = 1;
04560       } else
04561          return RESULT_SHOWUSAGE;
04562       break;
04563    case 5:
04564       if (!strcasecmp(argv[3], "like")) {
04565          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04566             return RESULT_SHOWUSAGE;
04567          havepattern = 1;
04568       } else
04569          return RESULT_SHOWUSAGE;
04570       break;
04571    case 4:
04572       if (!strcasecmp(argv[3], "registered"))
04573          registeredonly = 1;
04574       else
04575          return RESULT_SHOWUSAGE;
04576       break;
04577    case 3:
04578       break;
04579    default:
04580       return RESULT_SHOWUSAGE;
04581    }
04582 
04583 
04584    if (s)
04585       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04586    else
04587       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04588 
04589    i = ao2_iterator_init(peers, 0);
04590    for (peer = ao2_iterator_next(&i); peer; 
04591       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04592       char nm[20];
04593       char status[20];
04594       char srch[2000];
04595       int retstatus;
04596 
04597       if (registeredonly && !peer->addr.sin_addr.s_addr)
04598          continue;
04599       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04600          continue;
04601 
04602       if (!ast_strlen_zero(peer->username))
04603          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04604       else
04605          ast_copy_string(name, peer->name, sizeof(name));
04606       
04607       retstatus = peer_status(peer, status, sizeof(status));
04608       if (retstatus > 0)
04609          online_peers++;
04610       else if (!retstatus)
04611          offline_peers++;
04612       else
04613          unmonitored_peers++;
04614       
04615       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04616       
04617       snprintf(srch, sizeof(srch), FORMAT, name, 
04618           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04619           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04620           nm,
04621           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04622           peer->encmethods ? "(E)" : "   ", status, term);
04623       
04624       if (s)
04625          astman_append(s, FORMAT, name, 
04626                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04627                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04628                   nm,
04629                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04630                   peer->encmethods ? "(E)" : "   ", status, term);
04631       else
04632          ast_cli(fd, FORMAT, name, 
04633             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04634             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04635             nm,
04636             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04637             peer->encmethods ? "(E)" : "   ", status, term);
04638       total_peers++;
04639    }
04640 
04641    if (s)
04642       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04643    else
04644       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04645 
04646    if (havepattern)
04647       regfree(&regexbuf);
04648 
04649    return RESULT_SUCCESS;
04650 #undef FORMAT
04651 #undef FORMAT2
04652 }
04653 
04654 static int iax2_show_threads(int fd, int argc, char *argv[])
04655 {
04656    struct iax2_thread *thread = NULL;
04657    time_t t;
04658    int threadcount = 0, dynamiccount = 0;
04659    char type;
04660 
04661    if (argc != 3)
04662       return RESULT_SHOWUSAGE;
04663       
04664    ast_cli(fd, "IAX2 Thread Information\n");
04665    time(&t);
04666    ast_cli(fd, "Idle Threads:\n");
04667    AST_LIST_LOCK(&idle_list);
04668    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04669 #ifdef DEBUG_SCHED_MULTITHREAD
04670       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04671          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04672 #else
04673       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04674          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04675 #endif
04676       threadcount++;
04677    }
04678    AST_LIST_UNLOCK(&idle_list);
04679    ast_cli(fd, "Active Threads:\n");
04680    AST_LIST_LOCK(&active_list);
04681    AST_LIST_TRAVERSE(&active_list, thread, list) {
04682       if (thread->type == IAX_TYPE_DYNAMIC)
04683          type = 'D';
04684       else
04685          type = 'P';
04686 #ifdef DEBUG_SCHED_MULTITHREAD
04687       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04688          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04689 #else
04690       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04691          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04692 #endif
04693       threadcount++;
04694    }
04695    AST_LIST_UNLOCK(&active_list);
04696    ast_cli(fd, "Dynamic Threads:\n");
04697         AST_LIST_LOCK(&dynamic_list);
04698         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04699 #ifdef DEBUG_SCHED_MULTITHREAD
04700                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04701                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04702 #else
04703                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04704                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04705 #endif
04706       dynamiccount++;
04707         }
04708         AST_LIST_UNLOCK(&dynamic_list);
04709    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04710    return RESULT_SUCCESS;
04711 }
04712 
04713 static int iax2_show_peers(int fd, int argc, char *argv[])
04714 {
04715    return __iax2_show_peers(0, fd, NULL, argc, argv);
04716 }
04717 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04718 {
04719    ast_cli_netstats(s, -1, 0);
04720    astman_append(s, "\r\n");
04721    return RESULT_SUCCESS;
04722 }
04723 
04724 static int iax2_show_firmware(int fd, int argc, char *argv[])
04725 {
04726 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04727 #if !defined(__FreeBSD__)
04728 #define FORMAT "%-15.15s  %-15d %-15d\n"
04729 #else /* __FreeBSD__ */
04730 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04731 #endif /* __FreeBSD__ */
04732    struct iax_firmware *cur;
04733    if ((argc != 3) && (argc != 4))
04734       return RESULT_SHOWUSAGE;
04735    ast_mutex_lock(&waresl.lock);
04736    
04737    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04738    for (cur = waresl.wares;cur;cur = cur->next) {
04739       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04740          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04741             (int)ntohl(cur->fwh->datalen));
04742    }
04743    ast_mutex_unlock(&waresl.lock);
04744    return RESULT_SUCCESS;
04745 #undef FORMAT
04746 #undef FORMAT2
04747 }
04748 
04749 /* JDG: callback to display iax peers in manager */
04750 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04751 {
04752    char *a[] = { "iax2", "show", "users" };
04753    int ret;
04754    const char *id = astman_get_header(m,"ActionID");
04755 
04756    if (!ast_strlen_zero(id))
04757       astman_append(s, "ActionID: %s\r\n",id);
04758    ret = __iax2_show_peers(1, -1, s, 3, a );
04759    astman_append(s, "\r\n\r\n" );
04760    return ret;
04761 } /* /JDG */
04762 
04763 static char *regstate2str(int regstate)
04764 {
04765    switch(regstate) {
04766    case REG_STATE_UNREGISTERED:
04767       return "Unregistered";
04768    case REG_STATE_REGSENT:
04769       return "Request Sent";
04770    case REG_STATE_AUTHSENT:
04771       return "Auth. Sent";
04772    case REG_STATE_REGISTERED:
04773       return "Registered";
04774    case REG_STATE_REJECTED:
04775       return "Rejected";
04776    case REG_STATE_TIMEOUT:
04777       return "Timeout";
04778    case REG_STATE_NOAUTH:
04779       return "No Authentication";
04780    default:
04781       return "Unknown";
04782    }
04783 }
04784 
04785 static int iax2_show_registry(int fd, int argc, char *argv[])
04786 {
04787 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04788 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04789    struct iax2_registry *reg = NULL;
04790 
04791    char host[80];
04792    char perceived[80];
04793    if (argc != 3)
04794       return RESULT_SHOWUSAGE;
04795    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04796    AST_LIST_LOCK(&registrations);
04797    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04798       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04799       if (reg->us.sin_addr.s_addr) 
04800          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04801       else
04802          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04803       ast_cli(fd, FORMAT, host, 
04804                (reg->dnsmgr) ? "Y" : "N", 
04805                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04806    }
04807    AST_LIST_UNLOCK(&registrations);
04808    return RESULT_SUCCESS;
04809 #undef FORMAT
04810 #undef FORMAT2
04811 }
04812 
04813 static int iax2_show_channels(int fd, int argc, char *argv[])
04814 {
04815 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04816 #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"
04817 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04818    int x;
04819    int numchans = 0;
04820 
04821    if (argc != 3)
04822       return RESULT_SHOWUSAGE;
04823    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04824    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04825       ast_mutex_lock(&iaxsl[x]);
04826       if (iaxs[x]) {
04827          int lag, jitter, localdelay;
04828          jb_info jbinfo;
04829          
04830          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04831             jb_getinfo(iaxs[x]->jb, &jbinfo);
04832             jitter = jbinfo.jitter;
04833             localdelay = jbinfo.current - jbinfo.min;
04834          } else {
04835             jitter = -1;
04836             localdelay = 0;
04837          }
04838          lag = iaxs[x]->remote_rr.delay;
04839          ast_cli(fd, FORMAT,
04840             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04841             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04842             S_OR(iaxs[x]->username, "(None)"),
04843             iaxs[x]->callno, iaxs[x]->peercallno,
04844             iaxs[x]->oseqno, iaxs[x]->iseqno,
04845             lag,
04846             jitter,
04847             localdelay,
04848             ast_getformatname(iaxs[x]->voiceformat) );
04849          numchans++;
04850       }
04851       ast_mutex_unlock(&iaxsl[x]);
04852    }
04853    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04854    return RESULT_SUCCESS;
04855 #undef FORMAT
04856 #undef FORMAT2
04857 #undef FORMATB
04858 }
04859 
04860 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04861 {
04862    int x;
04863    int numchans = 0;
04864    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04865       ast_mutex_lock(&iaxsl[x]);
04866       if (iaxs[x]) {
04867          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04868          char *fmt;
04869          jb_info jbinfo;
04870          
04871          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04872             jb_getinfo(iaxs[x]->jb, &jbinfo);
04873             localjitter = jbinfo.jitter;
04874             localdelay = jbinfo.current - jbinfo.min;
04875             locallost = jbinfo.frames_lost;
04876             locallosspct = jbinfo.losspct/1000;
04877             localdropped = jbinfo.frames_dropped;
04878             localooo = jbinfo.frames_ooo;
04879          } else {
04880             localjitter = -1;
04881             localdelay = 0;
04882             locallost = -1;
04883             locallosspct = -1;
04884             localdropped = 0;
04885             localooo = -1;
04886          }
04887          if (limit_fmt)
04888             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04889          else
04890             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04891          if (s)
04892             
04893             astman_append(s, fmt,
04894                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04895                      iaxs[x]->pingtime,
04896                      localjitter, 
04897                      localdelay,
04898                      locallost,
04899                      locallosspct,
04900                      localdropped,
04901                      localooo,
04902                      iaxs[x]->frames_received/1000,
04903                      iaxs[x]->remote_rr.jitter,
04904                      iaxs[x]->remote_rr.delay,
04905                      iaxs[x]->remote_rr.losscnt,
04906                      iaxs[x]->remote_rr.losspct,
04907                      iaxs[x]->remote_rr.dropped,
04908                      iaxs[x]->remote_rr.ooo,
04909                      iaxs[x]->remote_rr.packets/1000);
04910          else
04911             ast_cli(fd, fmt,
04912                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04913                iaxs[x]->pingtime,
04914                localjitter, 
04915                localdelay,
04916                locallost,
04917                locallosspct,
04918                localdropped,
04919                localooo,
04920                iaxs[x]->frames_received/1000,
04921                iaxs[x]->remote_rr.jitter,
04922                iaxs[x]->remote_rr.delay,
04923                iaxs[x]->remote_rr.losscnt,
04924                iaxs[x]->remote_rr.losspct,
04925                iaxs[x]->remote_rr.dropped,
04926                iaxs[x]->remote_rr.ooo,
04927                iaxs[x]->remote_rr.packets/1000
04928                );
04929          numchans++;
04930       }
04931       ast_mutex_unlock(&iaxsl[x]);
04932    }
04933    return numchans;
04934 }
04935 
04936 static int iax2_show_netstats(int fd, int argc, char *argv[])
04937 {
04938    int numchans = 0;
04939    if (argc != 3)
04940       return RESULT_SHOWUSAGE;
04941    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04942    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04943    numchans = ast_cli_netstats(NULL, fd, 1);
04944    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04945    return RESULT_SUCCESS;
04946 }
04947 
04948 static int iax2_do_debug(int fd, int argc, char *argv[])
04949 {
04950    if (argc < 2 || argc > 3)
04951       return RESULT_SHOWUSAGE;
04952    iaxdebug = 1;
04953    ast_cli(fd, "IAX2 Debugging Enabled\n");
04954    return RESULT_SUCCESS;
04955 }
04956 
04957 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04958 {
04959    if (argc < 3 || argc > 4)
04960       return RESULT_SHOWUSAGE;
04961    iaxtrunkdebug = 1;
04962    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04963    return RESULT_SUCCESS;
04964 }
04965 
04966 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04967 {
04968    if (argc < 3 || argc > 4)
04969       return RESULT_SHOWUSAGE;
04970    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04971    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04972    return RESULT_SUCCESS;
04973 }
04974 
04975 static int iax2_no_debug(int fd, int argc, char *argv[])
04976 {
04977    if (argc < 3 || argc > 4)
04978       return RESULT_SHOWUSAGE;
04979    iaxdebug = 0;
04980    ast_cli(fd, "IAX2 Debugging Disabled\n");
04981    return RESULT_SUCCESS;
04982 }
04983 
04984 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04985 {
04986    if (argc < 4 || argc > 5)
04987       return RESULT_SHOWUSAGE;
04988    iaxtrunkdebug = 0;
04989    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04990    return RESULT_SUCCESS;
04991 }
04992 
04993 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04994 {
04995    if (argc < 4 || argc > 5)
04996       return RESULT_SHOWUSAGE;
04997    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04998    jb_debug_output("\n");
04999    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05000    return RESULT_SUCCESS;
05001 }
05002 
05003 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05004 {
05005    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05006    int res = -1;
05007    ast_mutex_lock(&iaxsl[callno]);
05008    if (iaxs[callno]) {
05009    /* If there's an outstanding error, return failure now */
05010       if (!iaxs[callno]->error) {
05011          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05012             res = 0;
05013             /* Don't waste bandwidth sending null frames */
05014          else if (f->frametype == AST_FRAME_NULL)
05015             res = 0;
05016          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05017             res = 0;
05018          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05019             res = 0;
05020          else
05021          /* Simple, just queue for transmission */
05022             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05023       } else {
05024          if (option_debug)
05025             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05026       }
05027    }
05028    /* If it's already gone, just return */
05029    ast_mutex_unlock(&iaxsl[callno]);
05030    return res;
05031 }
05032 
05033 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05034       int now, int transfer, int final)
05035 {
05036    struct ast_frame f = { 0, };
05037 
05038    f.frametype = type;
05039    f.subclass = command;
05040    f.datalen = datalen;
05041    f.src = __FUNCTION__;
05042    f.data = (void *) data;
05043 
05044    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05045 }
05046 
05047 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05048 {
05049    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05050 }
05051 
05052 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05053 {
05054    int res;
05055    ast_mutex_lock(&iaxsl[callno]);
05056    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05057    ast_mutex_unlock(&iaxsl[callno]);
05058    return res;
05059 }
05060 
05061 /*!
05062  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05063  *       the pvt struct for the given call number may disappear during its 
05064  *       execution.
05065  */
05066 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)
05067 {
05068    int call_num = i->callno;
05069    /* It is assumed that the callno has already been locked */
05070    iax2_predestroy(i->callno);
05071    if (!iaxs[call_num])
05072       return -1;
05073    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05074 }
05075 
05076 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)
05077 {
05078    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05079 }
05080 
05081 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05082 {
05083    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05084 }
05085 
05086 static int apply_context(struct iax2_context *con, const char *context)
05087 {
05088    while(con) {
05089       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05090          return -1;
05091       con = con->next;
05092    }
05093    return 0;
05094 }
05095 
05096 
05097 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05098 {
05099    /* Start pessimistic */
05100    int res = -1;
05101    int version = 2;
05102    struct iax2_user *user = NULL, *best = NULL;
05103    int bestscore = 0;
05104    int gotcapability = 0;
05105    struct ast_variable *v = NULL, *tmpvar = NULL;
05106    struct ao2_iterator i;
05107 
05108    if (!iaxs[callno])
05109       return res;
05110    if (ies->called_number)
05111       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05112    if (ies->calling_number) {
05113       ast_shrink_phone_number(ies->calling_number);
05114       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05115    }
05116    if (ies->calling_name)
05117       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05118    if (ies->calling_ani)
05119       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05120    if (ies->dnid)
05121       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05122    if (ies->rdnis)
05123       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05124    if (ies->called_context)
05125       ast_string_field_set(iaxs[callno], context, ies->called_context);
05126    if (ies->language)
05127       ast_string_field_set(iaxs[callno], language, ies->language);
05128    if (ies->username)
05129       ast_string_field_set(iaxs[callno], username, ies->username);
05130    if (ies->calling_ton > -1)
05131       iaxs[callno]->calling_ton = ies->calling_ton;
05132    if (ies->calling_tns > -1)
05133       iaxs[callno]->calling_tns = ies->calling_tns;
05134    if (ies->calling_pres > -1)
05135       iaxs[callno]->calling_pres = ies->calling_pres;
05136    if (ies->format)
05137       iaxs[callno]->peerformat = ies->format;
05138    if (ies->adsicpe)
05139       iaxs[callno]->peeradsicpe = ies->adsicpe;
05140    if (ies->capability) {
05141       gotcapability = 1;
05142       iaxs[callno]->peercapability = ies->capability;
05143    } 
05144    if (ies->version)
05145       version = ies->version;
05146 
05147    /* Use provided preferences until told otherwise for actual preferences */
05148    if(ies->codec_prefs) {
05149       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05150       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05151    }
05152 
05153    if (!gotcapability) 
05154       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05155    if (version > IAX_PROTO_VERSION) {
05156       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05157          ast_inet_ntoa(sin->sin_addr), version);
05158       return res;
05159    }
05160    /* Search the userlist for a compatible entry, and fill in the rest */
05161    i = ao2_iterator_init(users, 0);
05162    while ((user = ao2_iterator_next(&i))) {
05163       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05164          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05165          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05166          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05167               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05168          if (!ast_strlen_zero(iaxs[callno]->username)) {
05169             /* Exact match, stop right now. */
05170             if (best)
05171                user_unref(best);
05172             best = user;
05173             break;
05174          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05175             /* No required authentication */
05176             if (user->ha) {
05177                /* There was host authentication and we passed, bonus! */
05178                if (bestscore < 4) {
05179                   bestscore = 4;
05180                   if (best)
05181                      user_unref(best);
05182                   best = user;
05183                   continue;
05184                }
05185             } else {
05186                /* No host access, but no secret, either, not bad */
05187                if (bestscore < 3) {
05188                   bestscore = 3;
05189                   if (best)
05190                      user_unref(best);
05191                   best = user;
05192                   continue;
05193                }
05194             }
05195          } else {
05196             if (user->ha) {
05197                /* Authentication, but host access too, eh, it's something.. */
05198                if (bestscore < 2) {
05199                   bestscore = 2;
05200                   if (best)
05201                      user_unref(best);
05202                   best = user;
05203                   continue;
05204                }
05205             } else {
05206                /* Authentication and no host access...  This is our baseline */
05207                if (bestscore < 1) {
05208                   bestscore = 1;
05209                   if (best)
05210                      user_unref(best);
05211                   best = user;
05212                   continue;
05213                }
05214             }
05215          }
05216       }
05217       user_unref(user);
05218    }
05219    user = best;
05220    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05221       user = realtime_user(iaxs[callno]->username, sin);
05222       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05223           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05224          user = user_unref(user);
05225       }
05226    }
05227    if (user) {
05228       /* We found our match (use the first) */
05229       /* copy vars */
05230       for (v = user->vars ; v ; v = v->next) {
05231          if((tmpvar = ast_variable_new(v->name, v->value))) {
05232             tmpvar->next = iaxs[callno]->vars; 
05233             iaxs[callno]->vars = tmpvar;
05234          }
05235       }
05236       /* If a max AUTHREQ restriction is in place, activate it */
05237       if (user->maxauthreq > 0)
05238          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05239       iaxs[callno]->prefs = user->prefs;
05240       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05241       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05242       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05243       iaxs[callno]->encmethods = user->encmethods;
05244       /* Store the requested username if not specified */
05245       if (ast_strlen_zero(iaxs[callno]->username))
05246          ast_string_field_set(iaxs[callno], username, user->name);
05247       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05248       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05249       iaxs[callno]->capability = user->capability;
05250       /* And use the default context */
05251       if (ast_strlen_zero(iaxs[callno]->context)) {
05252          if (user->contexts)
05253             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05254          else
05255             ast_string_field_set(iaxs[callno], context, context);
05256       }
05257       /* And any input keys */
05258       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05259       /* And the permitted authentication methods */
05260       iaxs[callno]->authmethods = user->authmethods;
05261       iaxs[callno]->adsi = user->adsi;
05262       /* If they have callerid, override the given caller id.  Always store the ANI */
05263       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05264          if (ast_test_flag(user, IAX_HASCALLERID)) {
05265             iaxs[callno]->calling_tns = 0;
05266             iaxs[callno]->calling_ton = 0;
05267             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05268             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05269             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05270          }
05271          if (ast_strlen_zero(iaxs[callno]->ani))
05272             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05273       } else {
05274          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05275       }
05276       if (!ast_strlen_zero(user->accountcode))
05277          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05278       if (!ast_strlen_zero(user->mohinterpret))
05279          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05280       if (!ast_strlen_zero(user->mohsuggest))
05281          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05282       if (user->amaflags)
05283          iaxs[callno]->amaflags = user->amaflags;
05284       if (!ast_strlen_zero(user->language))
05285          ast_string_field_set(iaxs[callno], language, user->language);
05286       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05287       /* Keep this check last */
05288       if (!ast_strlen_zero(user->dbsecret)) {
05289          char *family, *key=NULL;
05290          char buf[80];
05291          family = ast_strdupa(user->dbsecret);
05292          key = strchr(family, '/');
05293          if (key) {
05294             *key = '\0';
05295             key++;
05296          }
05297          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05298             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05299          else
05300             ast_string_field_set(iaxs[callno], secret, buf);
05301       } else
05302          ast_string_field_set(iaxs[callno], secret, user->secret);
05303       res = 0;
05304       user = user_unref(user);
05305    } else {
05306        /* user was not found, but we should still fake an AUTHREQ.
05307         * Set authmethods to the last known authmethod used by the system
05308         * Set a fake secret, it's not looked at, just required to attempt authentication.
05309         * Set authrej so the AUTHREP is rejected without even looking at its contents */
05310       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
05311       ast_string_field_set(iaxs[callno], secret, "badsecret");
05312       iaxs[callno]->authrej = 1;
05313       if (!ast_strlen_zero(iaxs[callno]->username)) {
05314          /* only send the AUTHREQ if a username was specified. */
05315          res = 0;
05316       }
05317    }
05318    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05319    return res;
05320 }
05321 
05322 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05323 {
05324    struct ast_iax2_full_hdr fh;
05325    fh.scallno = htons(src | IAX_FLAG_FULL);
05326    fh.dcallno = htons(dst);
05327    fh.ts = 0;
05328    fh.oseqno = 0;
05329    fh.iseqno = 0;
05330    fh.type = AST_FRAME_IAX;
05331    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05332    if (iaxdebug)
05333        iax_showframe(NULL, &fh, 0, sin, 0);
05334    if (option_debug)
05335       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05336          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05337    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05338 }
05339 
05340 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05341 {
05342    /* Select exactly one common encryption if there are any */
05343    p->encmethods &= enc;
05344    if (p->encmethods) {
05345       if (p->encmethods & IAX_ENCRYPT_AES128)
05346          p->encmethods = IAX_ENCRYPT_AES128;
05347       else
05348          p->encmethods = 0;
05349    }
05350 }
05351 
05352 /*!
05353  * \pre iaxsl[call_num] is locked
05354  *
05355  * \note Since this function calls send_command_final(), the pvt struct for the given
05356  *       call number may disappear while executing this function.
05357  */
05358 static int authenticate_request(int call_num)
05359 {
05360    struct iax_ie_data ied;
05361    int res = -1, authreq_restrict = 0;
05362    char challenge[10];
05363    struct chan_iax2_pvt *p = iaxs[call_num];
05364 
05365    memset(&ied, 0, sizeof(ied));
05366 
05367    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05368    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05369       struct iax2_user *user, tmp_user = {
05370          .name = p->username, 
05371       };
05372 
05373       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05374       if (user) {
05375          if (user->curauthreq == user->maxauthreq)
05376             authreq_restrict = 1;
05377          else
05378             user->curauthreq++;
05379          user = user_unref(user);
05380       }
05381    }
05382 
05383    /* If the AUTHREQ limit test failed, send back an error */
05384    if (authreq_restrict) {
05385       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05386       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05387       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05388       return 0;
05389    }
05390 
05391    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05392    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05393       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05394       ast_string_field_set(p, challenge, challenge);
05395       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05396       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05397    }
05398    if (p->encmethods)
05399       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05400 
05401    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05402 
05403    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05404 
05405    if (p->encmethods)
05406       ast_set_flag(p, IAX_ENCRYPTED);
05407 
05408    return res;
05409 }
05410 
05411 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05412 {
05413    char requeststr[256];
05414    char md5secret[256] = "";
05415    char secret[256] = "";
05416    char rsasecret[256] = "";
05417    int res = -1; 
05418    int x;
05419    struct iax2_user *user, tmp_user = {
05420       .name = p->username, 
05421    };
05422 
05423    if (p->authrej) {
05424       return res;
05425    }
05426    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05427    if (user) {
05428       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05429          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05430          ast_clear_flag(p, IAX_MAXAUTHREQ);
05431       }
05432       ast_string_field_set(p, host, user->name);
05433       user = user_unref(user);
05434    }
05435 
05436    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05437       return res;
05438    if (ies->password)
05439       ast_copy_string(secret, ies->password, sizeof(secret));
05440    if (ies->md5_result)
05441       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05442    if (ies->rsa_result)
05443       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05444    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05445       struct ast_key *key;
05446       char *keyn;
05447       char tmpkey[256];
05448       char *stringp=NULL;
05449       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05450       stringp=tmpkey;
05451       keyn = strsep(&stringp, ":");
05452       while(keyn) {
05453          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05454          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05455             res = 0;
05456             break;
05457          } else if (!key)
05458             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05459          keyn = strsep(&stringp, ":");
05460       }
05461    } else if (p->authmethods & IAX_AUTH_MD5) {
05462       struct MD5Context md5;
05463       unsigned char digest[16];
05464       char *tmppw, *stringp;
05465       
05466       tmppw = ast_strdupa(p->secret);
05467       stringp = tmppw;
05468       while((tmppw = strsep(&stringp, ";"))) {
05469          MD5Init(&md5);
05470          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05471          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05472          MD5Final(digest, &md5);
05473          /* If they support md5, authenticate with it.  */
05474          for (x=0;x<16;x++)
05475             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05476          if (!strcasecmp(requeststr, md5secret)) {
05477             res = 0;
05478             break;
05479          }
05480       }
05481    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05482       if (!strcmp(secret, p->secret))
05483          res = 0;
05484    }
05485    return res;
05486 }
05487 
05488 /*! \brief Verify inbound registration */
05489 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05490 {
05491    char requeststr[256] = "";
05492    char peer[256] = "";
05493    char md5secret[256] = "";
05494    char rsasecret[256] = "";
05495    char secret[256] = "";
05496    struct iax2_peer *p = NULL;
05497    struct ast_key *key;
05498    char *keyn;
05499    int x;
05500    int expire = 0;
05501    int res = -1;
05502 
05503    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05504    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05505    if (ies->username)
05506       ast_copy_string(peer, ies->username, sizeof(peer));
05507    if (ies->password)
05508       ast_copy_string(secret, ies->password, sizeof(secret));
05509    if (ies->md5_result)
05510       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05511    if (ies->rsa_result)
05512       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05513    if (ies->refresh)
05514       expire = ies->refresh;
05515 
05516    if (ast_strlen_zero(peer)) {
05517       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05518       return -1;
05519    }
05520 
05521    /* SLD: first call to lookup peer during registration */
05522    ast_mutex_unlock(&iaxsl[callno]);
05523    p = find_peer(peer, 1);
05524    ast_mutex_lock(&iaxsl[callno]);
05525    if (!p || !iaxs[callno]) {
05526       if (iaxs[callno]) {
05527          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
05528 
05529          ast_string_field_set(iaxs[callno], secret, "badsecret");
05530 
05531          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
05532           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
05533           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
05534           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
05535           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
05536           *
05537           * If none of these cases exist, res will be returned as 0 without authentication indicating
05538           * an AUTHREQ needs to be sent out. */
05539 
05540          if (ast_strlen_zero(iaxs[callno]->challenge) &&
05541             !(!ast_strlen_zero(secret) && plaintext)) {
05542             /* by setting res to 0, an REGAUTH will be sent */
05543             res = 0;
05544          }
05545       }
05546       if (authdebug && !p)
05547          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05548 
05549       goto return_unref;
05550    }
05551 
05552    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05553       if (authdebug)
05554          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05555       goto return_unref;
05556    }
05557 
05558    if (!ast_apply_ha(p->ha, sin)) {
05559       if (authdebug)
05560          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05561       goto return_unref;
05562    }
05563    ast_string_field_set(iaxs[callno], secret, p->secret);
05564    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05565    /* Check secret against what we have on file */
05566    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05567       if (!ast_strlen_zero(p->inkeys)) {
05568          char tmpkeys[256];
05569          char *stringp=NULL;
05570          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05571          stringp=tmpkeys;
05572          keyn = strsep(&stringp, ":");
05573          while(keyn) {
05574             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05575             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05576                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05577                break;
05578             } else if (!key)
05579                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05580             keyn = strsep(&stringp, ":");
05581          }
05582          if (!keyn) {
05583             if (authdebug)
05584                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05585             goto return_unref;
05586          }
05587       } else {
05588          if (authdebug)
05589             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05590          goto return_unref;
05591       }
05592    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05593       struct MD5Context md5;
05594       unsigned char digest[16];
05595       char *tmppw, *stringp;
05596 
05597       tmppw = ast_strdupa(p->secret);
05598       stringp = tmppw;
05599       while((tmppw = strsep(&stringp, ";"))) {
05600          MD5Init(&md5);
05601          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05602          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05603          MD5Final(digest, &md5);
05604          for (x=0;x<16;x++)
05605             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05606          if (!strcasecmp(requeststr, md5secret))
05607             break;
05608       }
05609       if (tmppw) {
05610          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05611       } else {
05612          if (authdebug)
05613             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05614          goto return_unref;
05615       }
05616    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05617       /* They've provided a plain text password and we support that */
05618       if (strcmp(secret, p->secret)) {
05619          if (authdebug)
05620             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05621          goto return_unref;
05622       } else
05623          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05624    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
05625       /* if challenge has been sent, but no challenge response if given, reject. */
05626       goto return_unref;
05627    }
05628    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05629 
05630    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
05631    res = 0;
05632 return_unref:
05633    if (iaxs[callno]) {
05634       ast_string_field_set(iaxs[callno], peer, peer);
05635    }
05636    /* Choose lowest expiry number */
05637    if (expire && (expire < iaxs[callno]->expiry)) {
05638       iaxs[callno]->expiry = expire;
05639    }
05640 
05641    if (p)
05642       peer_unref(p);
05643    return res;
05644 }
05645 
05646 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)
05647 {
05648    int res = -1;
05649    int x;
05650    if (!ast_strlen_zero(keyn)) {
05651       if (!(authmethods & IAX_AUTH_RSA)) {
05652          if (ast_strlen_zero(secret)) 
05653             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));
05654       } else if (ast_strlen_zero(challenge)) {
05655          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05656       } else {
05657          char sig[256];
05658          struct ast_key *key;
05659          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05660          if (!key) {
05661             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05662          } else {
05663             if (ast_sign(key, (char*)challenge, sig)) {
05664                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05665                res = -1;
05666             } else {
05667                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05668                res = 0;
05669             }
05670          }
05671       }
05672    } 
05673    /* Fall back */
05674    if (res && !ast_strlen_zero(secret)) {
05675       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05676          struct MD5Context md5;
05677          unsigned char digest[16];
05678          char digres[128];
05679          MD5Init(&md5);
05680          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05681          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05682          MD5Final(digest, &md5);
05683          /* If they support md5, authenticate with it.  */
05684          for (x=0;x<16;x++)
05685             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05686          if (ecx && dcx)
05687             build_enc_keys(digest, ecx, dcx);
05688          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05689          res = 0;
05690       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05691          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05692          res = 0;
05693       } else
05694          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05695    }
05696    return res;
05697 }
05698 
05699 /*!
05700  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05701  *       so do not call this function with a pvt lock held.
05702  */
05703 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05704 {
05705    struct iax2_peer *peer = NULL;
05706    /* Start pessimistic */
05707    int res = -1;
05708    int authmethods = 0;
05709    struct iax_ie_data ied;
05710    uint16_t callno = p->callno;
05711 
05712    memset(&ied, 0, sizeof(ied));
05713    
05714    if (ies->username)
05715       ast_string_field_set(p, username, ies->username);
05716    if (ies->challenge)
05717       ast_string_field_set(p, challenge, ies->challenge);
05718    if (ies->authmethods)
05719       authmethods = ies->authmethods;
05720    if (authmethods & IAX_AUTH_MD5)
05721       merge_encryption(p, ies->encmethods);
05722    else
05723       p->encmethods = 0;
05724 
05725    /* Check for override RSA authentication first */
05726    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05727       /* Normal password authentication */
05728       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05729    } else {
05730       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05731       while ((peer = ao2_iterator_next(&i))) {
05732          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05733              /* No peer specified at our end, or this is the peer */
05734              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05735              /* No username specified in peer rule, or this is the right username */
05736              && (!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)))
05737              /* No specified host, or this is our host */
05738             ) {
05739             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05740             if (!res) {
05741                peer_unref(peer);
05742                break;
05743             }
05744          }
05745          peer_unref(peer);
05746       }
05747       if (!peer) {
05748          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05749             that we're trying to authenticate *to* a realtime peer */
05750          const char *peer_name = ast_strdupa(p->peer);
05751          ast_mutex_unlock(&iaxsl[callno]);
05752          if ((peer = realtime_peer(peer_name, NULL))) {
05753             ast_mutex_lock(&iaxsl[callno]);
05754             if (!(p = iaxs[callno])) {
05755                peer_unref(peer);
05756                return -1;
05757             }
05758             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05759             peer_unref(peer);
05760          }
05761          if (!peer) {
05762             ast_mutex_lock(&iaxsl[callno]);
05763             if (!(p = iaxs[callno]))
05764                return -1;
05765          }
05766       }
05767    }
05768    if (ies->encmethods)
05769       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05770    if (!res)
05771       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05772    return res;
05773 }
05774 
05775 static int iax2_do_register(struct iax2_registry *reg);
05776 
05777 static void __iax2_do_register_s(const void *data)
05778 {
05779    struct iax2_registry *reg = (struct iax2_registry *)data;
05780    reg->expire = -1;
05781    iax2_do_register(reg);
05782 }
05783 
05784 static int iax2_do_register_s(const void *data)
05785 {
05786 #ifdef SCHED_MULTITHREADED
05787    if (schedule_action(__iax2_do_register_s, data))
05788 #endif      
05789       __iax2_do_register_s(data);
05790    return 0;
05791 }
05792 
05793 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05794 {
05795    int newcall = 0;
05796    char newip[256];
05797    struct iax_ie_data ied;
05798    struct sockaddr_in new;
05799    
05800    
05801    memset(&ied, 0, sizeof(ied));
05802    if (ies->apparent_addr)
05803       bcopy(ies->apparent_addr, &new, sizeof(new));
05804    if (ies->callno)
05805       newcall = ies->callno;
05806    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05807       ast_log(LOG_WARNING, "Invalid transfer request\n");
05808       return -1;
05809    }
05810    pvt->transfercallno = newcall;
05811    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05812    inet_aton(newip, &pvt->transfer.sin_addr);
05813    pvt->transfer.sin_family = AF_INET;
05814    pvt->transferring = TRANSFER_BEGIN;
05815    pvt->transferid = ies->transferid;
05816    if (ies->transferid)
05817       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05818    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05819    return 0; 
05820 }
05821 
05822 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05823 {
05824    char exten[256] = "";
05825    int status = CACHE_FLAG_UNKNOWN;
05826    int expiry = iaxdefaultdpcache;
05827    int x;
05828    int matchmore = 0;
05829    struct iax2_dpcache *dp, *prev;
05830    
05831    if (ies->called_number)
05832       ast_copy_string(exten, ies->called_number, sizeof(exten));
05833 
05834    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05835       status = CACHE_FLAG_EXISTS;
05836    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05837       status = CACHE_FLAG_CANEXIST;
05838    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05839       status = CACHE_FLAG_NONEXISTENT;
05840 
05841    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05842       /* Don't really do anything with this */
05843    }
05844    if (ies->refresh)
05845       expiry = ies->refresh;
05846    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05847       matchmore = CACHE_FLAG_MATCHMORE;
05848    ast_mutex_lock(&dpcache_lock);
05849    prev = NULL;
05850    dp = pvt->dpentries;
05851    while(dp) {
05852       if (!strcmp(dp->exten, exten)) {
05853          /* Let them go */
05854          if (prev)
05855             prev->peer = dp->peer;
05856          else
05857             pvt->dpentries = dp->peer;
05858          dp->peer = NULL;
05859          dp->callno = 0;
05860          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05861          if (dp->flags & CACHE_FLAG_PENDING) {
05862             dp->flags &= ~CACHE_FLAG_PENDING;
05863             dp->flags |= status;
05864             dp->flags |= matchmore;
05865          }
05866          /* Wake up waiters */
05867          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05868             if (dp->waiters[x] > -1)
05869                write(dp->waiters[x], "asdf", 4);
05870       }
05871       prev = dp;
05872       dp = dp->peer;
05873    }
05874    ast_mutex_unlock(&dpcache_lock);
05875    return 0;
05876 }
05877 
05878 static int complete_transfer(int callno, struct iax_ies *ies)
05879 {
05880    int peercallno = 0;
05881    struct chan_iax2_pvt *pvt = iaxs[callno];
05882    struct iax_frame *cur;
05883    jb_frame frame;
05884 
05885    if (ies->callno)
05886       peercallno = ies->callno;
05887 
05888    if (peercallno < 1) {
05889       ast_log(LOG_WARNING, "Invalid transfer request\n");
05890       return -1;
05891    }
05892    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05893    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05894    /* Reset sequence numbers */
05895    pvt->oseqno = 0;
05896    pvt->rseqno = 0;
05897    pvt->iseqno = 0;
05898    pvt->aseqno = 0;
05899 
05900    if (pvt->peercallno) {
05901       remove_by_peercallno(pvt);
05902    }
05903    pvt->peercallno = peercallno;
05904    store_by_peercallno(pvt);
05905 
05906    pvt->transferring = TRANSFER_NONE;
05907    pvt->svoiceformat = -1;
05908    pvt->voiceformat = 0;
05909    pvt->svideoformat = -1;
05910    pvt->videoformat = 0;
05911    pvt->transfercallno = -1;
05912    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05913    memset(&pvt->offset, 0, sizeof(pvt->offset));
05914    /* reset jitterbuffer */
05915    while(jb_getall(pvt->jb,&frame) == JB_OK)
05916       iax2_frame_free(frame.data);
05917    jb_reset(pvt->jb);
05918    pvt->lag = 0;
05919    pvt->last = 0;
05920    pvt->lastsent = 0;
05921    pvt->nextpred = 0;
05922    pvt->pingtime = DEFAULT_RETRY_TIME;
05923    AST_LIST_LOCK(&iaxq.queue);
05924    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05925       /* We must cancel any packets that would have been transmitted
05926          because now we're talking to someone new.  It's okay, they
05927          were transmitted to someone that didn't care anyway. */
05928       if (callno == cur->callno) 
05929          cur->retries = -1;
05930    }
05931    AST_LIST_UNLOCK(&iaxq.queue);
05932    return 0; 
05933 }
05934 
05935 /*! \brief Acknowledgment received for OUR registration */
05936 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05937 {
05938    struct iax2_registry *reg;
05939    /* Start pessimistic */
05940    char peer[256] = "";
05941    char msgstatus[60];
05942    int refresh = 60;
05943    char ourip[256] = "<Unspecified>";
05944    struct sockaddr_in oldus;
05945    struct sockaddr_in us;
05946    int oldmsgs;
05947 
05948    memset(&us, 0, sizeof(us));
05949    if (ies->apparent_addr)
05950       bcopy(ies->apparent_addr, &us, sizeof(us));
05951    if (ies->username)
05952       ast_copy_string(peer, ies->username, sizeof(peer));
05953    if (ies->refresh)
05954       refresh = ies->refresh;
05955    if (ies->calling_number) {
05956       /* We don't do anything with it really, but maybe we should */
05957    }
05958    reg = iaxs[callno]->reg;
05959    if (!reg) {
05960       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05961       return -1;
05962    }
05963    memcpy(&oldus, &reg->us, sizeof(oldus));
05964    oldmsgs = reg->messages;
05965    if (inaddrcmp(&reg->addr, sin)) {
05966       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05967       return -1;
05968    }
05969    memcpy(&reg->us, &us, sizeof(reg->us));
05970    if (ies->msgcount >= 0)
05971       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05972    /* always refresh the registration at the interval requested by the server
05973       we are registering to
05974    */
05975    reg->refresh = refresh;
05976    AST_SCHED_DEL(sched, reg->expire);
05977    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05978    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05979       if (option_verbose > 2) {
05980          if (reg->messages > 255)
05981             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05982          else if (reg->messages > 1)
05983             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05984          else if (reg->messages > 0)
05985             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05986          else
05987             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05988          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05989          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05990       }
05991       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05992    }
05993    reg->regstate = REG_STATE_REGISTERED;
05994    return 0;
05995 }
05996 
05997 static int iax2_register(char *value, int lineno)
05998 {
05999    struct iax2_registry *reg;
06000    char copy[256];
06001    char *username, *hostname, *secret;
06002    char *porta;
06003    char *stringp=NULL;
06004    
06005    if (!value)
06006       return -1;
06007    ast_copy_string(copy, value, sizeof(copy));
06008    stringp=copy;
06009    username = strsep(&stringp, "@");
06010    hostname = strsep(&stringp, "@");
06011    if (!hostname) {
06012       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06013       return -1;
06014    }
06015    stringp=username;
06016    username = strsep(&stringp, ":");
06017    secret = strsep(&stringp, ":");
06018    stringp=hostname;
06019    hostname = strsep(&stringp, ":");
06020    porta = strsep(&stringp, ":");
06021    
06022    if (porta && !atoi(porta)) {
06023       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06024       return -1;
06025    }
06026    if (!(reg = ast_calloc(1, sizeof(*reg))))
06027       return -1;
06028    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06029       free(reg);
06030       return -1;
06031    }
06032    ast_copy_string(reg->username, username, sizeof(reg->username));
06033    if (secret)
06034       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06035    reg->expire = -1;
06036    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06037    reg->addr.sin_family = AF_INET;
06038    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06039    AST_LIST_LOCK(&registrations);
06040    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06041    AST_LIST_UNLOCK(&registrations);
06042    
06043    return 0;
06044 }
06045 
06046 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06047 {
06048    char multi[256];
06049    char *stringp, *ext;
06050    if (!ast_strlen_zero(regcontext)) {
06051       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06052       stringp = multi;
06053       while((ext = strsep(&stringp, "&"))) {
06054          if (onoff) {
06055             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06056                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06057                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06058          } else
06059             ast_context_remove_extension(regcontext, ext, 1, NULL);
06060       }
06061    }
06062 }
06063 static void prune_peers(void);
06064 
06065 static void unlink_peer(struct iax2_peer *peer)
06066 {
06067    if (peer->expire > -1) {
06068       if (!ast_sched_del(sched, peer->expire)) {
06069          peer->expire = -1;
06070          peer_unref(peer);
06071       }
06072    }
06073 
06074    if (peer->pokeexpire > -1) {
06075       if (!ast_sched_del(sched, peer->pokeexpire)) {
06076          peer->pokeexpire = -1;
06077          peer_unref(peer);
06078       }
06079    }
06080 
06081    ao2_unlink(peers, peer);
06082 }
06083 
06084 static void __expire_registry(const void *data)
06085 {
06086    struct iax2_peer *peer = (struct iax2_peer *) data;
06087 
06088    if (!peer)
06089       return;
06090 
06091    peer->expire = -1;
06092 
06093    if (option_debug)
06094       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06095    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06096       realtime_update_peer(peer->name, &peer->addr, 0);
06097    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06098    /* Reset the address */
06099    memset(&peer->addr, 0, sizeof(peer->addr));
06100    /* Reset expiry value */
06101    peer->expiry = min_reg_expire;
06102    if (!ast_test_flag(peer, IAX_TEMPONLY))
06103       ast_db_del("IAX/Registry", peer->name);
06104    register_peer_exten(peer, 0);
06105    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06106    if (iax2_regfunk)
06107       iax2_regfunk(peer->name, 0);
06108 
06109    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06110       unlink_peer(peer);
06111 
06112    peer_unref(peer);
06113 }
06114 
06115 static int expire_registry(const void *data)
06116 {
06117 #ifdef SCHED_MULTITHREADED
06118    if (schedule_action(__expire_registry, data))
06119 #endif      
06120       __expire_registry(data);
06121    return 0;
06122 }
06123 
06124 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06125 
06126 static void reg_source_db(struct iax2_peer *p)
06127 {
06128    char data[80];
06129    struct in_addr in;
06130    char *c, *d;
06131    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06132       c = strchr(data, ':');
06133       if (c) {
06134          *c = '\0';
06135          c++;
06136          if (inet_aton(data, &in)) {
06137             d = strchr(c, ':');
06138             if (d) {
06139                *d = '\0';
06140                d++;
06141                if (option_verbose > 2)
06142                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06143                   ast_inet_ntoa(in), atoi(c), atoi(d));
06144                iax2_poke_peer(p, 0);
06145                p->expiry = atoi(d);
06146                memset(&p->addr, 0, sizeof(p->addr));
06147                p->addr.sin_family = AF_INET;
06148                p->addr.sin_addr = in;
06149                p->addr.sin_port = htons(atoi(c));
06150                if (p->expire > -1) {
06151                   if (!ast_sched_del(sched, p->expire)) {
06152                      p->expire = -1;
06153                      peer_unref(p);
06154                   }
06155                }
06156                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06157                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06158                if (p->expire == -1)
06159                   peer_unref(p);
06160                if (iax2_regfunk)
06161                   iax2_regfunk(p->name, 1);
06162                register_peer_exten(p, 1);
06163             }              
06164                
06165          }
06166       }
06167    }
06168 }
06169 
06170 /*!
06171  * \pre iaxsl[callno] is locked
06172  *
06173  * \note Since this function calls send_command_final(), the pvt struct for
06174  *       the given call number may disappear while executing this function.
06175  */
06176 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06177 {
06178    /* Called from IAX thread only, with proper iaxsl lock */
06179    struct iax_ie_data ied;
06180    struct iax2_peer *p;
06181    int msgcount;
06182    char data[80];
06183    int version;
06184    const char *peer_name;
06185    int res = -1;
06186 
06187    memset(&ied, 0, sizeof(ied));
06188 
06189    peer_name = ast_strdupa(iaxs[callno]->peer);
06190 
06191    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06192    ast_mutex_unlock(&iaxsl[callno]);
06193    if (!(p = find_peer(peer_name, 1))) {
06194       ast_mutex_lock(&iaxsl[callno]);
06195       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06196       return -1;
06197    }
06198    ast_mutex_lock(&iaxsl[callno]);
06199    if (!iaxs[callno])
06200       goto return_unref;
06201 
06202    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06203       if (sin->sin_addr.s_addr) {
06204          time_t nowtime;
06205          time(&nowtime);
06206          realtime_update_peer(peer_name, sin, nowtime);
06207       } else {
06208          realtime_update_peer(peer_name, sin, 0);
06209       }
06210    }
06211    if (inaddrcmp(&p->addr, sin)) {
06212       if (iax2_regfunk)
06213          iax2_regfunk(p->name, 1);
06214       /* Stash the IP address from which they registered */
06215       memcpy(&p->addr, sin, sizeof(p->addr));
06216       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06217       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06218          ast_db_put("IAX/Registry", p->name, data);
06219          if  (option_verbose > 2)
06220             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06221                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06222          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06223          register_peer_exten(p, 1);
06224          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06225       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06226          if  (option_verbose > 2)
06227             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06228                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06229          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06230          register_peer_exten(p, 0);
06231          ast_db_del("IAX/Registry", p->name);
06232          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06233       }
06234       /* Update the host */
06235       /* Verify that the host is really there */
06236       iax2_poke_peer(p, callno);
06237    }     
06238 
06239    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06240    if (!iaxs[callno]) {
06241       res = 0;
06242       goto return_unref;
06243    }
06244 
06245    /* Store socket fd */
06246    p->sockfd = fd;
06247    /* Setup the expiry */
06248    if (p->expire > -1) {
06249       if (!ast_sched_del(sched, p->expire)) {
06250          p->expire = -1;
06251          peer_unref(p);
06252       }
06253    }
06254    /* treat an unspecified refresh interval as the minimum */
06255    if (!refresh)
06256       refresh = min_reg_expire;
06257    if (refresh > max_reg_expire) {
06258       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06259          p->name, max_reg_expire, refresh);
06260       p->expiry = max_reg_expire;
06261    } else if (refresh < min_reg_expire) {
06262       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06263          p->name, min_reg_expire, refresh);
06264       p->expiry = min_reg_expire;
06265    } else {
06266       p->expiry = refresh;
06267    }
06268    if (p->expiry && sin->sin_addr.s_addr) {
06269       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06270       if (p->expire == -1)
06271          peer_unref(p);
06272    }
06273    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06274    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06275    if (sin->sin_addr.s_addr) {
06276       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06277       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06278       if (!ast_strlen_zero(p->mailbox)) {
06279          int new, old;
06280          ast_app_inboxcount(p->mailbox, &new, &old);
06281          if (new > 255)
06282             new = 255;
06283          if (old > 255)
06284             old = 255;
06285          msgcount = (old << 8) | new;
06286          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06287       }
06288       if (ast_test_flag(p, IAX_HASCALLERID)) {
06289          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06290          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06291       }
06292    }
06293    version = iax_check_version(devtype);
06294    if (version) 
06295       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06296 
06297    res = 0;
06298 
06299 return_unref:
06300    peer_unref(p);
06301 
06302    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06303 }
06304 
06305 static int registry_authrequest(int callno)
06306 {
06307    struct iax_ie_data ied;
06308    struct iax2_peer *p;
06309    char challenge[10];
06310    const char *peer_name;
06311    int sentauthmethod;
06312 
06313    peer_name = ast_strdupa(iaxs[callno]->peer);
06314 
06315    /* SLD: third call to find_peer in registration */
06316    ast_mutex_unlock(&iaxsl[callno]);
06317    if ((p = find_peer(peer_name, 1))) {
06318       last_authmethod = p->authmethods;
06319    }
06320 
06321    ast_mutex_lock(&iaxsl[callno]);
06322    if (!iaxs[callno])
06323       goto return_unref;
06324 
06325    memset(&ied, 0, sizeof(ied));
06326    /* The selection of which delayed reject is sent may leak information,
06327     * if it sets a static response.  For example, if a host is known to only
06328     * use MD5 authentication, then an RSA response would indicate that the
06329     * peer does not exist, and vice-versa.
06330     * Therefore, we use whatever the last peer used (which may vary over the
06331     * course of a server, which should leak minimal information). */
06332    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06333    if (!p) {
06334       iaxs[callno]->authmethods = sentauthmethod;
06335    }
06336    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06337    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06338       /* Build the challenge */
06339       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06340       ast_string_field_set(iaxs[callno], challenge, challenge);
06341       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06342    }
06343    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06344 
06345 return_unref:
06346    if (p) {
06347       peer_unref(p);
06348    }
06349 
06350    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06351 }
06352 
06353 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06354 {
06355    struct iax2_registry *reg;
06356    /* Start pessimistic */
06357    struct iax_ie_data ied;
06358    char peer[256] = "";
06359    char challenge[256] = "";
06360    int res;
06361    int authmethods = 0;
06362    if (ies->authmethods)
06363       authmethods = ies->authmethods;
06364    if (ies->username)
06365       ast_copy_string(peer, ies->username, sizeof(peer));
06366    if (ies->challenge)
06367       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06368    memset(&ied, 0, sizeof(ied));
06369    reg = iaxs[callno]->reg;
06370    if (reg) {
06371          if (inaddrcmp(&reg->addr, sin)) {
06372             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06373             return -1;
06374          }
06375          if (ast_strlen_zero(reg->secret)) {
06376             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06377             reg->regstate = REG_STATE_NOAUTH;
06378             return -1;
06379          }
06380          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06381          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06382          if (reg->secret[0] == '[') {
06383             char tmpkey[256];
06384             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06385             tmpkey[strlen(tmpkey) - 1] = '\0';
06386             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06387          } else
06388             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06389          if (!res) {
06390             reg->regstate = REG_STATE_AUTHSENT;
06391             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06392          } else
06393             return -1;
06394          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06395    } else   
06396       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06397    return -1;
06398 }
06399 
06400 static void stop_stuff(int callno)
06401 {
06402    iax2_destroy_helper(iaxs[callno]);
06403 }
06404 
06405 static void __auth_reject(const void *nothing)
06406 {
06407    /* Called from IAX thread only, without iaxs lock */
06408    int callno = (int)(long)(nothing);
06409    struct iax_ie_data ied;
06410    ast_mutex_lock(&iaxsl[callno]);
06411    if (iaxs[callno]) {
06412       memset(&ied, 0, sizeof(ied));
06413       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06414          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06415          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06416       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06417          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06418          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06419       }
06420       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06421    }
06422    ast_mutex_unlock(&iaxsl[callno]);
06423 }
06424 
06425 static int auth_reject(const void *data)
06426 {
06427    int callno = (int)(long)(data);
06428    ast_mutex_lock(&iaxsl[callno]);
06429    if (iaxs[callno])
06430       iaxs[callno]->authid = -1;
06431    ast_mutex_unlock(&iaxsl[callno]);
06432 #ifdef SCHED_MULTITHREADED
06433    if (schedule_action(__auth_reject, data))
06434 #endif      
06435       __auth_reject(data);
06436    return 0;
06437 }
06438 
06439 static int auth_fail(int callno, int failcode)
06440 {
06441    /* Schedule sending the authentication failure in one second, to prevent
06442       guessing */
06443    if (iaxs[callno]) {
06444       iaxs[callno]->authfail = failcode;
06445       if (delayreject) {
06446          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06447          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06448       } else
06449          auth_reject((void *)(long)callno);
06450    }
06451    return 0;
06452 }
06453 
06454 static void __auto_hangup(const void *nothing)
06455 {
06456    /* Called from IAX thread only, without iaxs lock */
06457    int callno = (int)(long)(nothing);
06458    struct iax_ie_data ied;
06459    ast_mutex_lock(&iaxsl[callno]);
06460    if (iaxs[callno]) {
06461       memset(&ied, 0, sizeof(ied));
06462       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06463       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06464       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06465    }
06466    ast_mutex_unlock(&iaxsl[callno]);
06467 }
06468 
06469 static int auto_hangup(const void *data)
06470 {
06471    int callno = (int)(long)(data);
06472    ast_mutex_lock(&iaxsl[callno]);
06473    if (iaxs[callno]) {
06474       iaxs[callno]->autoid = -1;
06475    }
06476    ast_mutex_unlock(&iaxsl[callno]);
06477 #ifdef SCHED_MULTITHREADED
06478    if (schedule_action(__auto_hangup, data))
06479 #endif      
06480       __auto_hangup(data);
06481    return 0;
06482 }
06483 
06484 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06485 {
06486    struct iax_ie_data ied;
06487    /* Auto-hangup with 30 seconds of inactivity */
06488    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06489    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06490    memset(&ied, 0, sizeof(ied));
06491    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06492    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06493    dp->flags |= CACHE_FLAG_TRANSMITTED;
06494 }
06495 
06496 static int iax2_vnak(int callno)
06497 {
06498    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06499 }
06500 
06501 static void vnak_retransmit(int callno, int last)
06502 {
06503    struct iax_frame *f;
06504 
06505    AST_LIST_LOCK(&iaxq.queue);
06506    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06507       /* Send a copy immediately */
06508       if ((f->callno == callno) && iaxs[f->callno] &&
06509          ((unsigned char ) (f->oseqno - last) < 128) &&
06510          (f->retries >= 0)) {
06511          send_packet(f);
06512       }
06513    }
06514    AST_LIST_UNLOCK(&iaxq.queue);
06515 }
06516 
06517 static void __iax2_poke_peer_s(const void *data)
06518 {
06519    struct iax2_peer *peer = (struct iax2_peer *)data;
06520    iax2_poke_peer(peer, 0);
06521    peer_unref(peer);
06522 }
06523 
06524 static int iax2_poke_peer_s(const void *data)
06525 {
06526    struct iax2_peer *peer = (struct iax2_peer *)data;
06527    peer->pokeexpire = -1;
06528 #ifdef SCHED_MULTITHREADED
06529    if (schedule_action(__iax2_poke_peer_s, data))
06530 #endif      
06531       __iax2_poke_peer_s(data);
06532    return 0;
06533 }
06534 
06535 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06536 {
06537    int res = 0;
06538    struct iax_frame *fr;
06539    struct ast_iax2_meta_hdr *meta;
06540    struct ast_iax2_meta_trunk_hdr *mth;
06541    int calls = 0;
06542    
06543    /* Point to frame */
06544    fr = (struct iax_frame *)tpeer->trunkdata;
06545    /* Point to meta data */
06546    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06547    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06548    if (tpeer->trunkdatalen) {
06549       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06550       meta->zeros = 0;
06551       meta->metacmd = IAX_META_TRUNK;
06552       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06553          meta->cmddata = IAX_META_TRUNK_MINI;
06554       else
06555          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06556       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06557       /* And the rest of the ast_iax2 header */
06558       fr->direction = DIRECTION_OUTGRESS;
06559       fr->retrans = -1;
06560       fr->transfer = 0;
06561       /* Any appropriate call will do */
06562       fr->data = fr->afdata;
06563       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06564       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06565       calls = tpeer->calls;
06566 #if 0
06567       if (option_debug)
06568          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));
06569 #endif      
06570       /* Reset transmit trunk side data */
06571       tpeer->trunkdatalen = 0;
06572       tpeer->calls = 0;
06573    }
06574    if (res < 0)
06575       return res;
06576    return calls;
06577 }
06578 
06579 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06580 {
06581    /* Drop when trunk is about 5 seconds idle */
06582    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06583       return 1;
06584    return 0;
06585 }
06586 
06587 static int timing_read(int *id, int fd, short events, void *cbdata)
06588 {
06589    char buf[1024];
06590    int res;
06591    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06592    int processed = 0;
06593    int totalcalls = 0;
06594 #ifdef ZT_TIMERACK
06595    int x = 1;
06596 #endif
06597    struct timeval now;
06598    if (iaxtrunkdebug)
06599       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06600    gettimeofday(&now, NULL);
06601    if (events & AST_IO_PRI) {
06602 #ifdef ZT_TIMERACK
06603       /* Great, this is a timing interface, just call the ioctl */
06604       if (ioctl(fd, ZT_TIMERACK, &x)) {
06605          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06606          usleep(1);
06607          return -1;
06608       }
06609 #endif      
06610    } else {
06611       /* Read and ignore from the pseudo channel for timing */
06612       res = read(fd, buf, sizeof(buf));
06613       if (res < 1) {
06614          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06615          return 1;
06616       }
06617    }
06618    /* For each peer that supports trunking... */
06619    ast_mutex_lock(&tpeerlock);
06620    tpeer = tpeers;
06621    while(tpeer) {
06622       processed++;
06623       res = 0;
06624       ast_mutex_lock(&tpeer->lock);
06625       /* We can drop a single tpeer per pass.  That makes all this logic
06626          substantially easier */
06627       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06628          /* Take it out of the list, but don't free it yet, because it
06629             could be in use */
06630          if (prev)
06631             prev->next = tpeer->next;
06632          else
06633             tpeers = tpeer->next;
06634          drop = tpeer;
06635       } else {
06636          res = send_trunk(tpeer, &now);
06637          if (iaxtrunkdebug)
06638             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);
06639       }     
06640       totalcalls += res;   
06641       res = 0;
06642       ast_mutex_unlock(&tpeer->lock);
06643       prev = tpeer;
06644       tpeer = tpeer->next;
06645    }
06646    ast_mutex_unlock(&tpeerlock);
06647    if (drop) {
06648       ast_mutex_lock(&drop->lock);
06649       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06650          because by the time they could get tpeerlock, we've already grabbed it */
06651       if (option_debug)
06652          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06653       if (drop->trunkdata) {
06654          free(drop->trunkdata);
06655          drop->trunkdata = NULL;
06656       }
06657       ast_mutex_unlock(&drop->lock);
06658       ast_mutex_destroy(&drop->lock);
06659       free(drop);
06660       
06661    }
06662    if (iaxtrunkdebug)
06663       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06664    iaxtrunkdebug =0;
06665    return 1;
06666 }
06667 
06668 struct dpreq_data {
06669    int callno;
06670    char context[AST_MAX_EXTENSION];
06671    char callednum[AST_MAX_EXTENSION];
06672    char *callerid;
06673 };
06674 
06675 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06676 {
06677    unsigned short dpstatus = 0;
06678    struct iax_ie_data ied1;
06679    int mm;
06680 
06681    memset(&ied1, 0, sizeof(ied1));
06682    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06683    /* Must be started */
06684    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06685       dpstatus = IAX_DPSTATUS_EXISTS;
06686    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06687       dpstatus = IAX_DPSTATUS_CANEXIST;
06688    } else {
06689       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06690    }
06691    if (ast_ignore_pattern(context, callednum))
06692       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06693    if (mm)
06694       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06695    if (!skiplock)
06696       ast_mutex_lock(&iaxsl[callno]);
06697    if (iaxs[callno]) {
06698       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06699       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06700       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06701       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06702    }
06703    if (!skiplock)
06704       ast_mutex_unlock(&iaxsl[callno]);
06705 }
06706 
06707 static void *dp_lookup_thread(void *data)
06708 {
06709    /* Look up for dpreq */
06710    struct dpreq_data *dpr = data;
06711    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06712    if (dpr->callerid)
06713       free(dpr->callerid);
06714    free(dpr);
06715    return NULL;
06716 }
06717 
06718 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06719 {
06720    pthread_t newthread;
06721    struct dpreq_data *dpr;
06722    pthread_attr_t attr;
06723    
06724    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06725       return;
06726 
06727    pthread_attr_init(&attr);
06728    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06729 
06730    dpr->callno = callno;
06731    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06732    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06733    if (callerid)
06734       dpr->callerid = ast_strdup(callerid);
06735    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06736       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06737    }
06738 
06739    pthread_attr_destroy(&attr);
06740 }
06741 
06742 struct iax_dual {
06743    struct ast_channel *chan1;
06744    struct ast_channel *chan2;
06745 };
06746 
06747 static void *iax_park_thread(void *stuff)
06748 {
06749    struct ast_channel *chan1, *chan2;
06750    struct iax_dual *d;
06751    struct ast_frame *f;
06752    int ext;
06753    int res;
06754    d = stuff;
06755    chan1 = d->chan1;
06756    chan2 = d->chan2;
06757    free(d);
06758    f = ast_read(chan1);
06759    if (f)
06760       ast_frfree(f);
06761    res = ast_park_call(chan1, chan2, 0, &ext);
06762    ast_hangup(chan2);
06763    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06764    return NULL;
06765 }
06766 
06767 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06768 {
06769    struct iax_dual *d;
06770    struct ast_channel *chan1m, *chan2m;
06771    pthread_t th;
06772    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06773    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06774    if (chan2m && chan1m) {
06775       /* Make formats okay */
06776       chan1m->readformat = chan1->readformat;
06777       chan1m->writeformat = chan1->writeformat;
06778       ast_channel_masquerade(chan1m, chan1);
06779       /* Setup the extensions and such */
06780       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06781       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06782       chan1m->priority = chan1->priority;
06783       
06784       /* We make a clone of the peer channel too, so we can play
06785          back the announcement */
06786       /* Make formats okay */
06787       chan2m->readformat = chan2->readformat;
06788       chan2m->writeformat = chan2->writeformat;
06789       ast_channel_masquerade(chan2m, chan2);
06790       /* Setup the extensions and such */
06791       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06792       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06793       chan2m->priority = chan2->priority;
06794       if (ast_do_masquerade(chan2m)) {
06795          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06796          ast_hangup(chan2m);
06797          return -1;
06798       }
06799    } else {
06800       if (chan1m)
06801          ast_hangup(chan1m);
06802       if (chan2m)
06803          ast_hangup(chan2m);
06804       return -1;
06805    }
06806    if ((d = ast_calloc(1, sizeof(*d)))) {
06807       pthread_attr_t attr;
06808 
06809       pthread_attr_init(&attr);
06810       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06811 
06812       d->chan1 = chan1m;
06813       d->chan2 = chan2m;
06814       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06815          pthread_attr_destroy(&attr);
06816          return 0;
06817       }
06818       pthread_attr_destroy(&attr);
06819       free(d);
06820    }
06821    return -1;
06822 }
06823 
06824 
06825 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06826 
06827 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06828 {
06829    unsigned int ourver;
06830    char rsi[80];
06831    snprintf(rsi, sizeof(rsi), "si-%s", si);
06832    if (iax_provision_version(&ourver, rsi, 1))
06833       return 0;
06834    if (option_debug)
06835       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06836    if (ourver != ver) 
06837       iax2_provision(sin, sockfd, NULL, rsi, 1);
06838    return 0;
06839 }
06840 
06841 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06842 {
06843    jb_info stats;
06844    jb_getinfo(pvt->jb, &stats);
06845    
06846    memset(iep, 0, sizeof(*iep));
06847 
06848    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06849    if(stats.frames_in == 0) stats.frames_in = 1;
06850    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06851    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06852    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06853    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06854    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06855 }
06856 
06857 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06858 {
06859    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06860    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06861    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06862    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06863    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06864    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06865    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06866 }
06867 
06868 static int socket_process(struct iax2_thread *thread);
06869 
06870 /*!
06871  * \brief Handle any deferred full frames for this thread
06872  */
06873 static void handle_deferred_full_frames(struct iax2_thread *thread)
06874 {
06875    struct iax2_pkt_buf *pkt_buf;
06876 
06877    ast_mutex_lock(&thread->lock);
06878 
06879    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06880       ast_mutex_unlock(&thread->lock);
06881 
06882       thread->buf = pkt_buf->buf;
06883       thread->buf_len = pkt_buf->len;
06884       thread->buf_size = pkt_buf->len + 1;
06885       
06886       socket_process(thread);
06887 
06888       thread->buf = NULL;
06889       ast_free(pkt_buf);
06890 
06891       ast_mutex_lock(&thread->lock);
06892    }
06893 
06894    ast_mutex_unlock(&thread->lock);
06895 }
06896 
06897 /*!
06898  * \brief Queue the last read full frame for processing by a certain thread
06899  *
06900  * If there are already any full frames queued, they are sorted
06901  * by sequence number.
06902  */
06903 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06904 {
06905    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06906    struct ast_iax2_full_hdr *fh, *cur_fh;
06907 
06908    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06909       return;
06910 
06911    pkt_buf->len = from_here->buf_len;
06912    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06913 
06914    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06915    ast_mutex_lock(&to_here->lock);
06916    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06917       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06918       if (fh->oseqno < cur_fh->oseqno) {
06919          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06920          break;
06921       }
06922    }
06923    AST_LIST_TRAVERSE_SAFE_END
06924 
06925    if (!cur_pkt_buf)
06926       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06927    
06928    ast_mutex_unlock(&to_here->lock);
06929 }
06930 
06931 static int socket_read(int *id, int fd, short events, void *cbdata)
06932 {
06933    struct iax2_thread *thread;
06934    socklen_t len;
06935    time_t t;
06936    static time_t last_errtime = 0;
06937    struct ast_iax2_full_hdr *fh;
06938 
06939    if (!(thread = find_idle_thread())) {
06940       time(&t);
06941       if (t != last_errtime && option_debug)
06942          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06943       last_errtime = t;
06944       usleep(1);
06945       return 1;
06946    }
06947 
06948    len = sizeof(thread->iosin);
06949    thread->iofd = fd;
06950    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06951    thread->buf_size = sizeof(thread->readbuf);
06952    thread->buf = thread->readbuf;
06953    if (thread->buf_len < 0) {
06954       if (errno != ECONNREFUSED && errno != EAGAIN)
06955          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06956       handle_error();
06957       thread->iostate = IAX_IOSTATE_IDLE;
06958       signal_condition(&thread->lock, &thread->cond);
06959       return 1;
06960    }
06961    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06962       thread->iostate = IAX_IOSTATE_IDLE;
06963       signal_condition(&thread->lock, &thread->cond);
06964       return 1;
06965    }
06966    
06967    /* Determine if this frame is a full frame; if so, and any thread is currently
06968       processing a full frame for the same callno from this peer, then drop this
06969       frame (and the peer will retransmit it) */
06970    fh = (struct ast_iax2_full_hdr *) thread->buf;
06971    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06972       struct iax2_thread *cur = NULL;
06973       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06974       
06975       AST_LIST_LOCK(&active_list);
06976       AST_LIST_TRAVERSE(&active_list, cur, list) {
06977          if ((cur->ffinfo.callno == callno) &&
06978              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06979             break;
06980       }
06981       if (cur) {
06982          /* we found another thread processing a full frame for this call,
06983             so queue it up for processing later. */
06984          defer_full_frame(thread, cur);
06985          AST_LIST_UNLOCK(&active_list);
06986          thread->iostate = IAX_IOSTATE_IDLE;
06987          signal_condition(&thread->lock, &thread->cond);
06988          return 1;
06989       } else {
06990          /* this thread is going to process this frame, so mark it */
06991          thread->ffinfo.callno = callno;
06992          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06993          thread->ffinfo.type = fh->type;
06994          thread->ffinfo.csub = fh->csub;
06995       }
06996       AST_LIST_UNLOCK(&active_list);
06997    }
06998    
06999    /* Mark as ready and send on its way */
07000    thread->iostate = IAX_IOSTATE_READY;
07001 #ifdef DEBUG_SCHED_MULTITHREAD
07002    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07003 #endif
07004    signal_condition(&thread->lock, &thread->cond);
07005 
07006    return 1;
07007 }
07008 
07009 static int socket_process(struct iax2_thread *thread)
07010 {
07011    struct sockaddr_in sin;
07012    int res;
07013    int updatehistory=1;
07014    int new = NEW_PREVENT;
07015    void *ptr;
07016    int dcallno = 0;
07017    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07018    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07019    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07020    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07021    struct ast_iax2_meta_trunk_hdr *mth;
07022    struct ast_iax2_meta_trunk_entry *mte;
07023    struct ast_iax2_meta_trunk_mini *mtm;
07024    struct iax_frame *fr;
07025    struct iax_frame *cur;
07026    struct ast_frame f = { 0, };
07027    struct ast_channel *c;
07028    struct iax2_dpcache *dp;
07029    struct iax2_peer *peer;
07030    struct iax2_trunk_peer *tpeer;
07031    struct timeval rxtrunktime;
07032    struct iax_ies ies;
07033    struct iax_ie_data ied0, ied1;
07034    int format;
07035    int fd;
07036    int exists;
07037    int minivid = 0;
07038    unsigned int ts;
07039    char empty[32]="";      /* Safety measure */
07040    struct iax_frame *duped_fr;
07041    char host_pref_buf[128];
07042    char caller_pref_buf[128];
07043    struct ast_codec_pref pref;
07044    char *using_prefs = "mine";
07045 
07046    /* allocate an iax_frame with 4096 bytes of data buffer */
07047    fr = alloca(sizeof(*fr) + 4096);
07048    memset(fr, 0, sizeof(*fr));
07049    fr->afdatalen = 4096; /* From alloca() above */
07050 
07051    /* Copy frequently used parameters to the stack */
07052    res = thread->buf_len;
07053    fd = thread->iofd;
07054    memcpy(&sin, &thread->iosin, sizeof(sin));
07055 
07056    if (res < sizeof(*mh)) {
07057       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07058       return 1;
07059    }
07060    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07061       if (res < sizeof(*vh)) {
07062          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));
07063          return 1;
07064       }
07065 
07066       /* This is a video frame, get call number */
07067       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07068       minivid = 1;
07069    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07070       unsigned char metatype;
07071 
07072       if (res < sizeof(*meta)) {
07073          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));
07074          return 1;
07075       }
07076 
07077       /* This is a meta header */
07078       switch(meta->metacmd) {
07079       case IAX_META_TRUNK:
07080          if (res < (sizeof(*meta) + sizeof(*mth))) {
07081             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07082                sizeof(*meta) + sizeof(*mth));
07083             return 1;
07084          }
07085          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07086          ts = ntohl(mth->ts);
07087          metatype = meta->cmddata;
07088          res -= (sizeof(*meta) + sizeof(*mth));
07089          ptr = mth->data;
07090          tpeer = find_tpeer(&sin, fd);
07091          if (!tpeer) {
07092             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));
07093             return 1;
07094          }
07095          tpeer->trunkact = ast_tvnow();
07096          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07097             tpeer->rxtrunktime = tpeer->trunkact;
07098          rxtrunktime = tpeer->rxtrunktime;
07099          ast_mutex_unlock(&tpeer->lock);
07100          while(res >= sizeof(*mte)) {
07101             /* Process channels */
07102             unsigned short callno, trunked_ts, len;
07103 
07104             if (metatype == IAX_META_TRUNK_MINI) {
07105                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07106                ptr += sizeof(*mtm);
07107                res -= sizeof(*mtm);
07108                len = ntohs(mtm->len);
07109                callno = ntohs(mtm->mini.callno);
07110                trunked_ts = ntohs(mtm->mini.ts);
07111             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07112                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07113                ptr += sizeof(*mte);
07114                res -= sizeof(*mte);
07115                len = ntohs(mte->len);
07116                callno = ntohs(mte->callno);
07117                trunked_ts = 0;
07118             } else {
07119                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07120                break;
07121             }
07122             /* Stop if we don't have enough data */
07123             if (len > res)
07124                break;
07125             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07126             if (fr->callno) {
07127                /* If it's a valid call, deliver the contents.  If not, we
07128                   drop it, since we don't have a scallno to use for an INVAL */
07129                /* Process as a mini frame */
07130                memset(&f, 0, sizeof(f));
07131                f.frametype = AST_FRAME_VOICE;
07132                if (iaxs[fr->callno]) {
07133                   if (iaxs[fr->callno]->voiceformat > 0) {
07134                      f.subclass = iaxs[fr->callno]->voiceformat;
07135                      f.datalen = len;
07136                      if (f.datalen >= 0) {
07137                         if (f.datalen)
07138                            f.data = ptr;
07139                         if(trunked_ts) {
07140                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07141                         } else
07142                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07143                         /* Don't pass any packets until we're started */
07144                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07145                            /* Common things */
07146                            f.src = "IAX2";
07147                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07148                               f.samples = ast_codec_get_samples(&f);
07149                            iax_frame_wrap(fr, &f);
07150                            duped_fr = iaxfrdup2(fr);
07151                            if (duped_fr) {
07152                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07153                            }
07154                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07155                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07156                               iaxs[fr->callno]->last = fr->ts;
07157 #if 1
07158                               if (option_debug && iaxdebug)
07159                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07160 #endif
07161                            }
07162                         }
07163                      } else {
07164                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07165                      }
07166                   } else {
07167                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07168                      iax2_vnak(fr->callno);
07169                   }
07170                }
07171                ast_mutex_unlock(&iaxsl[fr->callno]);
07172             }
07173             ptr += len;
07174             res -= len;
07175          }
07176          
07177       }
07178       return 1;
07179    }
07180 
07181 #ifdef DEBUG_SUPPORT
07182    if (iaxdebug && (res >= sizeof(*fh)))
07183       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07184 #endif
07185    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07186       if (res < sizeof(*fh)) {
07187          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));
07188          return 1;
07189       }
07190 
07191       /* Get the destination call number */
07192       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07193       /* Retrieve the type and subclass */
07194       f.frametype = fh->type;
07195       if (f.frametype == AST_FRAME_VIDEO) {
07196          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07197       } else {
07198          f.subclass = uncompress_subclass(fh->csub);
07199       }
07200 
07201       /* Deal with POKE/PONG without allocating a callno */
07202       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07203          /* Reply back with a PONG, but don't care about the result. */
07204          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07205          return 1;
07206       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07207          /* Ignore */
07208          return 1;
07209       }
07210 
07211       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07212                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07213                          (f.subclass == IAX_COMMAND_REGREL)))
07214          new = NEW_ALLOW;
07215    } else {
07216       /* Don't know anything about it yet */
07217       f.frametype = AST_FRAME_NULL;
07218       f.subclass = 0;
07219    }
07220 
07221    if (!fr->callno) {
07222       int check_dcallno = 0;
07223 
07224       /*
07225        * We enforce accurate destination call numbers for all full frames except
07226        * LAGRQ and PING commands.  This is because older versions of Asterisk
07227        * schedule these commands to get sent very quickly, and they will sometimes
07228        * be sent before they receive the first frame from the other side.  When
07229        * that happens, it doesn't contain the destination call number.  However,
07230        * not checking it for these frames is safe.
07231        * 
07232        * Discussed in the following thread:
07233        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07234        */
07235 
07236       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07237          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07238       }
07239 
07240       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07241    }
07242 
07243    if (fr->callno > 0)
07244       ast_mutex_lock(&iaxsl[fr->callno]);
07245 
07246    if (!fr->callno || !iaxs[fr->callno]) {
07247       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07248          frame, reply with an inval */
07249       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07250          /* We can only raw hangup control frames */
07251          if (((f.subclass != IAX_COMMAND_INVAL) &&
07252              (f.subclass != IAX_COMMAND_TXCNT) &&
07253              (f.subclass != IAX_COMMAND_TXACC) &&
07254              (f.subclass != IAX_COMMAND_FWDOWNL))||
07255              (f.frametype != AST_FRAME_IAX))
07256             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07257             fd);
07258       }
07259       if (fr->callno > 0) 
07260          ast_mutex_unlock(&iaxsl[fr->callno]);
07261       return 1;
07262    }
07263    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07264       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07265          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07266          ast_mutex_unlock(&iaxsl[fr->callno]);
07267          return 1;
07268       }
07269 #ifdef DEBUG_SUPPORT
07270       else if (iaxdebug)
07271          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07272 #endif
07273    }
07274 
07275    /* count this frame */
07276    iaxs[fr->callno]->frames_received++;
07277 
07278    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07279       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07280       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07281       unsigned short new_peercallno;
07282 
07283       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07284       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07285          if (iaxs[fr->callno]->peercallno) {
07286             remove_by_peercallno(iaxs[fr->callno]);
07287          }
07288          iaxs[fr->callno]->peercallno = new_peercallno;
07289          store_by_peercallno(iaxs[fr->callno]);
07290       }
07291    }
07292    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07293       if (option_debug  && iaxdebug)
07294          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07295       /* Check if it's out of order (and not an ACK or INVAL) */
07296       fr->oseqno = fh->oseqno;
07297       fr->iseqno = fh->iseqno;
07298       fr->ts = ntohl(fh->ts);
07299 #ifdef IAXTESTS
07300       if (test_resync) {
07301          if (option_debug)
07302             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07303          fr->ts += test_resync;
07304       }
07305 #endif /* IAXTESTS */
07306 #if 0
07307       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07308            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07309                         (f.subclass == IAX_COMMAND_NEW ||
07310                          f.subclass == IAX_COMMAND_AUTHREQ ||
07311                          f.subclass == IAX_COMMAND_ACCEPT ||
07312                          f.subclass == IAX_COMMAND_REJECT))      ) )
07313 #endif
07314       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07315          updatehistory = 0;
07316       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07317          (iaxs[fr->callno]->iseqno ||
07318             ((f.subclass != IAX_COMMAND_TXCNT) &&
07319             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07320             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07321             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07322             (f.subclass != IAX_COMMAND_TXACC)) ||
07323             (f.frametype != AST_FRAME_IAX))) {
07324          if (
07325           ((f.subclass != IAX_COMMAND_ACK) &&
07326            (f.subclass != IAX_COMMAND_INVAL) &&
07327            (f.subclass != IAX_COMMAND_TXCNT) &&
07328            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07329            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07330            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07331            (f.subclass != IAX_COMMAND_TXACC) &&
07332            (f.subclass != IAX_COMMAND_VNAK)) ||
07333            (f.frametype != AST_FRAME_IAX)) {
07334             /* If it's not an ACK packet, it's out of order. */
07335             if (option_debug)
07336                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07337                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07338             /* Check to see if we need to request retransmission,
07339              * and take sequence number wraparound into account */
07340             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07341                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07342                if ((f.frametype != AST_FRAME_IAX) || 
07343                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07344                   if (option_debug)
07345                      ast_log(LOG_DEBUG, "Acking anyway\n");
07346                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07347                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07348                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07349                }
07350             } else {
07351                /* Send a VNAK requesting retransmission */
07352                iax2_vnak(fr->callno);
07353             }
07354             ast_mutex_unlock(&iaxsl[fr->callno]);
07355             return 1;
07356          }
07357       } else {
07358          /* Increment unless it's an ACK or VNAK */
07359          if (((f.subclass != IAX_COMMAND_ACK) &&
07360              (f.subclass != IAX_COMMAND_INVAL) &&
07361              (f.subclass != IAX_COMMAND_TXCNT) &&
07362              (f.subclass != IAX_COMMAND_TXACC) &&
07363             (f.subclass != IAX_COMMAND_VNAK)) ||
07364              (f.frametype != AST_FRAME_IAX))
07365             iaxs[fr->callno]->iseqno++;
07366       }
07367       /* A full frame */
07368       if (res < sizeof(*fh)) {
07369          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07370          ast_mutex_unlock(&iaxsl[fr->callno]);
07371          return 1;
07372       }
07373       /* Ensure text frames are NULL-terminated */
07374       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07375          if (res < thread->buf_size)
07376             thread->buf[res++] = '\0';
07377          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07378             thread->buf[res - 1] = '\0';
07379       }
07380       f.datalen = res - sizeof(*fh);
07381 
07382       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07383          from the real peer, not the transfer peer */
07384       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07385           ((f.subclass != IAX_COMMAND_INVAL) ||
07386            (f.frametype != AST_FRAME_IAX))) {
07387          unsigned char x;
07388          int call_to_destroy;
07389          /* XXX This code is not very efficient.  Surely there is a better way which still
07390                 properly handles boundary conditions? XXX */
07391          /* First we have to qualify that the ACKed value is within our window */
07392          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07393             if (fr->iseqno == x)
07394                break;
07395          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07396             /* The acknowledgement is within our window.  Time to acknowledge everything
07397                that it says to */
07398             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07399                /* Ack the packet with the given timestamp */
07400                if (option_debug && iaxdebug)
07401                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07402                call_to_destroy = 0;
07403                AST_LIST_LOCK(&iaxq.queue);
07404                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07405                   /* If it's our call, and our timestamp, mark -1 retries */
07406                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07407                      cur->retries = -1;
07408                      /* Destroy call if this is the end */
07409                      if (cur->final)
07410                         call_to_destroy = fr->callno;
07411                   }
07412                }
07413                AST_LIST_UNLOCK(&iaxq.queue);
07414                if (call_to_destroy) {
07415                   if (iaxdebug && option_debug)
07416                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07417                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07418                   iax2_destroy(call_to_destroy);
07419                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07420                }
07421             }
07422             /* Note how much we've received acknowledgement for */
07423             if (iaxs[fr->callno])
07424                iaxs[fr->callno]->rseqno = fr->iseqno;
07425             else {
07426                /* Stop processing now */
07427                ast_mutex_unlock(&iaxsl[fr->callno]);
07428                return 1;
07429             }
07430          } else if (option_debug)
07431             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07432       }
07433       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07434          ((f.frametype != AST_FRAME_IAX) || 
07435           ((f.subclass != IAX_COMMAND_TXACC) &&
07436            (f.subclass != IAX_COMMAND_TXCNT)))) {
07437          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07438          ast_mutex_unlock(&iaxsl[fr->callno]);
07439          return 1;
07440       }
07441 
07442       if (f.datalen) {
07443          if (f.frametype == AST_FRAME_IAX) {
07444             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07445                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07446                ast_mutex_unlock(&iaxsl[fr->callno]);
07447                return 1;
07448             }
07449             f.data = NULL;
07450             f.datalen = 0;
07451          } else
07452             f.data = thread->buf + sizeof(*fh);
07453       } else {
07454          if (f.frametype == AST_FRAME_IAX)
07455             f.data = NULL;
07456          else
07457             f.data = empty;
07458          memset(&ies, 0, sizeof(ies));
07459       }
07460 
07461       /* when we receive the first full frame for a new incoming channel,
07462          it is safe to start the PBX on the channel because we have now
07463          completed a 3-way handshake with the peer */
07464       if ((f.frametype == AST_FRAME_VOICE) ||
07465           (f.frametype == AST_FRAME_VIDEO) ||
07466           (f.frametype == AST_FRAME_IAX)) {
07467          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07468             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07469             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07470                ast_mutex_unlock(&iaxsl[fr->callno]);
07471                return 1;
07472             }
07473          }
07474       }
07475 
07476       if (f.frametype == AST_FRAME_VOICE) {
07477          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07478                iaxs[fr->callno]->voiceformat = f.subclass;
07479                if (option_debug)
07480                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07481                if (iaxs[fr->callno]->owner) {
07482                   int orignative;
07483 retryowner:
07484                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07485                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07486                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07487                   }
07488                   if (iaxs[fr->callno]) {
07489                      if (iaxs[fr->callno]->owner) {
07490                         orignative = iaxs[fr->callno]->owner->nativeformats;
07491                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07492                         if (iaxs[fr->callno]->owner->readformat)
07493                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07494                         iaxs[fr->callno]->owner->nativeformats = orignative;
07495                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07496                      }
07497                   } else {
07498                      if (option_debug)
07499                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07500                      ast_mutex_unlock(&iaxsl[fr->callno]);
07501                      return 1;
07502                   }
07503                }
07504          }
07505       }
07506       if (f.frametype == AST_FRAME_VIDEO) {
07507          if (f.subclass != iaxs[fr->callno]->videoformat) {
07508             if (option_debug)
07509                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07510             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07511          }
07512       }
07513       if (f.frametype == AST_FRAME_IAX) {
07514          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07515          /* Handle the IAX pseudo frame itself */
07516          if (option_debug && iaxdebug)
07517             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07518 
07519                         /* Update last ts unless the frame's timestamp originated with us. */
07520          if (iaxs[fr->callno]->last < fr->ts &&
07521                             f.subclass != IAX_COMMAND_ACK &&
07522                             f.subclass != IAX_COMMAND_PONG &&
07523                             f.subclass != IAX_COMMAND_LAGRP) {
07524             iaxs[fr->callno]->last = fr->ts;
07525             if (option_debug && iaxdebug)
07526                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07527          }
07528 
07529          switch(f.subclass) {
07530          case IAX_COMMAND_ACK:
07531             /* Do nothing */
07532             break;
07533          case IAX_COMMAND_QUELCH:
07534             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07535                     /* Generate Manager Hold event, if necessary*/
07536                if (iaxs[fr->callno]->owner) {
07537                   manager_event(EVENT_FLAG_CALL, "Hold",
07538                      "Channel: %s\r\n"
07539                      "Uniqueid: %s\r\n",
07540                      iaxs[fr->callno]->owner->name, 
07541                      iaxs[fr->callno]->owner->uniqueid);
07542                }
07543 
07544                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07545                if (ies.musiconhold) {
07546                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07547                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07548                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07549                         S_OR(mohsuggest, NULL),
07550                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07551                      if (!iaxs[fr->callno]) {
07552                         ast_mutex_unlock(&iaxsl[fr->callno]);
07553                         return 1;
07554                      }
07555                   }
07556                }
07557             }
07558             break;
07559          case IAX_COMMAND_UNQUELCH:
07560             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07561                     /* Generate Manager Unhold event, if necessary*/
07562                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07563                   manager_event(EVENT_FLAG_CALL, "Unhold",
07564                      "Channel: %s\r\n"
07565                      "Uniqueid: %s\r\n",
07566                      iaxs[fr->callno]->owner->name, 
07567                      iaxs[fr->callno]->owner->uniqueid);
07568                }
07569 
07570                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07571                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07572                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07573                   if (!iaxs[fr->callno]) {
07574                      ast_mutex_unlock(&iaxsl[fr->callno]);
07575                      return 1;
07576                   }
07577                }
07578             }
07579             break;
07580          case IAX_COMMAND_TXACC:
07581             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07582                /* Ack the packet with the given timestamp */
07583                AST_LIST_LOCK(&iaxq.queue);
07584                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07585                   /* Cancel any outstanding txcnt's */
07586                   if ((fr->callno == cur->callno) && (cur->transfer))
07587                      cur->retries = -1;
07588                }
07589                AST_LIST_UNLOCK(&iaxq.queue);
07590                memset(&ied1, 0, sizeof(ied1));
07591                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07592                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07593                iaxs[fr->callno]->transferring = TRANSFER_READY;
07594             }
07595             break;
07596          case IAX_COMMAND_NEW:
07597             /* Ignore if it's already up */
07598             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07599                break;
07600             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07601                ast_mutex_unlock(&iaxsl[fr->callno]);
07602                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07603                ast_mutex_lock(&iaxsl[fr->callno]);
07604                if (!iaxs[fr->callno]) {
07605                   ast_mutex_unlock(&iaxsl[fr->callno]);
07606                   return 1;
07607                }
07608             }
07609             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07610             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07611                int new_callno;
07612                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07613                   fr->callno = new_callno;
07614             }
07615             /* For security, always ack immediately */
07616             if (delayreject)
07617                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07618             if (check_access(fr->callno, &sin, &ies)) {
07619                /* They're not allowed on */
07620                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07621                if (authdebug)
07622                   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);
07623                break;
07624             }
07625             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07626                const char *context, *exten, *cid_num;
07627 
07628                context = ast_strdupa(iaxs[fr->callno]->context);
07629                exten = ast_strdupa(iaxs[fr->callno]->exten);
07630                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07631 
07632                /* This might re-enter the IAX code and need the lock */
07633                ast_mutex_unlock(&iaxsl[fr->callno]);
07634                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07635                ast_mutex_lock(&iaxsl[fr->callno]);
07636 
07637                if (!iaxs[fr->callno]) {
07638                   ast_mutex_unlock(&iaxsl[fr->callno]);
07639                   return 1;
07640                }
07641             } else
07642                exists = 0;
07643             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07644                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07645                   memset(&ied0, 0, sizeof(ied0));
07646                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07647                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07648                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07649                   if (!iaxs[fr->callno]) {
07650                      ast_mutex_unlock(&iaxsl[fr->callno]);
07651                      return 1;
07652                   }
07653                   if (authdebug)
07654                      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);
07655                } else {
07656                   /* Select an appropriate format */
07657 
07658                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07659                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07660                         using_prefs = "reqonly";
07661                      } else {
07662                         using_prefs = "disabled";
07663                      }
07664                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07665                      memset(&pref, 0, sizeof(pref));
07666                      strcpy(caller_pref_buf, "disabled");
07667                      strcpy(host_pref_buf, "disabled");
07668                   } else {
07669                      using_prefs = "mine";
07670                      /* If the information elements are in here... use them */
07671                      if (ies.codec_prefs)
07672                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07673                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07674                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07675                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07676                            pref = iaxs[fr->callno]->rprefs;
07677                            using_prefs = "caller";
07678                         } else {
07679                            pref = iaxs[fr->callno]->prefs;
07680                         }
07681                      } else
07682                         pref = iaxs[fr->callno]->prefs;
07683                      
07684                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07685                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07686                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07687                   }
07688                   if (!format) {
07689                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07690                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07691                      if (!format) {
07692                         memset(&ied0, 0, sizeof(ied0));
07693                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07694                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07695                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07696                         if (!iaxs[fr->callno]) {
07697                            ast_mutex_unlock(&iaxsl[fr->callno]);
07698                            return 1;
07699                         }
07700                         if (authdebug) {
07701                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07702                               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);
07703                            else 
07704                               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);
07705                         }
07706                      } else {
07707                         /* Pick one... */
07708                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07709                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07710                               format = 0;
07711                         } else {
07712                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07713                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07714                               memset(&pref, 0, sizeof(pref));
07715                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07716                               strcpy(caller_pref_buf,"disabled");
07717                               strcpy(host_pref_buf,"disabled");
07718                            } else {
07719                               using_prefs = "mine";
07720                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07721                                  /* Do the opposite of what we tried above. */
07722                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07723                                     pref = iaxs[fr->callno]->prefs;                       
07724                                  } else {
07725                                     pref = iaxs[fr->callno]->rprefs;
07726                                     using_prefs = "caller";
07727                                  }
07728                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07729                            
07730                               } else /* if no codec_prefs IE do it the old way */
07731                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07732                            }
07733                         }
07734 
07735                         if (!format) {
07736                            memset(&ied0, 0, sizeof(ied0));
07737                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07738                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07739                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07740                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07741                            if (!iaxs[fr->callno]) {
07742                               ast_mutex_unlock(&iaxsl[fr->callno]);
07743                               return 1;
07744                            }
07745                            if (authdebug)
07746                               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);
07747                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07748                            break;
07749                         }
07750                      }
07751                   }
07752                   if (format) {
07753                      /* No authentication required, let them in */
07754                      memset(&ied1, 0, sizeof(ied1));
07755                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07756                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07757                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07758                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07759                         if (option_verbose > 2) 
07760                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07761                                     "%srequested format = %s,\n"
07762                                     "%srequested prefs = %s,\n"
07763                                     "%sactual format = %s,\n"
07764                                     "%shost prefs = %s,\n"
07765                                     "%spriority = %s\n",
07766                                     ast_inet_ntoa(sin.sin_addr), 
07767                                     VERBOSE_PREFIX_4,
07768                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07769                                     VERBOSE_PREFIX_4,
07770                                     caller_pref_buf,
07771                                     VERBOSE_PREFIX_4,
07772                                     ast_getformatname(format), 
07773                                     VERBOSE_PREFIX_4,
07774                                     host_pref_buf, 
07775                                     VERBOSE_PREFIX_4,
07776                                     using_prefs);
07777                         
07778                         iaxs[fr->callno]->chosenformat = format;
07779                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07780                      } else {
07781                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07782                         /* If this is a TBD call, we're ready but now what...  */
07783                         if (option_verbose > 2)
07784                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07785                      }
07786                   }
07787                }
07788                break;
07789             }
07790             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07791                merge_encryption(iaxs[fr->callno],ies.encmethods);
07792             else
07793                iaxs[fr->callno]->encmethods = 0;
07794             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07795                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07796             if (!iaxs[fr->callno]) {
07797                ast_mutex_unlock(&iaxsl[fr->callno]);
07798                return 1;
07799             }
07800             break;
07801          case IAX_COMMAND_DPREQ:
07802             /* Request status in the dialplan */
07803             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07804                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07805                if (iaxcompat) {
07806                   /* Spawn a thread for the lookup */
07807                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07808                } else {
07809                   /* Just look it up */
07810                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07811                }
07812             }
07813             break;
07814          case IAX_COMMAND_HANGUP:
07815             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07816             if (option_debug)
07817                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07818             /* Set hangup cause according to remote */
07819             if (ies.causecode && iaxs[fr->callno]->owner)
07820                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07821             /* Send ack immediately, before we destroy */
07822             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07823             iax2_destroy(fr->callno);
07824             break;
07825          case IAX_COMMAND_REJECT:
07826             /* Set hangup cause according to remote */
07827             if (ies.causecode && iaxs[fr->callno]->owner)
07828                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07829 
07830             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07831                if (iaxs[fr->callno]->owner && authdebug)
07832                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07833                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07834                      ies.cause ? ies.cause : "<Unknown>");
07835                if (option_debug)
07836                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07837                      fr->callno);
07838             }
07839             /* Send ack immediately, before we destroy */
07840             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07841                          fr->ts, NULL, 0, fr->iseqno);
07842             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07843                iaxs[fr->callno]->error = EPERM;
07844             iax2_destroy(fr->callno);
07845             break;
07846          case IAX_COMMAND_TRANSFER:
07847          {
07848             struct ast_channel *bridged_chan;
07849 
07850             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07851                /* Set BLINDTRANSFER channel variables */
07852 
07853                ast_mutex_unlock(&iaxsl[fr->callno]);
07854                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07855                ast_mutex_lock(&iaxsl[fr->callno]);
07856                if (!iaxs[fr->callno]) {
07857                   ast_mutex_unlock(&iaxsl[fr->callno]);
07858                   return 1;
07859                }
07860 
07861                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07862                if (!strcmp(ies.called_number, ast_parking_ext())) {
07863                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07864                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07865                   } else {
07866                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07867                   }
07868                } else {
07869                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07870                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07871                         ies.called_number, iaxs[fr->callno]->context);
07872                   else
07873                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07874                         ies.called_number, iaxs[fr->callno]->context);
07875                }
07876             } else
07877                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07878 
07879             break;
07880          }
07881          case IAX_COMMAND_ACCEPT:
07882             /* Ignore if call is already up or needs authentication or is a TBD */
07883             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07884                break;
07885             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07886                /* Send ack immediately, before we destroy */
07887                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07888                iax2_destroy(fr->callno);
07889                break;
07890             }
07891             if (ies.format) {
07892                iaxs[fr->callno]->peerformat = ies.format;
07893             } else {
07894                if (iaxs[fr->callno]->owner)
07895                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07896                else
07897                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07898             }
07899             if (option_verbose > 2)
07900                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));
07901             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07902                memset(&ied0, 0, sizeof(ied0));
07903                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07904                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07905                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07906                if (!iaxs[fr->callno]) {
07907                   ast_mutex_unlock(&iaxsl[fr->callno]);
07908                   return 1;
07909                }
07910                if (authdebug)
07911                   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);
07912             } else {
07913                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07914                if (iaxs[fr->callno]->owner) {
07915                   /* Switch us to use a compatible format */
07916                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07917                   if (option_verbose > 2)
07918                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07919 retryowner2:
07920                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07921                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07922                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07923                   }
07924                   
07925                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07926                      /* Setup read/write formats properly. */
07927                      if (iaxs[fr->callno]->owner->writeformat)
07928                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07929                      if (iaxs[fr->callno]->owner->readformat)
07930                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07931                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07932                   }
07933                }
07934             }
07935             if (iaxs[fr->callno]) {
07936                ast_mutex_lock(&dpcache_lock);
07937                dp = iaxs[fr->callno]->dpentries;
07938                while(dp) {
07939                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07940                      iax2_dprequest(dp, fr->callno);
07941                   }
07942                   dp = dp->peer;
07943                }
07944                ast_mutex_unlock(&dpcache_lock);
07945             }
07946             break;
07947          case IAX_COMMAND_POKE:
07948             /* Send back a pong packet with the original timestamp */
07949             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07950             if (!iaxs[fr->callno]) {
07951                ast_mutex_unlock(&iaxsl[fr->callno]);
07952                return 1;
07953             }
07954             break;
07955          case IAX_COMMAND_PING:
07956          {
07957             struct iax_ie_data pingied;
07958             construct_rr(iaxs[fr->callno], &pingied);
07959             /* Send back a pong packet with the original timestamp */
07960             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07961          }
07962             break;
07963          case IAX_COMMAND_PONG:
07964             /* Calculate ping time */
07965             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07966             /* save RR info */
07967             save_rr(fr, &ies);
07968 
07969             if (iaxs[fr->callno]->peerpoke) {
07970                peer = iaxs[fr->callno]->peerpoke;
07971                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07972                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07973                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07974                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07975                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07976                   }
07977                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07978                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07979                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07980                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07981                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07982                   }
07983                }
07984                peer->lastms = iaxs[fr->callno]->pingtime;
07985                if (peer->smoothing && (peer->lastms > -1))
07986                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07987                else if (peer->smoothing && peer->lastms < 0)
07988                   peer->historicms = (0 + peer->historicms) / 2;
07989                else              
07990                   peer->historicms = iaxs[fr->callno]->pingtime;
07991 
07992                /* Remove scheduled iax2_poke_noanswer */
07993                if (peer->pokeexpire > -1) {
07994                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07995                      peer_unref(peer);
07996                      peer->pokeexpire = -1;
07997                   }
07998                }
07999                /* Schedule the next cycle */
08000                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
08001                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08002                else
08003                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08004                if (peer->pokeexpire == -1)
08005                   peer_unref(peer);
08006                /* and finally send the ack */
08007                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08008                /* And wrap up the qualify call */
08009                iax2_destroy(fr->callno);
08010                peer->callno = 0;
08011                if (option_debug)
08012                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08013             }
08014             break;
08015          case IAX_COMMAND_LAGRQ:
08016          case IAX_COMMAND_LAGRP:
08017             f.src = "LAGRQ";
08018             f.mallocd = 0;
08019             f.offset = 0;
08020             f.samples = 0;
08021             iax_frame_wrap(fr, &f);
08022             if(f.subclass == IAX_COMMAND_LAGRQ) {
08023                /* Received a LAGRQ - echo back a LAGRP */
08024                fr->af.subclass = IAX_COMMAND_LAGRP;
08025                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08026             } else {
08027                /* Received LAGRP in response to our LAGRQ */
08028                unsigned int ts;
08029                /* This is a reply we've been given, actually measure the difference */
08030                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08031                iaxs[fr->callno]->lag = ts - fr->ts;
08032                if (option_debug && iaxdebug)
08033                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08034                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08035             }
08036             break;
08037          case IAX_COMMAND_AUTHREQ:
08038             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08039                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>");
08040                break;
08041             }
08042             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08043                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08044                         .subclass = AST_CONTROL_HANGUP,
08045                };
08046                ast_log(LOG_WARNING, 
08047                   "I don't know how to authenticate %s to %s\n", 
08048                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08049                iax2_queue_frame(fr->callno, &hangup_fr);
08050             }
08051             if (!iaxs[fr->callno]) {
08052                ast_mutex_unlock(&iaxsl[fr->callno]);
08053                return 1;
08054             }
08055             break;
08056          case IAX_COMMAND_AUTHREP:
08057             /* For security, always ack immediately */
08058             if (delayreject)
08059                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08060             /* Ignore once we've started */
08061             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08062                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>");
08063                break;
08064             }
08065             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08066                if (authdebug)
08067                   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);
08068                memset(&ied0, 0, sizeof(ied0));
08069                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08070                break;
08071             }
08072             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08073                /* This might re-enter the IAX code and need the lock */
08074                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08075             } else
08076                exists = 0;
08077             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08078                if (authdebug)
08079                   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);
08080                memset(&ied0, 0, sizeof(ied0));
08081                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08082                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08083                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08084                if (!iaxs[fr->callno]) {
08085                   ast_mutex_unlock(&iaxsl[fr->callno]);
08086                   return 1;
08087                }
08088             } else {
08089                /* Select an appropriate format */
08090                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08091                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08092                      using_prefs = "reqonly";
08093                   } else {
08094                      using_prefs = "disabled";
08095                   }
08096                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08097                   memset(&pref, 0, sizeof(pref));
08098                   strcpy(caller_pref_buf, "disabled");
08099                   strcpy(host_pref_buf, "disabled");
08100                } else {
08101                   using_prefs = "mine";
08102                   if (ies.codec_prefs)
08103                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08104                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08105                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08106                         pref = iaxs[fr->callno]->rprefs;
08107                         using_prefs = "caller";
08108                      } else {
08109                         pref = iaxs[fr->callno]->prefs;
08110                      }
08111                   } else /* if no codec_prefs IE do it the old way */
08112                      pref = iaxs[fr->callno]->prefs;
08113                
08114                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08115                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08116                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08117                }
08118                if (!format) {
08119                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08120                      if (option_debug)
08121                         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);
08122                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08123                   }
08124                   if (!format) {
08125                      if (authdebug) {
08126                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08127                            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);
08128                         else
08129                            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);
08130                      }
08131                      memset(&ied0, 0, sizeof(ied0));
08132                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08133                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08134                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08135                      if (!iaxs[fr->callno]) {
08136                         ast_mutex_unlock(&iaxsl[fr->callno]);
08137                         return 1;
08138                      }
08139                   } else {
08140                      /* Pick one... */
08141                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08142                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08143                            format = 0;
08144                      } else {
08145                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08146                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08147                            memset(&pref, 0, sizeof(pref));
08148                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08149                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08150                            strcpy(caller_pref_buf,"disabled");
08151                            strcpy(host_pref_buf,"disabled");
08152                         } else {
08153                            using_prefs = "mine";
08154                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08155                               /* Do the opposite of what we tried above. */
08156                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08157                                  pref = iaxs[fr->callno]->prefs;                 
08158                               } else {
08159                                  pref = iaxs[fr->callno]->rprefs;
08160                                  using_prefs = "caller";
08161                               }
08162                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08163                            } else /* if no codec_prefs IE do it the old way */
08164                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08165                         }
08166                      }
08167                      if (!format) {
08168                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08169                         if (authdebug) {
08170                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08171                               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);
08172                            else
08173                               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);
08174                         }
08175                         memset(&ied0, 0, sizeof(ied0));
08176                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08177                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08178                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08179                         if (!iaxs[fr->callno]) {
08180                            ast_mutex_unlock(&iaxsl[fr->callno]);
08181                            return 1;
08182                         }
08183                      }
08184                   }
08185                }
08186                if (format) {
08187                   /* Authentication received */
08188                   memset(&ied1, 0, sizeof(ied1));
08189                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08190                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08191                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08192                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08193                      if (option_verbose > 2) 
08194                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08195                                  "%srequested format = %s,\n"
08196                                  "%srequested prefs = %s,\n"
08197                                  "%sactual format = %s,\n"
08198                                  "%shost prefs = %s,\n"
08199                                  "%spriority = %s\n", 
08200                                  ast_inet_ntoa(sin.sin_addr), 
08201                                  VERBOSE_PREFIX_4,
08202                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08203                                  VERBOSE_PREFIX_4,
08204                                  caller_pref_buf,
08205                                  VERBOSE_PREFIX_4,
08206                                  ast_getformatname(format),
08207                                  VERBOSE_PREFIX_4,
08208                                  host_pref_buf,
08209                                  VERBOSE_PREFIX_4,
08210                                  using_prefs);
08211 
08212                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08213                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08214                         iax2_destroy(fr->callno);
08215                   } else {
08216                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08217                      /* If this is a TBD call, we're ready but now what...  */
08218                      if (option_verbose > 2)
08219                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08220                   }
08221                }
08222             }
08223             break;
08224          case IAX_COMMAND_DIAL:
08225             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08226                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08227                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08228                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08229                   if (authdebug)
08230                      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);
08231                   memset(&ied0, 0, sizeof(ied0));
08232                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08233                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08234                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08235                   if (!iaxs[fr->callno]) {
08236                      ast_mutex_unlock(&iaxsl[fr->callno]);
08237                      return 1;
08238                   }
08239                } else {
08240                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08241                   if (option_verbose > 2) 
08242                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08243                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08244                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08245                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08246                      iax2_destroy(fr->callno);
08247                }
08248             }
08249             break;
08250          case IAX_COMMAND_INVAL:
08251             iaxs[fr->callno]->error = ENOTCONN;
08252             if (option_debug)
08253                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08254             iax2_destroy(fr->callno);
08255             if (option_debug)
08256                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08257             break;
08258          case IAX_COMMAND_VNAK:
08259             if (option_debug)
08260                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08261             /* Force retransmission */
08262             vnak_retransmit(fr->callno, fr->iseqno);
08263             break;
08264          case IAX_COMMAND_REGREQ:
08265          case IAX_COMMAND_REGREL:
08266             /* For security, always ack immediately */
08267             if (delayreject)
08268                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08269             if (register_verify(fr->callno, &sin, &ies)) {
08270                if (!iaxs[fr->callno]) {
08271                   ast_mutex_unlock(&iaxsl[fr->callno]);
08272                   return 1;
08273                }
08274                /* Send delayed failure */
08275                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08276                break;
08277             }
08278             if (!iaxs[fr->callno]) {
08279                ast_mutex_unlock(&iaxsl[fr->callno]);
08280                return 1;
08281             }
08282             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08283                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
08284 
08285                if (f.subclass == IAX_COMMAND_REGREL)
08286                   memset(&sin, 0, sizeof(sin));
08287                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08288                   ast_log(LOG_WARNING, "Registry error\n");
08289                if (!iaxs[fr->callno]) {
08290                   ast_mutex_unlock(&iaxsl[fr->callno]);
08291                   return 1;
08292                }
08293                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08294                   ast_mutex_unlock(&iaxsl[fr->callno]);
08295                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08296                   ast_mutex_lock(&iaxsl[fr->callno]);
08297                   if (!iaxs[fr->callno]) {
08298                      ast_mutex_unlock(&iaxsl[fr->callno]);
08299                      return 1;
08300                   }
08301                }
08302                break;
08303             }
08304             registry_authrequest(fr->callno);
08305             if (!iaxs[fr->callno]) {
08306                ast_mutex_unlock(&iaxsl[fr->callno]);
08307                return 1;
08308             }
08309             break;
08310          case IAX_COMMAND_REGACK:
08311             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08312                ast_log(LOG_WARNING, "Registration failure\n");
08313             /* Send ack immediately, before we destroy */
08314             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08315             iax2_destroy(fr->callno);
08316             break;
08317          case IAX_COMMAND_REGREJ:
08318             if (iaxs[fr->callno]->reg) {
08319                if (authdebug) {
08320                   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));
08321                   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>");
08322                }
08323                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08324             }
08325             /* Send ack immediately, before we destroy */
08326             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08327             iax2_destroy(fr->callno);
08328             break;
08329          case IAX_COMMAND_REGAUTH:
08330             /* Authentication request */
08331             if (registry_rerequest(&ies, fr->callno, &sin)) {
08332                memset(&ied0, 0, sizeof(ied0));
08333                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08334                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08335                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08336                if (!iaxs[fr->callno]) {
08337                   ast_mutex_unlock(&iaxsl[fr->callno]);
08338                   return 1;
08339                }
08340             }
08341             break;
08342          case IAX_COMMAND_TXREJ:
08343             iaxs[fr->callno]->transferring = 0;
08344             if (option_verbose > 2) 
08345                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08346             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08347             if (iaxs[fr->callno]->bridgecallno) {
08348                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08349                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08350                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08351                }
08352             }
08353             break;
08354          case IAX_COMMAND_TXREADY:
08355             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08356                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08357                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08358                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08359                else
08360                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08361                if (option_verbose > 2) 
08362                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08363                if (iaxs[fr->callno]->bridgecallno) {
08364                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08365                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08366                      /* They're both ready, now release them. */
08367                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08368                         if (option_verbose > 2) 
08369                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08370                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08371 
08372                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08373                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08374 
08375                         memset(&ied0, 0, sizeof(ied0));
08376                         memset(&ied1, 0, sizeof(ied1));
08377                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08378                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08379                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08380                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08381                      } else {
08382                         if (option_verbose > 2) 
08383                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08384                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08385 
08386                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08387                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08388                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08389                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08390 
08391                         /* Stop doing lag & ping requests */
08392                         stop_stuff(fr->callno);
08393                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08394 
08395                         memset(&ied0, 0, sizeof(ied0));
08396                         memset(&ied1, 0, sizeof(ied1));
08397                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08398                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08399                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08400                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08401                      }
08402 
08403                   }
08404                }
08405             }
08406             break;
08407          case IAX_COMMAND_TXREQ:
08408             try_transfer(iaxs[fr->callno], &ies);
08409             break;
08410          case IAX_COMMAND_TXCNT:
08411             if (iaxs[fr->callno]->transferring)
08412                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08413             break;
08414          case IAX_COMMAND_TXREL:
08415             /* Send ack immediately, rather than waiting until we've changed addresses */
08416             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08417             complete_transfer(fr->callno, &ies);
08418             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08419             break;   
08420          case IAX_COMMAND_TXMEDIA:
08421             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08422                                         AST_LIST_LOCK(&iaxq.queue);
08423                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08424                                                 /* Cancel any outstanding frames and start anew */
08425                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08426                                                         cur->retries = -1;
08427                                                 }
08428                                         }
08429                                         AST_LIST_UNLOCK(&iaxq.queue);
08430                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08431                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08432             }
08433             break;   
08434          case IAX_COMMAND_DPREP:
08435             complete_dpreply(iaxs[fr->callno], &ies);
08436             break;
08437          case IAX_COMMAND_UNSUPPORT:
08438             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08439             break;
08440          case IAX_COMMAND_FWDOWNL:
08441             /* Firmware download */
08442             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08443                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08444                break;
08445             }
08446             memset(&ied0, 0, sizeof(ied0));
08447             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08448             if (res < 0)
08449                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08450             else if (res > 0)
08451                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08452             else
08453                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08454             if (!iaxs[fr->callno]) {
08455                ast_mutex_unlock(&iaxsl[fr->callno]);
08456                return 1;
08457             }
08458             break;
08459          default:
08460             if (option_debug)
08461                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08462             memset(&ied0, 0, sizeof(ied0));
08463             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08464             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08465          }
08466          /* Don't actually pass these frames along */
08467          if ((f.subclass != IAX_COMMAND_ACK) && 
08468            (f.subclass != IAX_COMMAND_TXCNT) && 
08469            (f.subclass != IAX_COMMAND_TXACC) && 
08470            (f.subclass != IAX_COMMAND_INVAL) &&
08471            (f.subclass != IAX_COMMAND_VNAK)) { 
08472             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08473                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08474          }
08475          ast_mutex_unlock(&iaxsl[fr->callno]);
08476          return 1;
08477       }
08478       /* Unless this is an ACK or INVAL frame, ack it */
08479       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08480          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08481    } else if (minivid) {
08482       f.frametype = AST_FRAME_VIDEO;
08483       if (iaxs[fr->callno]->videoformat > 0) 
08484          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08485       else {
08486          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08487          iax2_vnak(fr->callno);
08488          ast_mutex_unlock(&iaxsl[fr->callno]);
08489          return 1;
08490       }
08491       f.datalen = res - sizeof(*vh);
08492       if (f.datalen)
08493          f.data = thread->buf + sizeof(*vh);
08494       else
08495          f.data = NULL;
08496 #ifdef IAXTESTS
08497       if (test_resync) {
08498          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08499       } else
08500 #endif /* IAXTESTS */
08501          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08502    } else {
08503       /* A mini frame */
08504       f.frametype = AST_FRAME_VOICE;
08505       if (iaxs[fr->callno]->voiceformat > 0)
08506          f.subclass = iaxs[fr->callno]->voiceformat;
08507       else {
08508          if (option_debug)
08509             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08510          iax2_vnak(fr->callno);
08511          ast_mutex_unlock(&iaxsl[fr->callno]);
08512          return 1;
08513       }
08514       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08515       if (f.datalen < 0) {
08516          ast_log(LOG_WARNING, "Datalen < 0?\n");
08517          ast_mutex_unlock(&iaxsl[fr->callno]);
08518          return 1;
08519       }
08520       if (f.datalen)
08521          f.data = thread->buf + sizeof(*mh);
08522       else
08523          f.data = NULL;
08524 #ifdef IAXTESTS
08525       if (test_resync) {
08526          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08527       } else
08528 #endif /* IAXTESTS */
08529       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08530       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08531    }
08532    /* Don't pass any packets until we're started */
08533    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08534       ast_mutex_unlock(&iaxsl[fr->callno]);
08535       return 1;
08536    }
08537    /* Common things */
08538    f.src = "IAX2";
08539    f.mallocd = 0;
08540    f.offset = 0;
08541    f.len = 0;
08542    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08543       f.samples = ast_codec_get_samples(&f);
08544       /* We need to byteswap incoming slinear samples from network byte order */
08545       if (f.subclass == AST_FORMAT_SLINEAR)
08546          ast_frame_byteswap_be(&f);
08547    } else
08548       f.samples = 0;
08549    iax_frame_wrap(fr, &f);
08550 
08551    /* If this is our most recent packet, use it as our basis for timestamping */
08552    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08553       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08554       fr->outoforder = 0;
08555    } else {
08556       if (option_debug && iaxdebug && iaxs[fr->callno])
08557          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);
08558       fr->outoforder = -1;
08559    }
08560    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08561    duped_fr = iaxfrdup2(fr);
08562    if (duped_fr) {
08563       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08564    }
08565    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08566       iaxs[fr->callno]->last = fr->ts;
08567 #if 1
08568       if (option_debug && iaxdebug)
08569          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08570 #endif
08571    }
08572 
08573    /* Always run again */
08574    ast_mutex_unlock(&iaxsl[fr->callno]);
08575    return 1;
08576 }
08577 
08578 /* Function to clean up process thread if it is cancelled */
08579 static void iax2_process_thread_cleanup(void *data)
08580 {
08581    struct iax2_thread *thread = data;
08582    ast_mutex_destroy(&thread->lock);
08583    ast_cond_destroy(&thread->cond);
08584    free(thread);
08585    ast_atomic_dec_and_test(&iaxactivethreadcount);
08586 }
08587 
08588 static void *iax2_process_thread(void *data)
08589 {
08590    struct iax2_thread *thread = data;
08591    struct timeval tv;
08592    struct timespec ts;
08593    int put_into_idle = 0;
08594 
08595    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08596    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08597    for(;;) {
08598       /* Wait for something to signal us to be awake */
08599       ast_mutex_lock(&thread->lock);
08600 
08601       /* Flag that we're ready to accept signals */
08602       thread->ready_for_signal = 1;
08603       
08604       /* Put into idle list if applicable */
08605       if (put_into_idle)
08606          insert_idle_thread(thread);
08607 
08608       if (thread->type == IAX_TYPE_DYNAMIC) {
08609          struct iax2_thread *t = NULL;
08610          /* Wait to be signalled or time out */
08611          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08612          ts.tv_sec = tv.tv_sec;
08613          ts.tv_nsec = tv.tv_usec * 1000;
08614          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08615             /* This thread was never put back into the available dynamic
08616              * thread list, so just go away. */
08617             if (!put_into_idle) {
08618                ast_mutex_unlock(&thread->lock);
08619                break;
08620             }
08621             AST_LIST_LOCK(&dynamic_list);
08622             /* Account for the case where this thread is acquired *right* after a timeout */
08623             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08624                iaxdynamicthreadcount--;
08625             AST_LIST_UNLOCK(&dynamic_list);
08626             if (t) {
08627                /* This dynamic thread timed out waiting for a task and was
08628                 * not acquired immediately after the timeout, 
08629                 * so it's time to go away. */
08630                ast_mutex_unlock(&thread->lock);
08631                break;
08632             }
08633             /* Someone grabbed our thread *right* after we timed out.
08634              * Wait for them to set us up with something to do and signal
08635              * us to continue. */
08636             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08637             ts.tv_sec = tv.tv_sec;
08638             ts.tv_nsec = tv.tv_usec * 1000;
08639             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08640             {
08641                ast_mutex_unlock(&thread->lock);
08642                break;
08643             }
08644          }
08645       } else {
08646          ast_cond_wait(&thread->cond, &thread->lock);
08647       }
08648 
08649       /* Go back into our respective list */
08650       put_into_idle = 1;
08651 
08652       ast_mutex_unlock(&thread->lock);
08653 
08654       if (thread->iostate == IAX_IOSTATE_IDLE)
08655          continue;
08656 
08657       /* Add ourselves to the active list now */
08658       AST_LIST_LOCK(&active_list);
08659       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08660       AST_LIST_UNLOCK(&active_list);
08661 
08662       /* See what we need to do */
08663       switch(thread->iostate) {
08664       case IAX_IOSTATE_READY:
08665          thread->actions++;
08666          thread->iostate = IAX_IOSTATE_PROCESSING;
08667          socket_process(thread);
08668          handle_deferred_full_frames(thread);
08669          break;
08670       case IAX_IOSTATE_SCHEDREADY:
08671          thread->actions++;
08672          thread->iostate = IAX_IOSTATE_PROCESSING;
08673 #ifdef SCHED_MULTITHREADED
08674          thread->schedfunc(thread->scheddata);
08675 #endif      
08676          break;
08677       }
08678       time(&thread->checktime);
08679       thread->iostate = IAX_IOSTATE_IDLE;
08680 #ifdef DEBUG_SCHED_MULTITHREAD
08681       thread->curfunc[0]='\0';
08682 #endif      
08683 
08684       /* Now... remove ourselves from the active list, and return to the idle list */
08685       AST_LIST_LOCK(&active_list);
08686       AST_LIST_REMOVE(&active_list, thread, list);
08687       AST_LIST_UNLOCK(&active_list);
08688 
08689       /* Make sure another frame didn't sneak in there after we thought we were done. */
08690       handle_deferred_full_frames(thread);
08691    }
08692 
08693    /*!\note For some reason, idle threads are exiting without being removed
08694     * from an idle list, which is causing memory corruption.  Forcibly remove
08695     * it from the list, if it's there.
08696     */
08697    AST_LIST_LOCK(&idle_list);
08698    AST_LIST_REMOVE(&idle_list, thread, list);
08699    AST_LIST_UNLOCK(&idle_list);
08700 
08701    AST_LIST_LOCK(&dynamic_list);
08702    AST_LIST_REMOVE(&dynamic_list, thread, list);
08703    AST_LIST_UNLOCK(&dynamic_list);
08704 
08705    /* I am exiting here on my own volition, I need to clean up my own data structures
08706    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08707    */
08708    pthread_cleanup_pop(1);
08709 
08710    return NULL;
08711 }
08712 
08713 static int iax2_do_register(struct iax2_registry *reg)
08714 {
08715    struct iax_ie_data ied;
08716    if (option_debug && iaxdebug)
08717       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08718 
08719    if (reg->dnsmgr && 
08720        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08721       /* Maybe the IP has changed, force DNS refresh */
08722       ast_dnsmgr_refresh(reg->dnsmgr);
08723    }
08724    
08725    /*
08726     * if IP has Changed, free allocated call to create a new one with new IP
08727     * call has the pointer to IP and must be updated to the new one
08728     */
08729    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08730       ast_mutex_lock(&iaxsl[reg->callno]);
08731       iax2_destroy(reg->callno);
08732       ast_mutex_unlock(&iaxsl[reg->callno]);
08733       reg->callno = 0;
08734    }
08735    if (!reg->addr.sin_addr.s_addr) {
08736       if (option_debug && iaxdebug)
08737          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08738       /* Setup the next registration attempt */
08739       AST_SCHED_DEL(sched, reg->expire);
08740       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08741       return -1;
08742    }
08743 
08744    if (!reg->callno) {
08745       if (option_debug)
08746          ast_log(LOG_DEBUG, "Allocate call number\n");
08747       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08748       if (reg->callno < 1) {
08749          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08750          return -1;
08751       } else if (option_debug)
08752          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08753       iaxs[reg->callno]->reg = reg;
08754       ast_mutex_unlock(&iaxsl[reg->callno]);
08755    }
08756    /* Schedule the next registration attempt */
08757    AST_SCHED_DEL(sched, reg->expire);
08758    /* Setup the next registration a little early */
08759    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08760    /* Send the request */
08761    memset(&ied, 0, sizeof(ied));
08762    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08763    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08764    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08765    reg->regstate = REG_STATE_REGSENT;
08766    return 0;
08767 }
08768 
08769 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08770 {
08771    if (pos != 3)
08772       return NULL;
08773    return iax_prov_complete_template(line, word, pos, state);
08774 }
08775 
08776 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08777 {
08778    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08779       is found for template */
08780    struct iax_ie_data provdata;
08781    struct iax_ie_data ied;
08782    unsigned int sig;
08783    struct sockaddr_in sin;
08784    int callno;
08785    struct create_addr_info cai;
08786 
08787    memset(&cai, 0, sizeof(cai));
08788 
08789    if (option_debug)
08790       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08791 
08792    if (iax_provision_build(&provdata, &sig, template, force)) {
08793       if (option_debug)
08794          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08795       return 0;
08796    }
08797 
08798    if (end) {
08799       memcpy(&sin, end, sizeof(sin));
08800       cai.sockfd = sockfd;
08801    } else if (create_addr(dest, NULL, &sin, &cai))
08802       return -1;
08803 
08804    /* Build the rest of the message */
08805    memset(&ied, 0, sizeof(ied));
08806    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08807 
08808    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08809    if (!callno)
08810       return -1;
08811 
08812    if (iaxs[callno]) {
08813       /* Schedule autodestruct in case they don't ever give us anything back */
08814       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08815       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08816       ast_set_flag(iaxs[callno], IAX_PROVISION);
08817       /* Got a call number now, so go ahead and send the provisioning information */
08818       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08819    }
08820    ast_mutex_unlock(&iaxsl[callno]);
08821 
08822    return 1;
08823 }
08824 
08825 static char *papp = "IAX2Provision";
08826 static char *psyn = "Provision a calling IAXy with a given template";
08827 static char *pdescrip = 
08828 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08829 "the calling entity is in fact an IAXy) with the given template or\n"
08830 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08831 
08832 /*! iax2provision
08833 \ingroup applications
08834 */
08835 static int iax2_prov_app(struct ast_channel *chan, void *data)
08836 {
08837    int res;
08838    char *sdata;
08839    char *opts;
08840    int force =0;
08841    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08842    if (ast_strlen_zero(data))
08843       data = "default";
08844    sdata = ast_strdupa(data);
08845    opts = strchr(sdata, '|');
08846    if (opts)
08847       *opts='\0';
08848 
08849    if (chan->tech != &iax2_tech) {
08850       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08851       return -1;
08852    } 
08853    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08854       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08855       return -1;
08856    }
08857    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08858    if (option_verbose > 2)
08859       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08860       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08861       sdata, res);
08862    return res;
08863 }
08864 
08865 
08866 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08867 {
08868    int force = 0;
08869    int res;
08870    if (argc < 4)
08871       return RESULT_SHOWUSAGE;
08872    if ((argc > 4)) {
08873       if (!strcasecmp(argv[4], "forced"))
08874          force = 1;
08875       else
08876          return RESULT_SHOWUSAGE;
08877    }
08878    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08879    if (res < 0)
08880       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08881    else if (res < 1)
08882       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08883    else
08884       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08885    return RESULT_SUCCESS;
08886 }
08887 
08888 static void __iax2_poke_noanswer(const void *data)
08889 {
08890    struct iax2_peer *peer = (struct iax2_peer *)data;
08891    int callno;
08892 
08893    if (peer->lastms > -1) {
08894       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08895       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08896       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08897    }
08898    if ((callno = peer->callno) > 0) {
08899       ast_mutex_lock(&iaxsl[callno]);
08900       iax2_destroy(callno);
08901       ast_mutex_unlock(&iaxsl[callno]);
08902    }
08903    peer->callno = 0;
08904    peer->lastms = -1;
08905    /* Try again quickly */
08906    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08907    if (peer->pokeexpire == -1)
08908       peer_unref(peer);
08909 }
08910 
08911 static int iax2_poke_noanswer(const void *data)
08912 {
08913    struct iax2_peer *peer = (struct iax2_peer *)data;
08914    peer->pokeexpire = -1;
08915 #ifdef SCHED_MULTITHREADED
08916    if (schedule_action(__iax2_poke_noanswer, data))
08917 #endif      
08918       __iax2_poke_noanswer(data);
08919    peer_unref(peer);
08920    return 0;
08921 }
08922 
08923 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08924 {
08925    struct iax2_peer *peer = obj;
08926 
08927    iax2_poke_peer(peer, 0);
08928 
08929    return 0;
08930 }
08931 
08932 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08933 {
08934    int callno;
08935    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08936       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08937         immediately after clearing things out */
08938       peer->lastms = 0;
08939       peer->historicms = 0;
08940       peer->pokeexpire = -1;
08941       peer->callno = 0;
08942       return 0;
08943    }
08944 
08945    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
08946    if ((callno = peer->callno) > 0) {
08947       ast_log(LOG_NOTICE, "Still have a callno...\n");
08948       ast_mutex_lock(&iaxsl[callno]);
08949       iax2_destroy(callno);
08950       ast_mutex_unlock(&iaxsl[callno]);
08951    }
08952    if (heldcall)
08953       ast_mutex_unlock(&iaxsl[heldcall]);
08954    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08955    if (heldcall)
08956       ast_mutex_lock(&iaxsl[heldcall]);
08957    if (peer->callno < 1) {
08958       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08959       return -1;
08960    }
08961 
08962    /* Speed up retransmission times for this qualify call */
08963    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08964    iaxs[peer->callno]->peerpoke = peer;
08965    
08966    /* Remove any pending pokeexpire task */
08967    if (peer->pokeexpire > -1) {
08968       if (!ast_sched_del(sched, peer->pokeexpire)) {
08969          peer->pokeexpire = -1;
08970          peer_unref(peer);
08971       }
08972    }
08973 
08974    /* Queue up a new task to handle no reply */
08975    /* If the host is already unreachable then use the unreachable interval instead */
08976    if (peer->lastms < 0) {
08977       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08978    } else
08979       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08980 
08981    if (peer->pokeexpire == -1)
08982       peer_unref(peer);
08983 
08984    /* And send the poke */
08985    ast_mutex_lock(&iaxsl[callno]);
08986    if (iaxs[callno]) {
08987       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08988    }
08989    ast_mutex_unlock(&iaxsl[callno]);
08990 
08991    return 0;
08992 }
08993 
08994 static void free_context(struct iax2_context *con)
08995 {
08996    struct iax2_context *conl;
08997    while(con) {
08998       conl = con;
08999       con = con->next;
09000       free(conl);
09001    }
09002 }
09003 
09004 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09005 {
09006    int callno;
09007    int res;
09008    int fmt, native;
09009    struct sockaddr_in sin;
09010    struct ast_channel *c;
09011    struct parsed_dial_string pds;
09012    struct create_addr_info cai;
09013    char *tmpstr;
09014 
09015    memset(&pds, 0, sizeof(pds));
09016    tmpstr = ast_strdupa(data);
09017    parse_dial_string(tmpstr, &pds);
09018 
09019    if (ast_strlen_zero(pds.peer)) {
09020       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09021       return NULL;
09022    }
09023           
09024    memset(&cai, 0, sizeof(cai));
09025    cai.capability = iax2_capability;
09026 
09027    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09028    
09029    /* Populate our address from the given */
09030    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09031       *cause = AST_CAUSE_UNREGISTERED;
09032       return NULL;
09033    }
09034 
09035    if (pds.port)
09036       sin.sin_port = htons(atoi(pds.port));
09037 
09038    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09039    if (callno < 1) {
09040       ast_log(LOG_WARNING, "Unable to create call\n");
09041       *cause = AST_CAUSE_CONGESTION;
09042       return NULL;
09043    }
09044 
09045    /* If this is a trunk, update it now */
09046    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09047    if (ast_test_flag(&cai, IAX_TRUNK)) {
09048       int new_callno;
09049       if ((new_callno = make_trunk(callno, 1)) != -1)
09050          callno = new_callno;
09051    }
09052    iaxs[callno]->maxtime = cai.maxtime;
09053    if (cai.found)
09054       ast_string_field_set(iaxs[callno], host, pds.peer);
09055 
09056    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09057 
09058    ast_mutex_unlock(&iaxsl[callno]);
09059 
09060    if (c) {
09061       /* Choose a format we can live with */
09062       if (c->nativeformats & format) 
09063          c->nativeformats &= format;
09064       else {
09065          native = c->nativeformats;
09066          fmt = format;
09067          res = ast_translator_best_choice(&fmt, &native);
09068          if (res < 0) {
09069             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09070                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09071             ast_hangup(c);
09072             return NULL;
09073          }
09074          c->nativeformats = native;
09075       }
09076       c->readformat = ast_best_codec(c->nativeformats);
09077       c->writeformat = c->readformat;
09078    }
09079 
09080    return c;
09081 }
09082 
09083 static void *sched_thread(void *ignore)
09084 {
09085    int count;
09086    int res;
09087    struct timeval tv;
09088    struct timespec ts;
09089 
09090    for (;;) {
09091       res = ast_sched_wait(sched);
09092       if ((res > 1000) || (res < 0))
09093          res = 1000;
09094       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09095       ts.tv_sec = tv.tv_sec;
09096       ts.tv_nsec = tv.tv_usec * 1000;
09097 
09098       pthread_testcancel();
09099       ast_mutex_lock(&sched_lock);
09100       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09101       ast_mutex_unlock(&sched_lock);
09102       pthread_testcancel();
09103 
09104       count = ast_sched_runq(sched);
09105       if (option_debug && count >= 20)
09106          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09107    }
09108    return NULL;
09109 }
09110 
09111 static void *network_thread(void *ignore)
09112 {
09113    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09114       from the network, and queue them for delivery to the channels */
09115    int res, count, wakeup;
09116    struct iax_frame *f;
09117 
09118    if (timingfd > -1)
09119       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09120    
09121    for(;;) {
09122       pthread_testcancel();
09123 
09124       /* Go through the queue, sending messages which have not yet been
09125          sent, and scheduling retransmissions if appropriate */
09126       AST_LIST_LOCK(&iaxq.queue);
09127       count = 0;
09128       wakeup = -1;
09129       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09130          if (f->sentyet)
09131             continue;
09132          
09133          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09134          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09135             wakeup = 1;
09136             continue;
09137          }
09138 
09139          f->sentyet++;
09140 
09141          if (iaxs[f->callno]) {
09142             send_packet(f);
09143             count++;
09144          } 
09145 
09146          ast_mutex_unlock(&iaxsl[f->callno]);
09147 
09148          if (f->retries < 0) {
09149             /* This is not supposed to be retransmitted */
09150             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09151             iaxq.count--;
09152             /* Free the iax frame */
09153             iax_frame_free(f);
09154          } else {
09155             /* We need reliable delivery.  Schedule a retransmission */
09156             f->retries++;
09157             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09158          }
09159       }
09160       AST_LIST_TRAVERSE_SAFE_END
09161       AST_LIST_UNLOCK(&iaxq.queue);
09162 
09163       pthread_testcancel();
09164 
09165       if (option_debug && count >= 20)
09166          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09167 
09168       /* Now do the IO, and run scheduled tasks */
09169       res = ast_io_wait(io, wakeup);
09170       if (res >= 0) {
09171          if (option_debug && res >= 20)
09172             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09173       }
09174    }
09175    return NULL;
09176 }
09177 
09178 static int start_network_thread(void)
09179 {
09180    pthread_attr_t attr;
09181    int threadcount = 0;
09182    int x;
09183    for (x = 0; x < iaxthreadcount; x++) {
09184       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09185       if (thread) {
09186          thread->type = IAX_TYPE_POOL;
09187          thread->threadnum = ++threadcount;
09188          ast_mutex_init(&thread->lock);
09189          ast_cond_init(&thread->cond, NULL);
09190          pthread_attr_init(&attr);
09191          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09192          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09193             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09194             free(thread);
09195             thread = NULL;
09196          }
09197          AST_LIST_LOCK(&idle_list);
09198          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09199          AST_LIST_UNLOCK(&idle_list);
09200       }
09201    }
09202    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09203    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09204    if (option_verbose > 1)
09205       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09206    return 0;
09207 }
09208 
09209 static struct iax2_context *build_context(char *context)
09210 {
09211    struct iax2_context *con;
09212 
09213    if ((con = ast_calloc(1, sizeof(*con))))
09214       ast_copy_string(con->context, context, sizeof(con->context));
09215    
09216    return con;
09217 }
09218 
09219 static int get_auth_methods(char *value)
09220 {
09221    int methods = 0;
09222    if (strstr(value, "rsa"))
09223       methods |= IAX_AUTH_RSA;
09224    if (strstr(value, "md5"))
09225       methods |= IAX_AUTH_MD5;
09226    if (strstr(value, "plaintext"))
09227       methods |= IAX_AUTH_PLAINTEXT;
09228    return methods;
09229 }
09230 
09231 
09232 /*! \brief Check if address can be used as packet source.
09233  \return 0  address available, 1  address unavailable, -1  error
09234 */
09235 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09236 {
09237    int sd;
09238    int res;
09239    
09240    sd = socket(AF_INET, SOCK_DGRAM, 0);
09241    if (sd < 0) {
09242       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09243       return -1;
09244    }
09245 
09246    res = bind(sd, sa, salen);
09247    if (res < 0) {
09248       if (option_debug)
09249          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09250       close(sd);
09251       return 1;
09252    }
09253 
09254    close(sd);
09255    return 0;
09256 }
09257 
09258 /*! \brief Parse the "sourceaddress" value,
09259   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09260   not found. */
09261 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09262 {
09263    struct sockaddr_in sin;
09264    int nonlocal = 1;
09265    int port = IAX_DEFAULT_PORTNO;
09266    int sockfd = defaultsockfd;
09267    char *tmp;
09268    char *addr;
09269    char *portstr;
09270 
09271    if (!(tmp = ast_strdupa(srcaddr)))
09272       return -1;
09273 
09274    addr = strsep(&tmp, ":");
09275    portstr = tmp;
09276 
09277    if (portstr) {
09278       port = atoi(portstr);
09279       if (port < 1)
09280          port = IAX_DEFAULT_PORTNO;
09281    }
09282    
09283    if (!ast_get_ip(&sin, addr)) {
09284       struct ast_netsock *sock;
09285       int res;
09286 
09287       sin.sin_port = 0;
09288       sin.sin_family = AF_INET;
09289       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09290       if (res == 0) {
09291          /* ip address valid. */
09292          sin.sin_port = htons(port);
09293          if (!(sock = ast_netsock_find(netsock, &sin)))
09294             sock = ast_netsock_find(outsock, &sin);
09295          if (sock) {
09296             sockfd = ast_netsock_sockfd(sock);
09297             nonlocal = 0;
09298          } else {
09299             unsigned int orig_saddr = sin.sin_addr.s_addr;
09300             /* INADDR_ANY matches anyway! */
09301             sin.sin_addr.s_addr = INADDR_ANY;
09302             if (ast_netsock_find(netsock, &sin)) {
09303                sin.sin_addr.s_addr = orig_saddr;
09304                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09305                if (sock) {
09306                   sockfd = ast_netsock_sockfd(sock);
09307                   ast_netsock_unref(sock);
09308                   nonlocal = 0;
09309                } else {
09310                   nonlocal = 2;
09311                }
09312             }
09313          }
09314       }
09315    }
09316       
09317    peer->sockfd = sockfd;
09318 
09319    if (nonlocal == 1) {
09320       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09321          srcaddr, peer->name);
09322       return -1;
09323         } else if (nonlocal == 2) {
09324       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09325          srcaddr, peer->name);
09326          return -1;
09327    } else {
09328       if (option_debug)
09329          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09330       return 0;
09331    }
09332 }
09333 
09334 static void peer_destructor(void *obj)
09335 {
09336    struct iax2_peer *peer = obj;
09337 
09338    ast_free_ha(peer->ha);
09339 
09340    if (peer->callno > 0) {
09341       ast_mutex_lock(&iaxsl[peer->callno]);
09342       iax2_destroy(peer->callno);
09343       ast_mutex_unlock(&iaxsl[peer->callno]);
09344    }
09345 
09346    register_peer_exten(peer, 0);
09347 
09348    if (peer->dnsmgr)
09349       ast_dnsmgr_release(peer->dnsmgr);
09350 
09351    ast_string_field_free_memory(peer);
09352 }
09353 
09354 /*! \brief Create peer structure based on configuration */
09355 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09356 {
09357    struct iax2_peer *peer = NULL;
09358    struct ast_ha *oldha = NULL;
09359    int maskfound=0;
09360    int found=0;
09361    int firstpass=1;
09362    struct iax2_peer tmp_peer = {
09363       .name = name,
09364    };
09365 
09366    if (!temponly) {
09367       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09368       if (peer && !ast_test_flag(peer, IAX_DELME))
09369          firstpass = 0;
09370    }
09371 
09372    if (peer) {
09373       found++;
09374       if (firstpass) {
09375          oldha = peer->ha;
09376          peer->ha = NULL;
09377       }
09378       unlink_peer(peer);
09379    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09380       peer->expire = -1;
09381       peer->pokeexpire = -1;
09382       peer->sockfd = defaultsockfd;
09383       if (ast_string_field_init(peer, 32))
09384          peer = peer_unref(peer);
09385    }
09386 
09387    if (peer) {
09388       if (firstpass) {
09389          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09390          peer->encmethods = iax2_encryption;
09391          peer->adsi = adsi;
09392          ast_string_field_set(peer,secret,"");
09393          if (!found) {
09394             ast_string_field_set(peer, name, name);
09395             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09396             peer->expiry = min_reg_expire;
09397          }
09398          peer->prefs = prefs;
09399          peer->capability = iax2_capability;
09400          peer->smoothing = 0;
09401          peer->pokefreqok = DEFAULT_FREQ_OK;
09402          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09403          ast_string_field_set(peer,context,"");
09404          ast_string_field_set(peer,peercontext,"");
09405          ast_clear_flag(peer, IAX_HASCALLERID);
09406          ast_string_field_set(peer, cid_name, "");
09407          ast_string_field_set(peer, cid_num, "");
09408       }
09409 
09410       if (!v) {
09411          v = alt;
09412          alt = NULL;
09413       }
09414       while(v) {
09415          if (!strcasecmp(v->name, "secret")) {
09416             ast_string_field_set(peer, secret, v->value);
09417          } else if (!strcasecmp(v->name, "mailbox")) {
09418             ast_string_field_set(peer, mailbox, v->value);
09419          } else if (!strcasecmp(v->name, "mohinterpret")) {
09420             ast_string_field_set(peer, mohinterpret, v->value);
09421          } else if (!strcasecmp(v->name, "mohsuggest")) {
09422             ast_string_field_set(peer, mohsuggest, v->value);
09423          } else if (!strcasecmp(v->name, "dbsecret")) {
09424             ast_string_field_set(peer, dbsecret, v->value);
09425          } else if (!strcasecmp(v->name, "trunk")) {
09426             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09427             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09428                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09429                ast_clear_flag(peer, IAX_TRUNK);
09430             }
09431          } else if (!strcasecmp(v->name, "auth")) {
09432             peer->authmethods = get_auth_methods(v->value);
09433          } else if (!strcasecmp(v->name, "encryption")) {
09434             peer->encmethods = get_encrypt_methods(v->value);
09435          } else if (!strcasecmp(v->name, "notransfer")) {
09436             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09437             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09438             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09439          } else if (!strcasecmp(v->name, "transfer")) {
09440             if (!strcasecmp(v->value, "mediaonly")) {
09441                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09442             } else if (ast_true(v->value)) {
09443                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09444             } else 
09445                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09446          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09447             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09448          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09449             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09450          } else if (!strcasecmp(v->name, "host")) {
09451             if (!strcasecmp(v->value, "dynamic")) {
09452                /* They'll register with us */
09453                ast_set_flag(peer, IAX_DYNAMIC); 
09454                if (!found) {
09455                   /* Initialize stuff iff we're not found, otherwise
09456                      we keep going with what we had */
09457                   memset(&peer->addr.sin_addr, 0, 4);
09458                   if (peer->addr.sin_port) {
09459                      /* If we've already got a port, make it the default rather than absolute */
09460                      peer->defaddr.sin_port = peer->addr.sin_port;
09461                      peer->addr.sin_port = 0;
09462                   }
09463                }
09464             } else {
09465                /* Non-dynamic.  Make sure we become that way if we're not */
09466                AST_SCHED_DEL(sched, peer->expire);
09467                ast_clear_flag(peer, IAX_DYNAMIC);
09468                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09469                   return peer_unref(peer);
09470                if (!peer->addr.sin_port)
09471                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09472             }
09473             if (!maskfound)
09474                inet_aton("255.255.255.255", &peer->mask);
09475          } else if (!strcasecmp(v->name, "defaultip")) {
09476             if (ast_get_ip(&peer->defaddr, v->value))
09477                return peer_unref(peer);
09478          } else if (!strcasecmp(v->name, "sourceaddress")) {
09479             peer_set_srcaddr(peer, v->value);
09480          } else if (!strcasecmp(v->name, "permit") ||
09481                   !strcasecmp(v->name, "deny")) {
09482             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09483          } else if (!strcasecmp(v->name, "mask")) {
09484             maskfound++;
09485             inet_aton(v->value, &peer->mask);
09486          } else if (!strcasecmp(v->name, "context")) {
09487             ast_string_field_set(peer, context, v->value);
09488          } else if (!strcasecmp(v->name, "regexten")) {
09489             ast_string_field_set(peer, regexten, v->value);
09490          } else if (!strcasecmp(v->name, "peercontext")) {
09491             ast_string_field_set(peer, peercontext, v->value);
09492          } else if (!strcasecmp(v->name, "port")) {
09493             if (ast_test_flag(peer, IAX_DYNAMIC))
09494                peer->defaddr.sin_port = htons(atoi(v->value));
09495             else
09496                peer->addr.sin_port = htons(atoi(v->value));
09497          } else if (!strcasecmp(v->name, "username")) {
09498             ast_string_field_set(peer, username, v->value);
09499          } else if (!strcasecmp(v->name, "allow")) {
09500             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09501          } else if (!strcasecmp(v->name, "disallow")) {
09502             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09503          } else if (!strcasecmp(v->name, "callerid")) {
09504             if (!ast_strlen_zero(v->value)) {
09505                char name2[80];
09506                char num2[80];
09507                ast_callerid_split(v->value, name2, 80, num2, 80);
09508                ast_string_field_set(peer, cid_name, name2);
09509                ast_string_field_set(peer, cid_num, num2);
09510                ast_set_flag(peer, IAX_HASCALLERID);
09511             } else {
09512                ast_clear_flag(peer, IAX_HASCALLERID);
09513                ast_string_field_set(peer, cid_name, "");
09514                ast_string_field_set(peer, cid_num, "");
09515             }
09516          } else if (!strcasecmp(v->name, "fullname")) {
09517             if (!ast_strlen_zero(v->value)) {
09518                ast_string_field_set(peer, cid_name, v->value);
09519                ast_set_flag(peer, IAX_HASCALLERID);
09520             } else {
09521                ast_string_field_set(peer, cid_name, "");
09522                if (ast_strlen_zero(peer->cid_num))
09523                   ast_clear_flag(peer, IAX_HASCALLERID);
09524             }
09525          } else if (!strcasecmp(v->name, "cid_number")) {
09526             if (!ast_strlen_zero(v->value)) {
09527                ast_string_field_set(peer, cid_num, v->value);
09528                ast_set_flag(peer, IAX_HASCALLERID);
09529             } else {
09530                ast_string_field_set(peer, cid_num, "");
09531                if (ast_strlen_zero(peer->cid_name))
09532                   ast_clear_flag(peer, IAX_HASCALLERID);
09533             }
09534          } else if (!strcasecmp(v->name, "sendani")) {
09535             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09536          } else if (!strcasecmp(v->name, "inkeys")) {
09537             ast_string_field_set(peer, inkeys, v->value);
09538          } else if (!strcasecmp(v->name, "outkey")) {
09539             ast_string_field_set(peer, outkey, v->value);
09540          } else if (!strcasecmp(v->name, "qualify")) {
09541             if (!strcasecmp(v->value, "no")) {
09542                peer->maxms = 0;
09543             } else if (!strcasecmp(v->value, "yes")) {
09544                peer->maxms = DEFAULT_MAXMS;
09545             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09546                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);
09547                peer->maxms = 0;
09548             }
09549          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09550             peer->smoothing = ast_true(v->value);
09551          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09552             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09553                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);
09554             }
09555          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09556             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09557                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);
09558             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09559          } else if (!strcasecmp(v->name, "timezone")) {
09560             ast_string_field_set(peer, zonetag, v->value);
09561          } else if (!strcasecmp(v->name, "adsi")) {
09562             peer->adsi = ast_true(v->value);
09563          }/* else if (strcasecmp(v->name,"type")) */
09564          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09565          v = v->next;
09566          if (!v) {
09567             v = alt;
09568             alt = NULL;
09569          }
09570       }
09571       if (!peer->authmethods)
09572          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09573       ast_clear_flag(peer, IAX_DELME); 
09574       /* Make sure these are IPv4 addresses */
09575       peer->addr.sin_family = AF_INET;
09576    }
09577    if (oldha)
09578       ast_free_ha(oldha);
09579    return peer;
09580 }
09581 
09582 static void user_destructor(void *obj)
09583 {
09584    struct iax2_user *user = obj;
09585 
09586    ast_free_ha(user->ha);
09587    free_context(user->contexts);
09588    if(user->vars) {
09589       ast_variables_destroy(user->vars);
09590       user->vars = NULL;
09591    }
09592    ast_string_field_free_memory(user);
09593 }
09594 
09595 /*! \brief Create in-memory user structure from configuration */
09596 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09597 {
09598    struct iax2_user *user = NULL;
09599    struct iax2_context *con, *conl = NULL;
09600    struct ast_ha *oldha = NULL;
09601    struct iax2_context *oldcon = NULL;
09602    int format;
09603    int firstpass=1;
09604    int oldcurauthreq = 0;
09605    char *varname = NULL, *varval = NULL;
09606    struct ast_variable *tmpvar = NULL;
09607    struct iax2_user tmp_user = {
09608       .name = name,
09609    };
09610 
09611    if (!temponly) {
09612       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09613       if (user && !ast_test_flag(user, IAX_DELME))
09614          firstpass = 0;
09615    }
09616 
09617    if (user) {
09618       if (firstpass) {
09619          oldcurauthreq = user->curauthreq;
09620          oldha = user->ha;
09621          oldcon = user->contexts;
09622          user->ha = NULL;
09623          user->contexts = NULL;
09624       }
09625       /* Already in the list, remove it and it will be added back (or FREE'd) */
09626       ao2_unlink(users, user);
09627    } else {
09628       user = ao2_alloc(sizeof(*user), user_destructor);
09629    }
09630    
09631    if (user) {
09632       if (firstpass) {
09633          ast_string_field_free_memory(user);
09634          memset(user, 0, sizeof(struct iax2_user));
09635          if (ast_string_field_init(user, 32)) {
09636             user = user_unref(user);
09637             goto cleanup;
09638          }
09639          user->maxauthreq = maxauthreq;
09640          user->curauthreq = oldcurauthreq;
09641          user->prefs = prefs;
09642          user->capability = iax2_capability;
09643          user->encmethods = iax2_encryption;
09644          user->adsi = adsi;
09645          ast_string_field_set(user, name, name);
09646          ast_string_field_set(user, language, language);
09647          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09648          ast_clear_flag(user, IAX_HASCALLERID);
09649          ast_string_field_set(user, cid_name, "");
09650          ast_string_field_set(user, cid_num, "");
09651       }
09652       if (!v) {
09653          v = alt;
09654          alt = NULL;
09655       }
09656       while(v) {
09657          if (!strcasecmp(v->name, "context")) {
09658             con = build_context(v->value);
09659             if (con) {
09660                if (conl)
09661                   conl->next = con;
09662                else
09663                   user->contexts = con;
09664                conl = con;
09665             }
09666          } else if (!strcasecmp(v->name, "permit") ||
09667                   !strcasecmp(v->name, "deny")) {
09668             user->ha = ast_append_ha(v->name, v->value, user->ha);
09669          } else if (!strcasecmp(v->name, "setvar")) {
09670             varname = ast_strdupa(v->value);
09671             if (varname && (varval = strchr(varname,'='))) {
09672                *varval = '\0';
09673                varval++;
09674                if((tmpvar = ast_variable_new(varname, varval))) {
09675                   tmpvar->next = user->vars; 
09676                   user->vars = tmpvar;
09677                }
09678             }
09679          } else if (!strcasecmp(v->name, "allow")) {
09680             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09681          } else if (!strcasecmp(v->name, "disallow")) {
09682             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09683          } else if (!strcasecmp(v->name, "trunk")) {
09684             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09685             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09686                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09687                ast_clear_flag(user, IAX_TRUNK);
09688             }
09689          } else if (!strcasecmp(v->name, "auth")) {
09690             user->authmethods = get_auth_methods(v->value);
09691          } else if (!strcasecmp(v->name, "encryption")) {
09692             user->encmethods = get_encrypt_methods(v->value);
09693          } else if (!strcasecmp(v->name, "notransfer")) {
09694             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09695             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09696             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09697          } else if (!strcasecmp(v->name, "transfer")) {
09698             if (!strcasecmp(v->value, "mediaonly")) {
09699                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09700             } else if (ast_true(v->value)) {
09701                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09702             } else 
09703                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09704          } else if (!strcasecmp(v->name, "codecpriority")) {
09705             if(!strcasecmp(v->value, "caller"))
09706                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09707             else if(!strcasecmp(v->value, "disabled"))
09708                ast_set_flag(user, IAX_CODEC_NOPREFS);
09709             else if(!strcasecmp(v->value, "reqonly")) {
09710                ast_set_flag(user, IAX_CODEC_NOCAP);
09711                ast_set_flag(user, IAX_CODEC_NOPREFS);
09712             }
09713          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09714             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09715          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09716             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09717          } else if (!strcasecmp(v->name, "dbsecret")) {
09718             ast_string_field_set(user, dbsecret, v->value);
09719          } else if (!strcasecmp(v->name, "secret")) {
09720             if (!ast_strlen_zero(user->secret)) {
09721                char *old = ast_strdupa(user->secret);
09722 
09723                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09724             } else
09725                ast_string_field_set(user, secret, v->value);
09726          } else if (!strcasecmp(v->name, "callerid")) {
09727             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09728                char name2[80];
09729                char num2[80];
09730                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09731                ast_string_field_set(user, cid_name, name2);
09732                ast_string_field_set(user, cid_num, num2);
09733                ast_set_flag(user, IAX_HASCALLERID);
09734             } else {
09735                ast_clear_flag(user, IAX_HASCALLERID);
09736                ast_string_field_set(user, cid_name, "");
09737                ast_string_field_set(user, cid_num, "");
09738             }
09739          } else if (!strcasecmp(v->name, "fullname")) {
09740             if (!ast_strlen_zero(v->value)) {
09741                ast_string_field_set(user, cid_name, v->value);
09742                ast_set_flag(user, IAX_HASCALLERID);
09743             } else {
09744                ast_string_field_set(user, cid_name, "");
09745                if (ast_strlen_zero(user->cid_num))
09746                   ast_clear_flag(user, IAX_HASCALLERID);
09747             }
09748          } else if (!strcasecmp(v->name, "cid_number")) {
09749             if (!ast_strlen_zero(v->value)) {
09750                ast_string_field_set(user, cid_num, v->value);
09751                ast_set_flag(user, IAX_HASCALLERID);
09752             } else {
09753                ast_string_field_set(user, cid_num, "");
09754                if (ast_strlen_zero(user->cid_name))
09755                   ast_clear_flag(user, IAX_HASCALLERID);
09756             }
09757          } else if (!strcasecmp(v->name, "accountcode")) {
09758             ast_string_field_set(user, accountcode, v->value);
09759          } else if (!strcasecmp(v->name, "mohinterpret")) {
09760             ast_string_field_set(user, mohinterpret, v->value);
09761          } else if (!strcasecmp(v->name, "mohsuggest")) {
09762             ast_string_field_set(user, mohsuggest, v->value);
09763          } else if (!strcasecmp(v->name, "language")) {
09764             ast_string_field_set(user, language, v->value);
09765          } else if (!strcasecmp(v->name, "amaflags")) {
09766             format = ast_cdr_amaflags2int(v->value);
09767             if (format < 0) {
09768                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09769             } else {
09770                user->amaflags = format;
09771             }
09772          } else if (!strcasecmp(v->name, "inkeys")) {
09773             ast_string_field_set(user, inkeys, v->value);
09774          } else if (!strcasecmp(v->name, "maxauthreq")) {
09775             user->maxauthreq = atoi(v->value);
09776             if (user->maxauthreq < 0)
09777                user->maxauthreq = 0;
09778          } else if (!strcasecmp(v->name, "adsi")) {
09779             user->adsi = ast_true(v->value);
09780          }/* else if (strcasecmp(v->name,"type")) */
09781          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09782          v = v->next;
09783          if (!v) {
09784             v = alt;
09785             alt = NULL;
09786          }
09787       }
09788       if (!user->authmethods) {
09789          if (!ast_strlen_zero(user->secret)) {
09790             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09791             if (!ast_strlen_zero(user->inkeys))
09792                user->authmethods |= IAX_AUTH_RSA;
09793          } else if (!ast_strlen_zero(user->inkeys)) {
09794             user->authmethods = IAX_AUTH_RSA;
09795          } else {
09796             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09797          }
09798       }
09799       ast_clear_flag(user, IAX_DELME);
09800    }
09801 cleanup:
09802    if (oldha)
09803       ast_free_ha(oldha);
09804    if (oldcon)
09805       free_context(oldcon);
09806    return user;
09807 }
09808 
09809 static int peer_delme_cb(void *obj, void *arg, int flags)
09810 {
09811    struct iax2_peer *peer = obj;
09812 
09813    ast_set_flag(peer, IAX_DELME);
09814 
09815    return 0;
09816 }
09817 
09818 static int user_delme_cb(void *obj, void *arg, int flags)
09819 {
09820    struct iax2_user *user = obj;
09821 
09822    ast_set_flag(user, IAX_DELME);
09823 
09824    return 0;
09825 }
09826 
09827 static void delete_users(void)
09828 {
09829    struct iax2_registry *reg;
09830 
09831    ao2_callback(users, 0, user_delme_cb, NULL);
09832 
09833    AST_LIST_LOCK(&registrations);
09834    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09835       ast_sched_del(sched, reg->expire);
09836       if (reg->callno) {
09837          ast_mutex_lock(&iaxsl[reg->callno]);
09838          if (iaxs[reg->callno]) {
09839             iaxs[reg->callno]->reg = NULL;
09840             iax2_destroy(reg->callno);
09841          }
09842          ast_mutex_unlock(&iaxsl[reg->callno]);
09843       }
09844       if (reg->dnsmgr)
09845          ast_dnsmgr_release(reg->dnsmgr);
09846       free(reg);
09847    }
09848    AST_LIST_UNLOCK(&registrations);
09849 
09850    ao2_callback(peers, 0, peer_delme_cb, NULL);
09851 }
09852 
09853 static void prune_users(void)
09854 {
09855    struct iax2_user *user;
09856    struct ao2_iterator i;
09857 
09858    i = ao2_iterator_init(users, 0);
09859    while ((user = ao2_iterator_next(&i))) {
09860       if (ast_test_flag(user, IAX_DELME))
09861          ao2_unlink(users, user);
09862       user_unref(user);
09863    }
09864 }
09865 
09866 /* Prune peers who still are supposed to be deleted */
09867 static void prune_peers(void)
09868 {
09869    struct iax2_peer *peer;
09870    struct ao2_iterator i;
09871 
09872    i = ao2_iterator_init(peers, 0);
09873    while ((peer = ao2_iterator_next(&i))) {
09874       if (ast_test_flag(peer, IAX_DELME))
09875          unlink_peer(peer);
09876       peer_unref(peer);
09877    }
09878 }
09879 
09880 static void set_timing(void)
09881 {
09882 #ifdef HAVE_ZAPTEL
09883    int bs = trunkfreq * 8;
09884    if (timingfd > -1) {
09885       if (
09886 #ifdef ZT_TIMERACK
09887          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09888 #endif         
09889          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09890          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09891    }
09892 #endif
09893 }
09894 
09895 static void set_config_destroy(void)
09896 {
09897    strcpy(accountcode, "");
09898    strcpy(language, "");
09899    strcpy(mohinterpret, "default");
09900    strcpy(mohsuggest, "");
09901    amaflags = 0;
09902    delayreject = 0;
09903    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09904    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09905    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09906    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09907    delete_users();
09908 }
09909 
09910 /*! \brief Load configuration */
09911 static int set_config(char *config_file, int reload)
09912 {
09913    struct ast_config *cfg, *ucfg;
09914    int capability=iax2_capability;
09915    struct ast_variable *v;
09916    char *cat;
09917    const char *utype;
09918    const char *tosval;
09919    int format;
09920    int portno = IAX_DEFAULT_PORTNO;
09921    int  x;
09922    struct iax2_user *user;
09923    struct iax2_peer *peer;
09924    struct ast_netsock *ns;
09925 #if 0
09926    static unsigned short int last_port=0;
09927 #endif
09928 
09929    cfg = ast_config_load(config_file);
09930    
09931    if (!cfg) {
09932       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09933       return -1;
09934    }
09935 
09936    if (reload) {
09937       set_config_destroy();
09938    }
09939 
09940    /* Reset global codec prefs */   
09941    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09942    
09943    /* Reset Global Flags */
09944    memset(&globalflags, 0, sizeof(globalflags));
09945    ast_set_flag(&globalflags, IAX_RTUPDATE);
09946 
09947 #ifdef SO_NO_CHECK
09948    nochecksums = 0;
09949 #endif
09950 
09951    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09952    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09953 
09954    maxauthreq = 3;
09955 
09956    v = ast_variable_browse(cfg, "general");
09957 
09958    /* Seed initial tos value */
09959    tosval = ast_variable_retrieve(cfg, "general", "tos");
09960    if (tosval) {
09961       if (ast_str2tos(tosval, &tos))
09962          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09963    }
09964    while(v) {
09965       if (!strcasecmp(v->name, "bindport")){ 
09966          if (reload)
09967             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09968          else
09969             portno = atoi(v->value);
09970       } else if (!strcasecmp(v->name, "pingtime")) 
09971          ping_time = atoi(v->value);
09972       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09973          if (reload) {
09974             if (atoi(v->value) != iaxthreadcount)
09975                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09976          } else {
09977             iaxthreadcount = atoi(v->value);
09978             if (iaxthreadcount < 1) {
09979                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09980                iaxthreadcount = 1;
09981             } else if (iaxthreadcount > 256) {
09982                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09983                iaxthreadcount = 256;
09984             }
09985          }
09986       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09987          if (reload) {
09988             AST_LIST_LOCK(&dynamic_list);
09989             iaxmaxthreadcount = atoi(v->value);
09990             AST_LIST_UNLOCK(&dynamic_list);
09991          } else {
09992             iaxmaxthreadcount = atoi(v->value);
09993             if (iaxmaxthreadcount < 0) {
09994                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09995                iaxmaxthreadcount = 0;
09996             } else if (iaxmaxthreadcount > 256) {
09997                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09998                iaxmaxthreadcount = 256;
09999             }
10000          }
10001       } else if (!strcasecmp(v->name, "nochecksums")) {
10002 #ifdef SO_NO_CHECK
10003          if (ast_true(v->value))
10004             nochecksums = 1;
10005          else
10006             nochecksums = 0;
10007 #else
10008          if (ast_true(v->value))
10009             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10010 #endif
10011       }
10012       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
10013          maxjitterbuffer = atoi(v->value);
10014       else if (!strcasecmp(v->name, "resyncthreshold")) 
10015          resyncthreshold = atoi(v->value);
10016       else if (!strcasecmp(v->name, "maxjitterinterps")) 
10017          maxjitterinterps = atoi(v->value);
10018       else if (!strcasecmp(v->name, "lagrqtime")) 
10019          lagrq_time = atoi(v->value);
10020       else if (!strcasecmp(v->name, "maxregexpire")) 
10021          max_reg_expire = atoi(v->value);
10022       else if (!strcasecmp(v->name, "minregexpire")) 
10023          min_reg_expire = atoi(v->value);
10024       else if (!strcasecmp(v->name, "bindaddr")) {
10025          if (reload) {
10026             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10027          } else {
10028             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10029                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10030             } else {
10031                if (option_verbose > 1) {
10032                   if (strchr(v->value, ':'))
10033                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10034                   else
10035                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10036                }
10037                if (defaultsockfd < 0) 
10038                   defaultsockfd = ast_netsock_sockfd(ns);
10039                ast_netsock_unref(ns);
10040             }
10041          }
10042       } else if (!strcasecmp(v->name, "authdebug"))
10043          authdebug = ast_true(v->value);
10044       else if (!strcasecmp(v->name, "encryption"))
10045          iax2_encryption = get_encrypt_methods(v->value);
10046       else if (!strcasecmp(v->name, "notransfer")) {
10047          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10048          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10049          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10050       } else if (!strcasecmp(v->name, "transfer")) {
10051          if (!strcasecmp(v->value, "mediaonly")) {
10052             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10053          } else if (ast_true(v->value)) {
10054             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10055          } else 
10056             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10057       } else if (!strcasecmp(v->name, "codecpriority")) {
10058          if(!strcasecmp(v->value, "caller"))
10059             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10060          else if(!strcasecmp(v->value, "disabled"))
10061             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10062          else if(!strcasecmp(v->value, "reqonly")) {
10063             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10064             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10065          }
10066       } else if (!strcasecmp(v->name, "jitterbuffer"))
10067          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10068       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10069          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10070       else if (!strcasecmp(v->name, "delayreject"))
10071          delayreject = ast_true(v->value);
10072       else if (!strcasecmp(v->name, "allowfwdownload"))
10073          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10074       else if (!strcasecmp(v->name, "rtcachefriends"))
10075          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10076       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10077          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10078       else if (!strcasecmp(v->name, "rtupdate"))
10079          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10080       else if (!strcasecmp(v->name, "trunktimestamps"))
10081          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10082       else if (!strcasecmp(v->name, "rtautoclear")) {
10083          int i = atoi(v->value);
10084          if(i > 0)
10085             global_rtautoclear = i;
10086          else
10087             i = 0;
10088          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10089       } else if (!strcasecmp(v->name, "trunkfreq")) {
10090          trunkfreq = atoi(v->value);
10091          if (trunkfreq < 10)
10092             trunkfreq = 10;
10093       } else if (!strcasecmp(v->name, "autokill")) {
10094          if (sscanf(v->value, "%d", &x) == 1) {
10095             if (x >= 0)
10096                autokill = x;
10097             else
10098                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10099          } else if (ast_true(v->value)) {
10100             autokill = DEFAULT_MAXMS;
10101          } else {
10102             autokill = 0;
10103          }
10104       } else if (!strcasecmp(v->name, "bandwidth")) {
10105          if (!strcasecmp(v->value, "low")) {
10106             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10107          } else if (!strcasecmp(v->value, "medium")) {
10108             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10109          } else if (!strcasecmp(v->value, "high")) {
10110             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10111          } else
10112             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10113       } else if (!strcasecmp(v->name, "allow")) {
10114          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10115       } else if (!strcasecmp(v->name, "disallow")) {
10116          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10117       } else if (!strcasecmp(v->name, "register")) {
10118          iax2_register(v->value, v->lineno);
10119       } else if (!strcasecmp(v->name, "iaxcompat")) {
10120          iaxcompat = ast_true(v->value);
10121       } else if (!strcasecmp(v->name, "regcontext")) {
10122          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10123          /* Create context if it doesn't exist already */
10124          if (!ast_context_find(regcontext))
10125             ast_context_create(NULL, regcontext, "IAX2");
10126       } else if (!strcasecmp(v->name, "tos")) {
10127          if (ast_str2tos(v->value, &tos))
10128             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10129       } else if (!strcasecmp(v->name, "accountcode")) {
10130          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10131       } else if (!strcasecmp(v->name, "mohinterpret")) {
10132          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10133       } else if (!strcasecmp(v->name, "mohsuggest")) {
10134          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10135       } else if (!strcasecmp(v->name, "amaflags")) {
10136          format = ast_cdr_amaflags2int(v->value);
10137          if (format < 0) {
10138             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10139          } else {
10140             amaflags = format;
10141          }
10142       } else if (!strcasecmp(v->name, "language")) {
10143          ast_copy_string(language, v->value, sizeof(language));
10144       } else if (!strcasecmp(v->name, "maxauthreq")) {
10145          maxauthreq = atoi(v->value);
10146          if (maxauthreq < 0)
10147             maxauthreq = 0;
10148       } else if (!strcasecmp(v->name, "adsi")) {
10149          adsi = ast_true(v->value);
10150       } /*else if (strcasecmp(v->name,"type")) */
10151       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10152       v = v->next;
10153    }
10154    
10155    if (defaultsockfd < 0) {
10156       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10157          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10158       } else {
10159          if (option_verbose > 1)
10160             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10161          defaultsockfd = ast_netsock_sockfd(ns);
10162          ast_netsock_unref(ns);
10163       }
10164    }
10165    if (reload) {
10166       ast_netsock_release(outsock);
10167       outsock = ast_netsock_list_alloc();
10168       if (!outsock) {
10169          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10170          return -1;
10171       }
10172       ast_netsock_init(outsock);
10173    }
10174 
10175    if (min_reg_expire > max_reg_expire) {
10176       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10177          min_reg_expire, max_reg_expire, max_reg_expire);
10178       min_reg_expire = max_reg_expire;
10179    }
10180    iax2_capability = capability;
10181    
10182    ucfg = ast_config_load("users.conf");
10183    if (ucfg) {
10184       struct ast_variable *gen;
10185       int genhasiax;
10186       int genregisteriax;
10187       const char *hasiax, *registeriax;
10188       
10189       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10190       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10191       gen = ast_variable_browse(ucfg, "general");
10192       cat = ast_category_browse(ucfg, NULL);
10193       while (cat) {
10194          if (strcasecmp(cat, "general")) {
10195             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10196             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10197             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10198                /* Start with general parameters, then specific parameters, user and peer */
10199                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10200                if (user) {
10201                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10202                   user = user_unref(user);
10203                }
10204                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10205                if (peer) {
10206                   if (ast_test_flag(peer, IAX_DYNAMIC))
10207                      reg_source_db(peer);
10208                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10209                   peer = peer_unref(peer);
10210                }
10211             }
10212             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10213                char tmp[256];
10214                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10215                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10216                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10217                if (!host)
10218                   host = ast_variable_retrieve(ucfg, "general", "host");
10219                if (!username)
10220                   username = ast_variable_retrieve(ucfg, "general", "username");
10221                if (!secret)
10222                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10223                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10224                   if (!ast_strlen_zero(secret))
10225                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10226                   else
10227                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10228                   iax2_register(tmp, 0);
10229                }
10230             }
10231          }
10232          cat = ast_category_browse(ucfg, cat);
10233       }
10234       ast_config_destroy(ucfg);
10235    }
10236    
10237    cat = ast_category_browse(cfg, NULL);
10238    while(cat) {
10239       if (strcasecmp(cat, "general")) {
10240          utype = ast_variable_retrieve(cfg, cat, "type");
10241          if (utype) {
10242             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10243                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10244                if (user) {
10245                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10246                   user = user_unref(user);
10247                }
10248             }
10249             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10250                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10251                if (peer) {
10252                   if (ast_test_flag(peer, IAX_DYNAMIC))
10253                      reg_source_db(peer);
10254                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10255                   peer = peer_unref(peer);
10256                }
10257             } else if (strcasecmp(utype, "user")) {
10258                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10259             }
10260          } else
10261             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10262       }
10263       cat = ast_category_browse(cfg, cat);
10264    }
10265    ast_config_destroy(cfg);
10266    set_timing();
10267    return 1;
10268 }
10269 
10270 static void poke_all_peers(void)
10271 {
10272    struct ao2_iterator i;
10273    struct iax2_peer *peer;
10274 
10275    i = ao2_iterator_init(peers, 0);
10276    while ((peer = ao2_iterator_next(&i))) {
10277       iax2_poke_peer(peer, 0);
10278       peer_unref(peer);
10279    }
10280 }
10281 static int reload_config(void)
10282 {
10283    char *config = "iax.conf";
10284    struct iax2_registry *reg;
10285 
10286    if (set_config(config, 1) > 0) {
10287       prune_peers();
10288       prune_users();
10289       AST_LIST_LOCK(&registrations);
10290       AST_LIST_TRAVERSE(&registrations, reg, entry)
10291          iax2_do_register(reg);
10292       AST_LIST_UNLOCK(&registrations);
10293       /* Qualify hosts, too */
10294       poke_all_peers();
10295    }
10296    reload_firmware(0);
10297    iax_provision_reload();
10298 
10299    return 0;
10300 }
10301 
10302 static int iax2_reload(int fd, int argc, char *argv[])
10303 {
10304    return reload_config();
10305 }
10306 
10307 static int reload(void)
10308 {
10309    return reload_config();
10310 }
10311 
10312 static int cache_get_callno_locked(const char *data)
10313 {
10314    struct sockaddr_in sin;
10315    int x;
10316    int callno;
10317    struct iax_ie_data ied;
10318    struct create_addr_info cai;
10319    struct parsed_dial_string pds;
10320    char *tmpstr;
10321 
10322    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10323       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10324          look up entries for a single context */
10325       if (!ast_mutex_trylock(&iaxsl[x])) {
10326          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10327             return x;
10328          ast_mutex_unlock(&iaxsl[x]);
10329       }
10330    }
10331 
10332    /* No match found, we need to create a new one */
10333 
10334    memset(&cai, 0, sizeof(cai));
10335    memset(&ied, 0, sizeof(ied));
10336    memset(&pds, 0, sizeof(pds));
10337 
10338    tmpstr = ast_strdupa(data);
10339    parse_dial_string(tmpstr, &pds);
10340 
10341    if (ast_strlen_zero(pds.peer)) {
10342       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10343       return -1;
10344    }
10345 
10346    /* Populate our address from the given */
10347    if (create_addr(pds.peer, NULL, &sin, &cai))
10348       return -1;
10349 
10350    if (option_debug)
10351       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10352          pds.peer, pds.username, pds.password, pds.context);
10353 
10354    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10355    if (callno < 1) {
10356       ast_log(LOG_WARNING, "Unable to create call\n");
10357       return -1;
10358    }
10359 
10360    ast_string_field_set(iaxs[callno], dproot, data);
10361    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10362 
10363    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10364    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10365    /* the string format is slightly different from a standard dial string,
10366       because the context appears in the 'exten' position
10367    */
10368    if (pds.exten)
10369       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10370    if (pds.username)
10371       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10372    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10373    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10374    /* Keep password handy */
10375    if (pds.password)
10376       ast_string_field_set(iaxs[callno], secret, pds.password);
10377    if (pds.key)
10378       ast_string_field_set(iaxs[callno], outkey, pds.key);
10379    /* Start the call going */
10380    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10381 
10382    return callno;
10383 }
10384 
10385 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10386 {
10387    struct iax2_dpcache *dp, *prev = NULL, *next;
10388    struct timeval tv;
10389    int x;
10390    int com[2];
10391    int timeout;
10392    int old=0;
10393    int outfd;
10394    int abort;
10395    int callno;
10396    struct ast_channel *c;
10397    struct ast_frame *f;
10398    gettimeofday(&tv, NULL);
10399    dp = dpcache;
10400    while(dp) {
10401       next = dp->next;
10402       /* Expire old caches */
10403       if (ast_tvcmp(tv, dp->expiry) > 0) {
10404             /* It's expired, let it disappear */
10405             if (prev)
10406                prev->next = dp->next;
10407             else
10408                dpcache = dp->next;
10409             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10410                /* Free memory and go again */
10411                free(dp);
10412             } else {
10413                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);
10414             }
10415             dp = next;
10416             continue;
10417       }
10418       /* We found an entry that matches us! */
10419       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10420          break;
10421       prev = dp;
10422       dp = next;
10423    }
10424    if (!dp) {
10425       /* No matching entry.  Create a new one. */
10426       /* First, can we make a callno? */
10427       callno = cache_get_callno_locked(data);
10428       if (callno < 0) {
10429          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10430          return NULL;
10431       }
10432       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10433          ast_mutex_unlock(&iaxsl[callno]);
10434          return NULL;
10435       }
10436       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10437       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10438       gettimeofday(&dp->expiry, NULL);
10439       dp->orig = dp->expiry;
10440       /* Expires in 30 mins by default */
10441       dp->expiry.tv_sec += iaxdefaultdpcache;
10442       dp->next = dpcache;
10443       dp->flags = CACHE_FLAG_PENDING;
10444       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10445          dp->waiters[x] = -1;
10446       dpcache = dp;
10447       dp->peer = iaxs[callno]->dpentries;
10448       iaxs[callno]->dpentries = dp;
10449       /* Send the request if we're already up */
10450       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10451          iax2_dprequest(dp, callno);
10452       ast_mutex_unlock(&iaxsl[callno]);
10453    }
10454    /* By here we must have a dp */
10455    if (dp->flags & CACHE_FLAG_PENDING) {
10456       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10457          for a reply to come back so long as it's pending */
10458       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10459          /* Find an empty slot */
10460          if (dp->waiters[x] < 0)
10461             break;
10462       }
10463       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10464          ast_log(LOG_WARNING, "No more waiter positions available\n");
10465          return NULL;
10466       }
10467       if (pipe(com)) {
10468          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10469          return NULL;
10470       }
10471       dp->waiters[x] = com[1];
10472       /* Okay, now we wait */
10473       timeout = iaxdefaulttimeout * 1000;
10474       /* Temporarily unlock */
10475       ast_mutex_unlock(&dpcache_lock);
10476       /* Defer any dtmf */
10477       if (chan)
10478          old = ast_channel_defer_dtmf(chan);
10479       abort = 0;
10480       while(timeout) {
10481          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10482          if (outfd > -1) {
10483             break;
10484          }
10485          if (c) {
10486             f = ast_read(c);
10487             if (f)
10488                ast_frfree(f);
10489             else {
10490                /* Got hung up on, abort! */
10491                break;
10492                abort = 1;
10493             }
10494          }
10495       }
10496       if (!timeout) {
10497          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10498       }
10499       ast_mutex_lock(&dpcache_lock);
10500       dp->waiters[x] = -1;
10501       close(com[1]);
10502       close(com[0]);
10503       if (abort) {
10504          /* Don't interpret anything, just abort.  Not sure what th epoint
10505            of undeferring dtmf on a hung up channel is but hey whatever */
10506          if (!old && chan)
10507             ast_channel_undefer_dtmf(chan);
10508          return NULL;
10509       }
10510       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10511          /* Now to do non-independent analysis the results of our wait */
10512          if (dp->flags & CACHE_FLAG_PENDING) {
10513             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10514                pending.  Don't let it take as long to timeout. */
10515             dp->flags &= ~CACHE_FLAG_PENDING;
10516             dp->flags |= CACHE_FLAG_TIMEOUT;
10517             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10518                systems without leaving it unavailable once the server comes back online */
10519             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10520             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10521                if (dp->waiters[x] > -1)
10522                   write(dp->waiters[x], "asdf", 4);
10523          }
10524       }
10525       /* Our caller will obtain the rest */
10526       if (!old && chan)
10527          ast_channel_undefer_dtmf(chan);
10528    }
10529    return dp;  
10530 }
10531 
10532 /*! \brief Part of the IAX2 switch interface */
10533 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10534 {
10535    struct iax2_dpcache *dp;
10536    int res = 0;
10537 #if 0
10538    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10539 #endif
10540    if ((priority != 1) && (priority != 2))
10541       return 0;
10542    ast_mutex_lock(&dpcache_lock);
10543    dp = find_cache(chan, data, context, exten, priority);
10544    if (dp) {
10545       if (dp->flags & CACHE_FLAG_EXISTS)
10546          res= 1;
10547    }
10548    ast_mutex_unlock(&dpcache_lock);
10549    if (!dp) {
10550       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10551    }
10552    return res;
10553 }
10554 
10555 /*! \brief part of the IAX2 dial plan switch interface */
10556 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10557 {
10558    int res = 0;
10559    struct iax2_dpcache *dp;
10560 #if 0
10561    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10562 #endif
10563    if ((priority != 1) && (priority != 2))
10564       return 0;
10565    ast_mutex_lock(&dpcache_lock);
10566    dp = find_cache(chan, data, context, exten, priority);
10567    if (dp) {
10568       if (dp->flags & CACHE_FLAG_CANEXIST)
10569          res= 1;
10570    }
10571    ast_mutex_unlock(&dpcache_lock);
10572    if (!dp) {
10573       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10574    }
10575    return res;
10576 }
10577 
10578 /*! \brief Part of the IAX2 Switch interface */
10579 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10580 {
10581    int res = 0;
10582    struct iax2_dpcache *dp;
10583 #if 0
10584    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10585 #endif
10586    if ((priority != 1) && (priority != 2))
10587       return 0;
10588    ast_mutex_lock(&dpcache_lock);
10589    dp = find_cache(chan, data, context, exten, priority);
10590    if (dp) {
10591       if (dp->flags & CACHE_FLAG_MATCHMORE)
10592          res= 1;
10593    }
10594    ast_mutex_unlock(&dpcache_lock);
10595    if (!dp) {
10596       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10597    }
10598    return res;
10599 }
10600 
10601 /*! \brief Execute IAX2 dialplan switch */
10602 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10603 {
10604    char odata[256];
10605    char req[256];
10606    char *ncontext;
10607    struct iax2_dpcache *dp;
10608    struct ast_app *dial;
10609 #if 0
10610    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);
10611 #endif
10612    if (priority == 2) {
10613       /* Indicate status, can be overridden in dialplan */
10614       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10615       if (dialstatus) {
10616          dial = pbx_findapp(dialstatus);
10617          if (dial) 
10618             pbx_exec(chan, dial, "");
10619       }
10620       return -1;
10621    } else if (priority != 1)
10622       return -1;
10623    ast_mutex_lock(&dpcache_lock);
10624    dp = find_cache(chan, data, context, exten, priority);
10625    if (dp) {
10626       if (dp->flags & CACHE_FLAG_EXISTS) {
10627          ast_copy_string(odata, data, sizeof(odata));
10628          ncontext = strchr(odata, '/');
10629          if (ncontext) {
10630             *ncontext = '\0';
10631             ncontext++;
10632             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10633          } else {
10634             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10635          }
10636          if (option_verbose > 2)
10637             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10638       } else {
10639          ast_mutex_unlock(&dpcache_lock);
10640          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10641          return -1;
10642       }
10643    }
10644    ast_mutex_unlock(&dpcache_lock);
10645    dial = pbx_findapp("Dial");
10646    if (dial) {
10647       return pbx_exec(chan, dial, req);
10648    } else {
10649       ast_log(LOG_WARNING, "No dial application registered\n");
10650    }
10651    return -1;
10652 }
10653 
10654 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10655 {
10656    struct iax2_peer *peer;
10657    char *peername, *colname;
10658 
10659    peername = ast_strdupa(data);
10660 
10661    /* if our channel, return the IP address of the endpoint of current channel */
10662    if (!strcmp(peername,"CURRENTCHANNEL")) {
10663            unsigned short callno;
10664       if (chan->tech != &iax2_tech)
10665          return -1;
10666       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10667       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10668       return 0;
10669    }
10670 
10671    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10672       *colname++ = '\0';
10673    else if ((colname = strchr(peername, '|')))
10674       *colname++ = '\0';
10675    else
10676       colname = "ip";
10677 
10678    if (!(peer = find_peer(peername, 1)))
10679       return -1;
10680 
10681    if (!strcasecmp(colname, "ip")) {
10682       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10683    } else  if (!strcasecmp(colname, "status")) {
10684       peer_status(peer, buf, len); 
10685    } else  if (!strcasecmp(colname, "mailbox")) {
10686       ast_copy_string(buf, peer->mailbox, len);
10687    } else  if (!strcasecmp(colname, "context")) {
10688       ast_copy_string(buf, peer->context, len);
10689    } else  if (!strcasecmp(colname, "expire")) {
10690       snprintf(buf, len, "%d", peer->expire);
10691    } else  if (!strcasecmp(colname, "dynamic")) {
10692       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10693    } else  if (!strcasecmp(colname, "callerid_name")) {
10694       ast_copy_string(buf, peer->cid_name, len);
10695    } else  if (!strcasecmp(colname, "callerid_num")) {
10696       ast_copy_string(buf, peer->cid_num, len);
10697    } else  if (!strcasecmp(colname, "codecs")) {
10698       ast_getformatname_multiple(buf, len -1, peer->capability);
10699    } else  if (!strncasecmp(colname, "codec[", 6)) {
10700       char *codecnum, *ptr;
10701       int index = 0, codec = 0;
10702       
10703       codecnum = strchr(colname, '[');
10704       *codecnum = '\0';
10705       codecnum++;
10706       if ((ptr = strchr(codecnum, ']'))) {
10707          *ptr = '\0';
10708       }
10709       index = atoi(codecnum);
10710       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10711          ast_copy_string(buf, ast_getformatname(codec), len);
10712       }
10713    }
10714 
10715    peer_unref(peer);
10716 
10717    return 0;
10718 }
10719 
10720 struct ast_custom_function iaxpeer_function = {
10721    .name = "IAXPEER",
10722    .synopsis = "Gets IAX peer information",
10723    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10724    .read = function_iaxpeer,
10725    .desc = "If peername specified, valid items are:\n"
10726    "- ip (default)          The IP address.\n"
10727    "- status                The peer's status (if qualify=yes)\n"
10728    "- mailbox               The configured mailbox.\n"
10729    "- context               The configured context.\n"
10730    "- expire                The epoch time of the next expire.\n"
10731    "- dynamic               Is it dynamic? (yes/no).\n"
10732    "- callerid_name         The configured Caller ID name.\n"
10733    "- callerid_num          The configured Caller ID number.\n"
10734    "- codecs                The configured codecs.\n"
10735    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10736    "\n"
10737    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10738    "\n"
10739 };
10740 
10741 
10742 /*! \brief Part of the device state notification system ---*/
10743 static int iax2_devicestate(void *data) 
10744 {
10745    struct parsed_dial_string pds;
10746    char *tmp = ast_strdupa(data);
10747    struct iax2_peer *p;
10748    int res = AST_DEVICE_INVALID;
10749 
10750    memset(&pds, 0, sizeof(pds));
10751    parse_dial_string(tmp, &pds);
10752 
10753    if (ast_strlen_zero(pds.peer)) {
10754       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10755       return res;
10756    }
10757    
10758    if (option_debug > 2)
10759       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10760 
10761    /* SLD: FIXME: second call to find_peer during registration */
10762    if (!(p = find_peer(pds.peer, 1)))
10763       return res;
10764 
10765    res = AST_DEVICE_UNAVAILABLE;
10766    if (option_debug > 2) 
10767       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10768          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10769    
10770    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10771        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10772       /* Peer is registered, or have default IP address
10773          and a valid registration */
10774       if (p->historicms == 0 || p->historicms <= p->maxms)
10775          /* let the core figure out whether it is in use or not */
10776          res = AST_DEVICE_UNKNOWN;  
10777    }
10778 
10779    peer_unref(p);
10780 
10781    return res;
10782 }
10783 
10784 static struct ast_switch iax2_switch = 
10785 {
10786    name:          "IAX2",
10787    description:      "IAX Remote Dialplan Switch",
10788    exists:        iax2_exists,
10789    canmatch:      iax2_canmatch,
10790    exec:       iax2_exec,
10791    matchmore:     iax2_matchmore,
10792 };
10793 
10794 static char show_stats_usage[] =
10795 "Usage: iax2 show stats\n"
10796 "       Display statistics on IAX channel driver.\n";
10797 
10798 static char show_cache_usage[] =
10799 "Usage: iax2 show cache\n"
10800 "       Display currently cached IAX Dialplan results.\n";
10801 
10802 static char show_peer_usage[] =
10803 "Usage: iax2 show peer <name>\n"
10804 "       Display details on specific IAX peer\n";
10805 
10806 static char prune_realtime_usage[] =
10807 "Usage: iax2 prune realtime [<peername>|all]\n"
10808 "       Prunes object(s) from the cache\n";
10809 
10810 static char iax2_reload_usage[] =
10811 "Usage: iax2 reload\n"
10812 "       Reloads IAX configuration from iax.conf\n";
10813 
10814 static char show_prov_usage[] =
10815 "Usage: iax2 provision <host> <template> [forced]\n"
10816 "       Provisions the given peer or IP address using a template\n"
10817 "       matching either 'template' or '*' if the template is not\n"
10818 "       found.  If 'forced' is specified, even empty provisioning\n"
10819 "       fields will be provisioned as empty fields.\n";
10820 
10821 static char show_users_usage[] = 
10822 "Usage: iax2 show users [like <pattern>]\n"
10823 "       Lists all known IAX2 users.\n"
10824 "       Optional regular expression pattern is used to filter the user list.\n";
10825 
10826 static char show_channels_usage[] = 
10827 "Usage: iax2 show channels\n"
10828 "       Lists all currently active IAX channels.\n";
10829 
10830 static char show_netstats_usage[] = 
10831 "Usage: iax2 show netstats\n"
10832 "       Lists network status for all currently active IAX channels.\n";
10833 
10834 static char show_threads_usage[] = 
10835 "Usage: iax2 show threads\n"
10836 "       Lists status of IAX helper threads\n";
10837 
10838 static char show_peers_usage[] = 
10839 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10840 "       Lists all known IAX2 peers.\n"
10841 "       Optional 'registered' argument lists only peers with known addresses.\n"
10842 "       Optional regular expression pattern is used to filter the peer list.\n";
10843 
10844 static char show_firmware_usage[] = 
10845 "Usage: iax2 show firmware\n"
10846 "       Lists all known IAX firmware images.\n";
10847 
10848 static char show_reg_usage[] =
10849 "Usage: iax2 show registry\n"
10850 "       Lists all registration requests and status.\n";
10851 
10852 static char debug_usage[] = 
10853 "Usage: iax2 set debug\n"
10854 "       Enables dumping of IAX packets for debugging purposes\n";
10855 
10856 static char no_debug_usage[] = 
10857 "Usage: iax2 set debug off\n"
10858 "       Disables dumping of IAX packets for debugging purposes\n";
10859 
10860 static char debug_trunk_usage[] =
10861 "Usage: iax2 set debug trunk\n"
10862 "       Requests current status of IAX trunking\n";
10863 
10864 static char no_debug_trunk_usage[] =
10865 "Usage: iax2 set debug trunk off\n"
10866 "       Requests current status of IAX trunking\n";
10867 
10868 static char debug_jb_usage[] =
10869 "Usage: iax2 set debug jb\n"
10870 "       Enables jitterbuffer debugging information\n";
10871 
10872 static char no_debug_jb_usage[] =
10873 "Usage: iax2 set debug jb off\n"
10874 "       Disables jitterbuffer debugging information\n";
10875 
10876 static char iax2_test_losspct_usage[] =
10877 "Usage: iax2 test losspct <percentage>\n"
10878 "       For testing, throws away <percentage> percent of incoming packets\n";
10879 
10880 #ifdef IAXTESTS
10881 static char iax2_test_late_usage[] =
10882 "Usage: iax2 test late <ms>\n"
10883 "       For testing, count the next frame as <ms> ms late\n";
10884 
10885 static char iax2_test_resync_usage[] =
10886 "Usage: iax2 test resync <ms>\n"
10887 "       For testing, adjust all future frames by <ms> ms\n";
10888 
10889 static char iax2_test_jitter_usage[] =
10890 "Usage: iax2 test jitter <ms> <pct>\n"
10891 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10892 #endif /* IAXTESTS */
10893 
10894 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10895    { "iax2", "trunk", "debug", NULL },
10896    iax2_do_trunk_debug, NULL,
10897    NULL };
10898 
10899 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10900    { "iax2", "jb", "debug", NULL },
10901    iax2_do_jb_debug, NULL,
10902    NULL };
10903 
10904 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10905    { "iax2", "no", "debug", NULL },
10906    iax2_no_debug, NULL,
10907    NULL };
10908 
10909 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10910    { "iax2", "no", "trunk", "debug", NULL },
10911    iax2_no_trunk_debug, NULL,
10912    NULL };
10913 
10914 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10915    { "iax2", "no", "jb", "debug", NULL },
10916    iax2_no_jb_debug, NULL,
10917    NULL };
10918 
10919 static struct ast_cli_entry cli_iax2[] = {
10920    { { "iax2", "show", "cache", NULL },
10921    iax2_show_cache, "Display IAX cached dialplan",
10922    show_cache_usage, NULL, },
10923 
10924    { { "iax2", "show", "channels", NULL },
10925    iax2_show_channels, "List active IAX channels",
10926    show_channels_usage, NULL, },
10927 
10928    { { "iax2", "show", "firmware", NULL },
10929    iax2_show_firmware, "List available IAX firmwares",
10930    show_firmware_usage, NULL, },
10931 
10932    { { "iax2", "show", "netstats", NULL },
10933    iax2_show_netstats, "List active IAX channel netstats",
10934    show_netstats_usage, NULL, },
10935 
10936    { { "iax2", "show", "peers", NULL },
10937    iax2_show_peers, "List defined IAX peers",
10938    show_peers_usage, NULL, },
10939 
10940    { { "iax2", "show", "registry", NULL },
10941    iax2_show_registry, "Display IAX registration status",
10942    show_reg_usage, NULL, },
10943 
10944    { { "iax2", "show", "stats", NULL },
10945    iax2_show_stats, "Display IAX statistics",
10946    show_stats_usage, NULL, },
10947 
10948    { { "iax2", "show", "threads", NULL },
10949    iax2_show_threads, "Display IAX helper thread info",
10950    show_threads_usage, NULL, },
10951 
10952    { { "iax2", "show", "users", NULL },
10953    iax2_show_users, "List defined IAX users",
10954    show_users_usage, NULL, },
10955 
10956    { { "iax2", "prune", "realtime", NULL },
10957    iax2_prune_realtime, "Prune a cached realtime lookup",
10958    prune_realtime_usage, complete_iax2_show_peer },
10959 
10960    { { "iax2", "reload", NULL },
10961    iax2_reload, "Reload IAX configuration",
10962    iax2_reload_usage },
10963 
10964    { { "iax2", "show", "peer", NULL },
10965    iax2_show_peer, "Show details on specific IAX peer",
10966    show_peer_usage, complete_iax2_show_peer },
10967 
10968    { { "iax2", "set", "debug", NULL },
10969    iax2_do_debug, "Enable IAX debugging",
10970    debug_usage },
10971 
10972    { { "iax2", "set", "debug", "trunk", NULL },
10973    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10974    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10975 
10976    { { "iax2", "set", "debug", "jb", NULL },
10977    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10978    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10979 
10980    { { "iax2", "set", "debug", "off", NULL },
10981    iax2_no_debug, "Disable IAX debugging",
10982    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10983 
10984    { { "iax2", "set", "debug", "trunk", "off", NULL },
10985    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10986    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10987 
10988    { { "iax2", "set", "debug", "jb", "off", NULL },
10989    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10990    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10991 
10992    { { "iax2", "test", "losspct", NULL },
10993    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10994    iax2_test_losspct_usage },
10995 
10996    { { "iax2", "provision", NULL },
10997    iax2_prov_cmd, "Provision an IAX device",
10998    show_prov_usage, iax2_prov_complete_template_3rd },
10999 
11000 #ifdef IAXTESTS
11001    { { "iax2", "test", "late", NULL },
11002    iax2_test_late, "Test the receipt of a late frame",
11003    iax2_test_late_usage },
11004 
11005    { { "iax2", "test", "resync", NULL },
11006    iax2_test_resync, "Test a resync in received timestamps",
11007    iax2_test_resync_usage },
11008 
11009    { { "iax2", "test", "jitter", NULL },
11010    iax2_test_jitter, "Simulates jitter for testing",
11011    iax2_test_jitter_usage },
11012 #endif /* IAXTESTS */
11013 };
11014 
11015 static int __unload_module(void)
11016 {
11017    struct iax2_thread *thread = NULL;
11018    int x;
11019 
11020    /* Make sure threads do not hold shared resources when they are canceled */
11021    
11022    /* Grab the sched lock resource to keep it away from threads about to die */
11023    /* Cancel the network thread, close the net socket */
11024    if (netthreadid != AST_PTHREADT_NULL) {
11025       AST_LIST_LOCK(&iaxq.queue);
11026       ast_mutex_lock(&sched_lock);
11027       pthread_cancel(netthreadid);
11028       ast_cond_signal(&sched_cond);
11029       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11030       AST_LIST_UNLOCK(&iaxq.queue);
11031       pthread_join(netthreadid, NULL);
11032    }
11033    if (schedthreadid != AST_PTHREADT_NULL) {
11034       ast_mutex_lock(&sched_lock);  
11035       pthread_cancel(schedthreadid);
11036       ast_cond_signal(&sched_cond);
11037       ast_mutex_unlock(&sched_lock);   
11038       pthread_join(schedthreadid, NULL);
11039    }
11040    
11041    /* Call for all threads to halt */
11042    AST_LIST_LOCK(&idle_list);
11043    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11044       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11045       pthread_cancel(thread->threadid);
11046    }
11047    AST_LIST_TRAVERSE_SAFE_END
11048    AST_LIST_UNLOCK(&idle_list);
11049 
11050    AST_LIST_LOCK(&active_list);
11051    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11052       AST_LIST_REMOVE_CURRENT(&active_list, list);
11053       pthread_cancel(thread->threadid);
11054    }
11055    AST_LIST_TRAVERSE_SAFE_END
11056    AST_LIST_UNLOCK(&active_list);
11057 
11058    AST_LIST_LOCK(&dynamic_list);
11059         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11060       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11061       pthread_cancel(thread->threadid);
11062         }
11063    AST_LIST_TRAVERSE_SAFE_END
11064         AST_LIST_UNLOCK(&dynamic_list);
11065 
11066    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11067 
11068    /* Wait for threads to exit */
11069    while(0 < iaxactivethreadcount)
11070       usleep(10000);
11071    
11072    ast_netsock_release(netsock);
11073    ast_netsock_release(outsock);
11074    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11075       if (iaxs[x]) {
11076          iax2_destroy(x);
11077       }
11078    }
11079    ast_manager_unregister( "IAXpeers" );
11080    ast_manager_unregister( "IAXnetstats" );
11081    ast_unregister_application(papp);
11082    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11083    ast_unregister_switch(&iax2_switch);
11084    ast_channel_unregister(&iax2_tech);
11085    delete_users();
11086    iax_provision_unload();
11087    sched_context_destroy(sched);
11088    reload_firmware(1);
11089 
11090    ast_mutex_destroy(&waresl.lock);
11091 
11092    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11093       ast_mutex_destroy(&iaxsl[x]);
11094    }
11095 
11096    ao2_ref(peers, -1);
11097    ao2_ref(users, -1);
11098    ao2_ref(iax_peercallno_pvts, -1);
11099 
11100    return 0;
11101 }
11102 
11103 static int unload_module(void)
11104 {
11105    ast_custom_function_unregister(&iaxpeer_function);
11106    return __unload_module();
11107 }
11108 
11109 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11110 {
11111    struct iax2_peer *peer = obj;
11112 
11113    if (peer->sockfd < 0)
11114       peer->sockfd = defaultsockfd;
11115 
11116    return 0;
11117 }
11118 
11119 static int pvt_hash_cb(const void *obj, const int flags)
11120 {
11121    const struct chan_iax2_pvt *pvt = obj;
11122 
11123    return pvt->peercallno;
11124 }
11125 
11126 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11127 {
11128    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11129 
11130    /* The frames_received field is used to hold whether we're matching
11131     * against a full frame or not ... */
11132 
11133    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11134       pvt2->frames_received) ? CMP_MATCH : 0;
11135 }
11136 
11137 /*! \brief Load IAX2 module, load configuraiton ---*/
11138 static int load_module(void)
11139 {
11140    char *config = "iax.conf";
11141    int res = 0;
11142    int x;
11143    struct iax2_registry *reg = NULL;
11144 
11145    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11146    if (!peers)
11147       return AST_MODULE_LOAD_FAILURE;
11148    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11149    if (!users) {
11150       ao2_ref(peers, -1);
11151       return AST_MODULE_LOAD_FAILURE;
11152    }
11153    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11154    if (!iax_peercallno_pvts) {
11155       ao2_ref(peers, -1);
11156       ao2_ref(users, -1);
11157       return AST_MODULE_LOAD_FAILURE;
11158    }
11159 
11160    ast_custom_function_register(&iaxpeer_function);
11161 
11162    iax_set_output(iax_debug_output);
11163    iax_set_error(iax_error_output);
11164    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11165    
11166 #ifdef HAVE_ZAPTEL
11167 #ifdef ZT_TIMERACK
11168    timingfd = open("/dev/zap/timer", O_RDWR);
11169    if (timingfd < 0)
11170 #endif
11171       timingfd = open("/dev/zap/pseudo", O_RDWR);
11172    if (timingfd < 0) 
11173       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11174 #endif      
11175 
11176    memset(iaxs, 0, sizeof(iaxs));
11177 
11178    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11179       ast_mutex_init(&iaxsl[x]);
11180    }
11181    
11182    ast_cond_init(&sched_cond, NULL);
11183 
11184    io = io_context_create();
11185    sched = sched_context_create();
11186    
11187    if (!io || !sched) {
11188       ast_log(LOG_ERROR, "Out of memory\n");
11189       return -1;
11190    }
11191 
11192    netsock = ast_netsock_list_alloc();
11193    if (!netsock) {
11194       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11195       return -1;
11196    }
11197    ast_netsock_init(netsock);
11198 
11199    outsock = ast_netsock_list_alloc();
11200    if (!outsock) {
11201       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11202       return -1;
11203    }
11204    ast_netsock_init(outsock);
11205 
11206    ast_mutex_init(&waresl.lock);
11207 
11208    AST_LIST_HEAD_INIT(&iaxq.queue);
11209    
11210    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11211 
11212    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11213    
11214    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11215    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11216 
11217    if(set_config(config, 0) == -1)
11218       return AST_MODULE_LOAD_DECLINE;
11219 
11220    if (ast_channel_register(&iax2_tech)) {
11221       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11222       __unload_module();
11223       return -1;
11224    }
11225 
11226    if (ast_register_switch(&iax2_switch)) 
11227       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11228 
11229    res = start_network_thread();
11230    if (!res) {
11231       if (option_verbose > 1) 
11232          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11233    } else {
11234       ast_log(LOG_ERROR, "Unable to start network thread\n");
11235       ast_netsock_release(netsock);
11236       ast_netsock_release(outsock);
11237    }
11238 
11239    AST_LIST_LOCK(&registrations);
11240    AST_LIST_TRAVERSE(&registrations, reg, entry)
11241       iax2_do_register(reg);
11242    AST_LIST_UNLOCK(&registrations); 
11243 
11244    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11245    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11246 
11247    reload_firmware(0);
11248    iax_provision_reload();
11249    return res;
11250 }
11251 
11252 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11253       .load = load_module,
11254       .unload = unload_module,
11255       .reload = reload,
11256           );

Generated on Sun Dec 18 20:55:38 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6