Sat Apr 18 23:45:00 2009

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * Hangup cause signalling implementation by
00015  * Levent Guendogdu <levon@feature-it.com>
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Implementation of Inter-Asterisk eXchange Version 2
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  *
00028  * \par See also
00029  * \arg \ref Config_iax
00030  *
00031  * \ingroup channel_drivers
00032  */
00033 
00034 /*** MODULEINFO
00035    <use>zaptel</use>
00036         <depend>res_features</depend>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <sys/types.h>
00046 #include <sys/mman.h>
00047 #include <dirent.h>
00048 #include <sys/socket.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #include <netinet/in_systm.h>
00052 #include <netinet/ip.h>
00053 #include <sys/time.h>
00054 #include <sys/signal.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include <strings.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netdb.h>
00061 #include <fcntl.h>
00062 #include <sys/stat.h>
00063 #include <regex.h>
00064 
00065 #ifdef HAVE_ZAPTEL
00066 #include <sys/ioctl.h>
00067 #include <zaptel/zaptel.h>
00068 #endif
00069 
00070 #include "asterisk/lock.h"
00071 #include "asterisk/frame.h" 
00072 #include "asterisk/channel.h"
00073 #include "asterisk/logger.h"
00074 #include "asterisk/module.h"
00075 #include "asterisk/pbx.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/io.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/options.h"
00080 #include "asterisk/cli.h"
00081 #include "asterisk/translate.h"
00082 #include "asterisk/md5.h"
00083 #include "asterisk/cdr.h"
00084 #include "asterisk/crypto.h"
00085 #include "asterisk/acl.h"
00086 #include "asterisk/manager.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/app.h"
00089 #include "asterisk/astdb.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/utils.h"
00093 #include "asterisk/causes.h"
00094 #include "asterisk/localtime.h"
00095 #include "asterisk/aes.h"
00096 #include "asterisk/dnsmgr.h"
00097 #include "asterisk/devicestate.h"
00098 #include "asterisk/netsock.h"
00099 #include "asterisk/stringfields.h"
00100 #include "asterisk/linkedlists.h"
00101 #include "asterisk/astobj2.h"
00102 
00103 #include "iax2.h"
00104 #include "iax2-parser.h"
00105 #include "iax2-provision.h"
00106 #include "jitterbuf.h"
00107 
00108 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00109    multithreaded mode. */
00110 #define SCHED_MULTITHREADED
00111 
00112 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00113    thread is actually doing. */
00114 #define DEBUG_SCHED_MULTITHREAD
00115 
00116 #ifndef IPTOS_MINCOST
00117 #define IPTOS_MINCOST 0x02
00118 #endif
00119 
00120 #ifdef SO_NO_CHECK
00121 static int nochecksums = 0;
00122 #endif
00123 
00124 
00125 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00126 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00127 
00128 #define DEFAULT_THREAD_COUNT 10
00129 #define DEFAULT_MAX_THREAD_COUNT 100
00130 #define DEFAULT_RETRY_TIME 1000
00131 #define MEMORY_SIZE 100
00132 #define DEFAULT_DROP 3
00133 
00134 #define DEBUG_SUPPORT
00135 
00136 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00137 
00138 /* Sample over last 100 units to determine historic jitter */
00139 #define GAMMA (0.01)
00140 
00141 static struct ast_codec_pref prefs;
00142 
00143 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00144 
00145 static char context[80] = "default";
00146 
00147 static char language[MAX_LANGUAGE] = "";
00148 static char regcontext[AST_MAX_CONTEXT] = "";
00149 
00150 static int maxauthreq = 3;
00151 static int max_retries = 4;
00152 static int ping_time = 21;
00153 static int lagrq_time = 10;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 
00162 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00163 
00164 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00165 
00166 static unsigned int tos = 0;
00167 
00168 static int min_reg_expire;
00169 static int max_reg_expire;
00170 
00171 static int timingfd = -1;           /* Timing file descriptor */
00172 
00173 static struct ast_netsock_list *netsock;
00174 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00175 static int defaultsockfd = -1;
00176 
00177 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00178 
00179 /* Ethernet, etc */
00180 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00181 /* T1, maybe ISDN */
00182 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00183                 ~AST_FORMAT_SLINEAR &        \
00184                 ~AST_FORMAT_ULAW &        \
00185                 ~AST_FORMAT_ALAW &        \
00186                 ~AST_FORMAT_G722) 
00187 /* A modem */
00188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00189                 ~AST_FORMAT_G726 &        \
00190                 ~AST_FORMAT_G726_AAL2 &      \
00191                 ~AST_FORMAT_ADPCM)
00192 
00193 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00194                 ~AST_FORMAT_G723_1)
00195 
00196 
00197 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00198 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00199 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00200 
00201 static   struct io_context *io;
00202 static   struct sched_context *sched;
00203 
00204 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00205 
00206 static int iaxdebug = 0;
00207 
00208 static int iaxtrunkdebug = 0;
00209 
00210 static int test_losspct = 0;
00211 #ifdef IAXTESTS
00212 static int test_late = 0;
00213 static int test_resync = 0;
00214 static int test_jit = 0;
00215 static int test_jitpct = 0;
00216 #endif /* IAXTESTS */
00217 
00218 static char accountcode[AST_MAX_ACCOUNT_CODE];
00219 static char mohinterpret[MAX_MUSICCLASS];
00220 static char mohsuggest[MAX_MUSICCLASS];
00221 static int amaflags = 0;
00222 static int adsi = 0;
00223 static int delayreject = 0;
00224 static int iax2_encryption = 0;
00225 
00226 static struct ast_flags globalflags = { 0 };
00227 
00228 static pthread_t netthreadid = AST_PTHREADT_NULL;
00229 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00230 AST_MUTEX_DEFINE_STATIC(sched_lock);
00231 static ast_cond_t sched_cond;
00232 
00233 enum {
00234    IAX_STATE_STARTED =     (1 << 0),
00235    IAX_STATE_AUTHENTICATED =  (1 << 1),
00236    IAX_STATE_TBD =      (1 << 2),
00237    IAX_STATE_UNCHANGED =      (1 << 3),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00272                        response, so that we've achieved a three-way handshake with
00273                        them before sending voice or anything else*/
00274    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00275 } iax2_flags;
00276 
00277 static int global_rtautoclear = 120;
00278 
00279 static int reload_config(void);
00280 static int iax2_reload(int fd, int argc, char *argv[]);
00281 
00282 
00283 struct iax2_user {
00284    AST_DECLARE_STRING_FIELDS(
00285       AST_STRING_FIELD(name);
00286       AST_STRING_FIELD(secret);
00287       AST_STRING_FIELD(dbsecret);
00288       AST_STRING_FIELD(accountcode);
00289       AST_STRING_FIELD(mohinterpret);
00290       AST_STRING_FIELD(mohsuggest);
00291       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00292       AST_STRING_FIELD(language);
00293       AST_STRING_FIELD(cid_num);
00294       AST_STRING_FIELD(cid_name);
00295    );
00296    
00297    int authmethods;
00298    int encmethods;
00299    int amaflags;
00300    int adsi;
00301    unsigned int flags;
00302    int capability;
00303    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00304    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00305    struct ast_codec_pref prefs;
00306    struct ast_ha *ha;
00307    struct iax2_context *contexts;
00308    struct ast_variable *vars;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361 };
00362 
00363 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00364 
00365 static struct iax2_trunk_peer {
00366    ast_mutex_t lock;
00367    int sockfd;
00368    struct sockaddr_in addr;
00369    struct timeval txtrunktime;      /*!< Transmit trunktime */
00370    struct timeval rxtrunktime;      /*!< Receive trunktime */
00371    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00372    struct timeval trunkact;      /*!< Last trunk activity */
00373    unsigned int lastsent;        /*!< Last sent time */
00374    /* Trunk data and length */
00375    unsigned char *trunkdata;
00376    unsigned int trunkdatalen;
00377    unsigned int trunkdataalloc;
00378    struct iax2_trunk_peer *next;
00379    int trunkerror;
00380    int calls;
00381 } *tpeers = NULL;
00382 
00383 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00384 
00385 struct iax_firmware {
00386    struct iax_firmware *next;
00387    int fd;
00388    int mmaplen;
00389    int dead;
00390    struct ast_iax2_firmware_header *fwh;
00391    unsigned char *buf;
00392 };
00393 
00394 enum iax_reg_state {
00395    REG_STATE_UNREGISTERED = 0,
00396    REG_STATE_REGSENT,
00397    REG_STATE_AUTHSENT,
00398    REG_STATE_REGISTERED,
00399    REG_STATE_REJECTED,
00400    REG_STATE_TIMEOUT,
00401    REG_STATE_NOAUTH
00402 };
00403 
00404 enum iax_transfer_state {
00405    TRANSFER_NONE = 0,
00406    TRANSFER_BEGIN,
00407    TRANSFER_READY,
00408    TRANSFER_RELEASED,
00409    TRANSFER_PASSTHROUGH,
00410    TRANSFER_MBEGIN,
00411    TRANSFER_MREADY,
00412    TRANSFER_MRELEASED,
00413    TRANSFER_MPASSTHROUGH,
00414    TRANSFER_MEDIA,
00415    TRANSFER_MEDIAPASS
00416 };
00417 
00418 struct iax2_registry {
00419    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00420    char username[80];
00421    char secret[80];        /*!< Password or key name in []'s */
00422    char random[80];
00423    int expire;          /*!< Sched ID of expiration */
00424    int refresh;            /*!< How often to refresh */
00425    enum iax_reg_state regstate;
00426    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00427    int callno;          /*!< Associated call number if applicable */
00428    struct sockaddr_in us;        /*!< Who the server thinks we are */
00429    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00430    AST_LIST_ENTRY(iax2_registry) entry;
00431 };
00432 
00433 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00434 
00435 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00436 #define MIN_RETRY_TIME     100
00437 #define MAX_RETRY_TIME     10000
00438 
00439 #define MAX_JITTER_BUFFER  50
00440 #define MIN_JITTER_BUFFER  10
00441 
00442 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00443 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00444 
00445 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00446 
00447 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00448 #define TS_GAP_FOR_JB_RESYNC  5000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxactivethreadcount = 0;
00454 
00455 struct iax_rr {
00456    int jitter;
00457    int losspct;
00458    int losscnt;
00459    int packets;
00460    int delay;
00461    int dropped;
00462    int ooo;
00463 };
00464 
00465 struct chan_iax2_pvt {
00466    /*! Socket to send/receive on for this call */
00467    int sockfd;
00468    /*! Last received voice format */
00469    int voiceformat;
00470    /*! Last received video format */
00471    int videoformat;
00472    /*! Last sent voice format */
00473    int svoiceformat;
00474    /*! Last sent video format */
00475    int svideoformat;
00476    /*! What we are capable of sending */
00477    int capability;
00478    /*! Last received timestamp */
00479    unsigned int last;
00480    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00481    unsigned int lastsent;
00482    /*! Timestamp of the last video frame sent */
00483    unsigned int lastvsent;
00484    /*! Next outgoing timestamp if everything is good */
00485    unsigned int nextpred;
00486    /*! True if the last voice we transmitted was not silence/CNG */
00487    int notsilenttx;
00488    /*! Ping time */
00489    unsigned int pingtime;
00490    /*! Max time for initial response */
00491    int maxtime;
00492    /*! Peer Address */
00493    struct sockaddr_in addr;
00494    /*! Actual used codec preferences */
00495    struct ast_codec_pref prefs;
00496    /*! Requested codec preferences */
00497    struct ast_codec_pref rprefs;
00498    /*! Our call number */
00499    unsigned short callno;
00500    /*! Peer callno */
00501    unsigned short peercallno;
00502    /*! Negotiated format, this is only used to remember what format was
00503        chosen for an unauthenticated call so that the channel can get
00504        created later using the right format */
00505    int chosenformat;
00506    /*! Peer selected format */
00507    int peerformat;
00508    /*! Peer capability */
00509    int peercapability;
00510    /*! timeval that we base our transmission on */
00511    struct timeval offset;
00512    /*! timeval that we base our delivery on */
00513    struct timeval rxcore;
00514    /*! The jitterbuffer */
00515         jitterbuf *jb;
00516    /*! active jb read scheduler id */
00517         int jbid;                       
00518    /*! LAG */
00519    int lag;
00520    /*! Error, as discovered by the manager */
00521    int error;
00522    /*! Owner if we have one */
00523    struct ast_channel *owner;
00524    /*! What's our state? */
00525    struct ast_flags state;
00526    /*! Expiry (optional) */
00527    int expiry;
00528    /*! Next outgoing sequence number */
00529    unsigned char oseqno;
00530    /*! Next sequence number they have not yet acknowledged */
00531    unsigned char rseqno;
00532    /*! Next incoming sequence number */
00533    unsigned char iseqno;
00534    /*! Last incoming sequence number we have acknowledged */
00535    unsigned char aseqno;
00536 
00537    AST_DECLARE_STRING_FIELDS(
00538       /*! Peer name */
00539       AST_STRING_FIELD(peer);
00540       /*! Default Context */
00541       AST_STRING_FIELD(context);
00542       /*! Caller ID if available */
00543       AST_STRING_FIELD(cid_num);
00544       AST_STRING_FIELD(cid_name);
00545       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00546       AST_STRING_FIELD(ani);
00547       /*! DNID */
00548       AST_STRING_FIELD(dnid);
00549       /*! RDNIS */
00550       AST_STRING_FIELD(rdnis);
00551       /*! Requested Extension */
00552       AST_STRING_FIELD(exten);
00553       /*! Expected Username */
00554       AST_STRING_FIELD(username);
00555       /*! Expected Secret */
00556       AST_STRING_FIELD(secret);
00557       /*! MD5 challenge */
00558       AST_STRING_FIELD(challenge);
00559       /*! Public keys permitted keys for incoming authentication */
00560       AST_STRING_FIELD(inkeys);
00561       /*! Private key for outgoing authentication */
00562       AST_STRING_FIELD(outkey);
00563       /*! Preferred language */
00564       AST_STRING_FIELD(language);
00565       /*! Hostname/peername for naming purposes */
00566       AST_STRING_FIELD(host);
00567 
00568       AST_STRING_FIELD(dproot);
00569       AST_STRING_FIELD(accountcode);
00570       AST_STRING_FIELD(mohinterpret);
00571       AST_STRING_FIELD(mohsuggest);
00572    );
00573    
00574    /*! permitted authentication methods */
00575    int authmethods;
00576    /*! permitted encryption methods */
00577    int encmethods;
00578    /*! Encryption AES-128 Key */
00579    aes_encrypt_ctx ecx;
00580    /*! Decryption AES-128 Key corresponding to ecx */
00581    aes_decrypt_ctx mydcx;
00582    /*! Decryption AES-128 Key used to decrypt peer frames */
00583    aes_decrypt_ctx dcx;
00584    /*! 32 bytes of semi-random data */
00585    unsigned char semirand[32];
00586    /*! Associated registry */
00587    struct iax2_registry *reg;
00588    /*! Associated peer for poking */
00589    struct iax2_peer *peerpoke;
00590    /*! IAX_ flags */
00591    unsigned int flags;
00592    int adsi;
00593 
00594    /*! Transferring status */
00595    enum iax_transfer_state transferring;
00596    /*! Transfer identifier */
00597    int transferid;
00598    /*! Who we are IAX transfering to */
00599    struct sockaddr_in transfer;
00600    /*! What's the new call number for the transfer */
00601    unsigned short transfercallno;
00602    /*! Transfer decrypt AES-128 Key */
00603    aes_encrypt_ctx tdcx;
00604 
00605    /*! Status of knowledge of peer ADSI capability */
00606    int peeradsicpe;
00607 
00608    /*! Who we are bridged to */
00609    unsigned short bridgecallno;
00610    
00611    int pingid;       /*!< Transmit PING request */
00612    int lagid;        /*!< Retransmit lag request */
00613    int autoid;       /*!< Auto hangup for Dialplan requestor */
00614    int authid;       /*!< Authentication rejection ID */
00615    int authfail;        /*!< Reason to report failure */
00616    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00617    int calling_ton;
00618    int calling_tns;
00619    int calling_pres;
00620    int amaflags;
00621    struct iax2_dpcache *dpentries;
00622    struct ast_variable *vars;
00623    /*! last received remote rr */
00624    struct iax_rr remote_rr;
00625    /*! Current base time: (just for stats) */
00626    int min;
00627    /*! Dropped frame count: (just for stats) */
00628    int frames_dropped;
00629    /*! received frame count: (just for stats) */
00630    int frames_received;
00631 };
00632 
00633 static struct ast_iax2_queue {
00634    AST_LIST_HEAD(, iax_frame) queue;
00635    int count;
00636 } iaxq;
00637 
00638 /*!
00639  * This module will get much higher performance when doing a lot of
00640  * user and peer lookups if the number of buckets is increased from 1.
00641  * However, to maintain old behavior for Asterisk 1.4, these are set to
00642  * 1 by default.  When using multiple buckets, search order through these
00643  * containers is considered random, so you will not be able to depend on
00644  * the order the entires are specified in iax.conf for matching order. */
00645 #ifdef LOW_MEMORY
00646 #define MAX_PEER_BUCKETS 1
00647 /* #define MAX_PEER_BUCKETS 17 */
00648 #else
00649 #define MAX_PEER_BUCKETS 1
00650 /* #define MAX_PEER_BUCKETS 563 */
00651 #endif
00652 static struct ao2_container *peers;
00653 
00654 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00655 static struct ao2_container *users;
00656 
00657 static struct ast_firmware_list {
00658    struct iax_firmware *wares;
00659    ast_mutex_t lock;
00660 } waresl;
00661 
00662 /*! Extension exists */
00663 #define CACHE_FLAG_EXISTS     (1 << 0)
00664 /*! Extension is nonexistent */
00665 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00666 /*! Extension can exist */
00667 #define CACHE_FLAG_CANEXIST      (1 << 2)
00668 /*! Waiting to hear back response */
00669 #define CACHE_FLAG_PENDING    (1 << 3)
00670 /*! Timed out */
00671 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00672 /*! Request transmitted */
00673 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00674 /*! Timeout */
00675 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00676 /*! Matchmore */
00677 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00678 
00679 static struct iax2_dpcache {
00680    char peercontext[AST_MAX_CONTEXT];
00681    char exten[AST_MAX_EXTENSION];
00682    struct timeval orig;
00683    struct timeval expiry;
00684    int flags;
00685    unsigned short callno;
00686    int waiters[256];
00687    struct iax2_dpcache *next;
00688    struct iax2_dpcache *peer; /*!< For linking in peers */
00689 } *dpcache;
00690 
00691 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00692 
00693 static void reg_source_db(struct iax2_peer *p);
00694 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00695 
00696 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00697 
00698 #define IAX_IOSTATE_IDLE      0
00699 #define IAX_IOSTATE_READY     1
00700 #define IAX_IOSTATE_PROCESSING   2
00701 #define IAX_IOSTATE_SCHEDREADY   3
00702 
00703 #define IAX_TYPE_POOL    1
00704 #define IAX_TYPE_DYNAMIC 2
00705 
00706 struct iax2_pkt_buf {
00707    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00708    size_t len;
00709    unsigned char buf[1];
00710 };
00711 
00712 struct iax2_thread {
00713    AST_LIST_ENTRY(iax2_thread) list;
00714    int type;
00715    int iostate;
00716 #ifdef SCHED_MULTITHREADED
00717    void (*schedfunc)(const void *);
00718    const void *scheddata;
00719 #endif
00720 #ifdef DEBUG_SCHED_MULTITHREAD
00721    char curfunc[80];
00722 #endif   
00723    int actions;
00724    pthread_t threadid;
00725    int threadnum;
00726    struct sockaddr_in iosin;
00727    unsigned char readbuf[4096]; 
00728    unsigned char *buf;
00729    ssize_t buf_len;
00730    size_t buf_size;
00731    int iofd;
00732    time_t checktime;
00733    ast_mutex_t lock;
00734    ast_cond_t cond;
00735    unsigned int ready_for_signal:1;
00736    /*! if this thread is processing a full frame,
00737      some information about that frame will be stored
00738      here, so we can avoid dispatching any more full
00739      frames for that callno to other threads */
00740    struct {
00741       unsigned short callno;
00742       struct sockaddr_in sin;
00743       unsigned char type;
00744       unsigned char csub;
00745    } ffinfo;
00746    /*! Queued up full frames for processing.  If more full frames arrive for
00747     *  a call which this thread is already processing a full frame for, they
00748     *  are queued up here. */
00749    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00750 };
00751 
00752 /* Thread lists */
00753 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00754 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00755 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00756 
00757 static void *iax2_process_thread(void *data);
00758 
00759 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00760 {
00761    ast_mutex_lock(lock);
00762    ast_cond_signal(cond);
00763    ast_mutex_unlock(lock);
00764 }
00765 
00766 static void iax_debug_output(const char *data)
00767 {
00768    if (iaxdebug)
00769       ast_verbose("%s", data);
00770 }
00771 
00772 static void iax_error_output(const char *data)
00773 {
00774    ast_log(LOG_WARNING, "%s", data);
00775 }
00776 
00777 static void jb_error_output(const char *fmt, ...)
00778 {
00779    va_list args;
00780    char buf[1024];
00781 
00782    va_start(args, fmt);
00783    vsnprintf(buf, 1024, fmt, args);
00784    va_end(args);
00785 
00786    ast_log(LOG_ERROR, buf);
00787 }
00788 
00789 static void jb_warning_output(const char *fmt, ...)
00790 {
00791    va_list args;
00792    char buf[1024];
00793 
00794    va_start(args, fmt);
00795    vsnprintf(buf, 1024, fmt, args);
00796    va_end(args);
00797 
00798    ast_log(LOG_WARNING, buf);
00799 }
00800 
00801 static void jb_debug_output(const char *fmt, ...)
00802 {
00803    va_list args;
00804    char buf[1024];
00805 
00806    va_start(args, fmt);
00807    vsnprintf(buf, 1024, fmt, args);
00808    va_end(args);
00809 
00810    ast_verbose(buf);
00811 }
00812 
00813 /* XXX We probably should use a mutex when working with this XXX */
00814 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00815 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00816 static struct timeval lastused[ARRAY_LEN(iaxs)];
00817 
00818 /*!
00819  * \brief Another container of iax2_pvt structures
00820  *
00821  * Active IAX2 pvt structs are also stored in this container, if they are a part
00822  * of an active call where we know the remote side's call number.  The reason
00823  * for this is that incoming media frames do not contain our call number.  So,
00824  * instead of having to iterate the entire iaxs array, we use this container to
00825  * look up calls where the remote side is using a given call number.
00826  */
00827 static struct ao2_container *iax_peercallno_pvts;
00828 
00829 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00830    but keeps the division between trunked and non-trunked better. */
00831 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00832 
00833 static int maxtrunkcall = TRUNK_CALL_START;
00834 static int maxnontrunkcall = 1;
00835 
00836 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);
00837 static int expire_registry(const void *data);
00838 static int iax2_answer(struct ast_channel *c);
00839 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00840 static int iax2_devicestate(void *data);
00841 static int iax2_digit_begin(struct ast_channel *c, char digit);
00842 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00843 static int iax2_do_register(struct iax2_registry *reg);
00844 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00845 static int iax2_hangup(struct ast_channel *c);
00846 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00847 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00848 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00849 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00850 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00851 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00852 static int iax2_sendtext(struct ast_channel *c, const char *text);
00853 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00854 static int iax2_transfer(struct ast_channel *c, const char *dest);
00855 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00856 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00857 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00858 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00859 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00860 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00861 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00862 static struct ast_frame *iax2_read(struct ast_channel *c);
00863 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00864 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00865 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00866 static void prune_peers(void);
00867 
00868 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00869 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00870 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00871   
00872 static const struct ast_channel_tech iax2_tech = {
00873    .type = "IAX2",
00874    .description = tdesc,
00875    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00876    .properties = AST_CHAN_TP_WANTSJITTER,
00877    .requester = iax2_request,
00878    .devicestate = iax2_devicestate,
00879    .send_digit_begin = iax2_digit_begin,
00880    .send_digit_end = iax2_digit_end,
00881    .send_text = iax2_sendtext,
00882    .send_image = iax2_sendimage,
00883    .send_html = iax2_sendhtml,
00884    .call = iax2_call,
00885    .hangup = iax2_hangup,
00886    .answer = iax2_answer,
00887    .read = iax2_read,
00888    .write = iax2_write,
00889    .write_video = iax2_write,
00890    .indicate = iax2_indicate,
00891    .setoption = iax2_setoption,
00892    .bridge = iax2_bridge,
00893    .transfer = iax2_transfer,
00894    .fixup = iax2_fixup,
00895 };
00896 
00897 /* WARNING: insert_idle_thread should only ever be called within the
00898  * context of an iax2_process_thread() thread.
00899  */
00900 static void insert_idle_thread(struct iax2_thread *thread)
00901 {
00902    if (thread->type == IAX_TYPE_DYNAMIC) {
00903       AST_LIST_LOCK(&dynamic_list);
00904       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00905       AST_LIST_UNLOCK(&dynamic_list);
00906    } else {
00907       AST_LIST_LOCK(&idle_list);
00908       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00909       AST_LIST_UNLOCK(&idle_list);
00910    }
00911 
00912    return;
00913 }
00914 
00915 static struct iax2_thread *find_idle_thread(void)
00916 {
00917    pthread_attr_t attr;
00918    struct iax2_thread *thread = NULL;
00919 
00920    /* Pop the head of the list off */
00921    AST_LIST_LOCK(&idle_list);
00922    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00923    AST_LIST_UNLOCK(&idle_list);
00924 
00925    /* If no idle thread is available from the regular list, try dynamic */
00926    if (thread == NULL) {
00927       AST_LIST_LOCK(&dynamic_list);
00928       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00929       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00930       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00931          /* We need to MAKE a thread! */
00932          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00933             thread->threadnum = iaxdynamicthreadcount;
00934             thread->type = IAX_TYPE_DYNAMIC;
00935             ast_mutex_init(&thread->lock);
00936             ast_cond_init(&thread->cond, NULL);
00937             pthread_attr_init(&attr);
00938             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00939             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00940                free(thread);
00941                thread = NULL;
00942             } else {
00943                /* All went well and the thread is up, so increment our count */
00944                iaxdynamicthreadcount++;
00945                
00946                /* Wait for the thread to be ready before returning it to the caller */
00947                while (!thread->ready_for_signal)
00948                   usleep(1);
00949             }
00950          }
00951       }
00952       AST_LIST_UNLOCK(&dynamic_list);
00953    }
00954 
00955    /* this thread is not processing a full frame (since it is idle),
00956       so ensure that the field for the full frame call number is empty */
00957    if (thread)
00958       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00959 
00960    return thread;
00961 }
00962 
00963 #ifdef SCHED_MULTITHREADED
00964 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00965 {
00966    struct iax2_thread *thread = NULL;
00967    static time_t lasterror;
00968    static time_t t;
00969 
00970    thread = find_idle_thread();
00971 
00972    if (thread != NULL) {
00973       thread->schedfunc = func;
00974       thread->scheddata = data;
00975       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00976 #ifdef DEBUG_SCHED_MULTITHREAD
00977       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00978 #endif
00979       signal_condition(&thread->lock, &thread->cond);
00980       return 0;
00981    }
00982    time(&t);
00983    if (t != lasterror && option_debug) 
00984       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00985    lasterror = t;
00986 
00987    return -1;
00988 }
00989 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00990 #endif
00991 
00992 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00993 {
00994    int res;
00995 
00996    res = ast_sched_add(con, when, callback, data);
00997    signal_condition(&sched_lock, &sched_cond);
00998 
00999    return res;
01000 }
01001 
01002 static int send_ping(const void *data);
01003 
01004 static void __send_ping(const void *data)
01005 {
01006    int callno = (long) data;
01007 
01008    ast_mutex_lock(&iaxsl[callno]);
01009 
01010    while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01011       if (iaxs[callno]->peercallno) {
01012          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01013       }
01014       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01015       break;
01016    }
01017 
01018    ast_mutex_unlock(&iaxsl[callno]);
01019 }
01020 
01021 static int send_ping(const void *data)
01022 {
01023 #ifdef SCHED_MULTITHREADED
01024    if (schedule_action(__send_ping, data))
01025 #endif      
01026       __send_ping(data);
01027    return 0;
01028 }
01029 
01030 static int get_encrypt_methods(const char *s)
01031 {
01032    int e;
01033    if (!strcasecmp(s, "aes128"))
01034       e = IAX_ENCRYPT_AES128;
01035    else if (ast_true(s))
01036       e = IAX_ENCRYPT_AES128;
01037    else
01038       e = 0;
01039    return e;
01040 }
01041 
01042 static int send_lagrq(const void *data);
01043 
01044 static void __send_lagrq(const void *data)
01045 {
01046    int callno = (long) data;
01047 
01048    ast_mutex_lock(&iaxsl[callno]);
01049 
01050    while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01051       if (iaxs[callno]->peercallno) {
01052          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01053       }
01054       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01055       break;
01056    }
01057 
01058    ast_mutex_unlock(&iaxsl[callno]);
01059 }
01060 
01061 static int send_lagrq(const void *data)
01062 {
01063 #ifdef SCHED_MULTITHREADED
01064    if (schedule_action(__send_lagrq, data))
01065 #endif      
01066       __send_lagrq(data);
01067    return 0;
01068 }
01069 
01070 static unsigned char compress_subclass(int subclass)
01071 {
01072    int x;
01073    int power=-1;
01074    /* If it's 128 or smaller, just return it */
01075    if (subclass < IAX_FLAG_SC_LOG)
01076       return subclass;
01077    /* Otherwise find its power */
01078    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01079       if (subclass & (1 << x)) {
01080          if (power > -1) {
01081             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01082             return 0;
01083          } else
01084             power = x;
01085       }
01086    }
01087    return power | IAX_FLAG_SC_LOG;
01088 }
01089 
01090 static int uncompress_subclass(unsigned char csub)
01091 {
01092    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01093    if (csub & IAX_FLAG_SC_LOG) {
01094       /* special case for 'compressed' -1 */
01095       if (csub == 0xff)
01096          return -1;
01097       else
01098          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01099    }
01100    else
01101       return csub;
01102 }
01103 
01104 /*!
01105  * \note The only member of the peer passed here guaranteed to be set is the name field
01106  */
01107 static int peer_hash_cb(const void *obj, const int flags)
01108 {
01109    const struct iax2_peer *peer = obj;
01110 
01111    return ast_str_hash(peer->name);
01112 }
01113 
01114 /*!
01115  * \note The only member of the peer passed here guaranteed to be set is the name field
01116  */
01117 static int peer_cmp_cb(void *obj, void *arg, int flags)
01118 {
01119    struct iax2_peer *peer = obj, *peer2 = arg;
01120 
01121    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01122 }
01123 
01124 /*!
01125  * \note The only member of the user passed here guaranteed to be set is the name field
01126  */
01127 static int user_hash_cb(const void *obj, const int flags)
01128 {
01129    const struct iax2_user *user = obj;
01130 
01131    return ast_str_hash(user->name);
01132 }
01133 
01134 /*!
01135  * \note The only member of the user passed here guaranteed to be set is the name field
01136  */
01137 static int user_cmp_cb(void *obj, void *arg, int flags)
01138 {
01139    struct iax2_user *user = obj, *user2 = arg;
01140 
01141    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01142 }
01143 
01144 /*!
01145  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01146  *       so do not call it with a pvt lock held.
01147  */
01148 static struct iax2_peer *find_peer(const char *name, int realtime) 
01149 {
01150    struct iax2_peer *peer = NULL;
01151    struct iax2_peer tmp_peer = {
01152       .name = name,
01153    };
01154 
01155    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01156 
01157    /* Now go for realtime if applicable */
01158    if(!peer && realtime)
01159       peer = realtime_peer(name, NULL);
01160 
01161    return peer;
01162 }
01163 
01164 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01165 {
01166    ao2_ref(peer, +1);
01167    return peer;
01168 }
01169 
01170 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01171 {
01172    ao2_ref(peer, -1);
01173    return NULL;
01174 }
01175 
01176 static inline struct iax2_user *user_ref(struct iax2_user *user)
01177 {
01178    ao2_ref(user, +1);
01179    return user;
01180 }
01181 
01182 static inline struct iax2_user *user_unref(struct iax2_user *user)
01183 {
01184    ao2_ref(user, -1);
01185    return NULL;
01186 }
01187 
01188 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01189 {
01190    struct iax2_peer *peer = NULL;
01191    int res = 0;
01192    struct ao2_iterator i;
01193 
01194    i = ao2_iterator_init(peers, 0);
01195    while ((peer = ao2_iterator_next(&i))) {
01196       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01197           (peer->addr.sin_port == sin.sin_port)) {
01198          ast_copy_string(host, peer->name, len);
01199          peer_unref(peer);
01200          res = 1;
01201          break;
01202       }
01203       peer_unref(peer);
01204    }
01205 
01206    if (!peer) {
01207       peer = realtime_peer(NULL, &sin);
01208       if (peer) {
01209          ast_copy_string(host, peer->name, len);
01210          peer_unref(peer);
01211          res = 1;
01212       }
01213    }
01214 
01215    return res;
01216 }
01217 
01218 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01219 {
01220    /* Decrement AUTHREQ count if needed */
01221    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01222       struct iax2_user *user;
01223       struct iax2_user tmp_user = {
01224          .name = pvt->username,
01225       };
01226 
01227       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01228       if (user) {
01229          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01230          user = user_unref(user);       
01231       }
01232 
01233       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01234    }
01235 
01236    /* No more pings or lagrq's */
01237    AST_SCHED_DEL(sched, pvt->pingid);
01238    AST_SCHED_DEL(sched, pvt->lagid);
01239    AST_SCHED_DEL(sched, pvt->autoid);
01240    AST_SCHED_DEL(sched, pvt->authid);
01241    AST_SCHED_DEL(sched, pvt->initid);
01242    AST_SCHED_DEL(sched, pvt->jbid);
01243 }
01244 
01245 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01246 {
01247    if (!pvt->peercallno) {
01248       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01249       return;
01250    }
01251 
01252    ao2_link(iax_peercallno_pvts, pvt);
01253 }
01254 
01255 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01256 {
01257    if (!pvt->peercallno) {
01258       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01259       return;
01260    }
01261 
01262    ao2_unlink(iax_peercallno_pvts, pvt);
01263 }
01264 
01265 static void update_max_trunk(void)
01266 {
01267    int max = TRUNK_CALL_START;
01268    int x;
01269 
01270    /* XXX Prolly don't need locks here XXX */
01271    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01272       if (iaxs[x]) {
01273          max = x + 1;
01274       }
01275    }
01276 
01277    maxtrunkcall = max;
01278    if (option_debug && iaxdebug)
01279       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01280 }
01281 
01282 static void iax2_frame_free(struct iax_frame *fr)
01283 {
01284    AST_SCHED_DEL(sched, fr->retrans);
01285    iax_frame_free(fr);
01286 }
01287 
01288 static void iax2_destroy(int callno)
01289 {
01290    struct chan_iax2_pvt *pvt;
01291    struct ast_channel *owner;
01292 
01293 retry:
01294    pvt = iaxs[callno];
01295    gettimeofday(&lastused[callno], NULL);
01296    
01297    owner = pvt ? pvt->owner : NULL;
01298 
01299    if (owner) {
01300       if (ast_mutex_trylock(&owner->lock)) {
01301          if (option_debug > 2)
01302             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01303          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01304          goto retry;
01305       }
01306    }
01307    if (!owner) {
01308       iaxs[callno] = NULL;
01309    }
01310 
01311    if (pvt) {
01312       if (!owner) {
01313          pvt->owner = NULL;
01314       } else {
01315          /* If there's an owner, prod it to give up */
01316          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01317           * because we already hold the owner channel lock. */
01318          ast_queue_hangup(owner);
01319       }
01320 
01321       if (pvt->peercallno) {
01322          remove_by_peercallno(pvt);
01323       }
01324 
01325       if (!owner) {
01326          ao2_ref(pvt, -1);
01327          pvt = NULL;
01328       }
01329    }
01330 
01331    if (owner) {
01332       ast_mutex_unlock(&owner->lock);
01333    }
01334 
01335    if (callno & 0x4000) {
01336       update_max_trunk();
01337    }
01338 }
01339 
01340 static void pvt_destructor(void *obj)
01341 {
01342    struct chan_iax2_pvt *pvt = obj;
01343    struct iax_frame *cur = NULL;
01344 
01345    iax2_destroy_helper(pvt);
01346 
01347    /* Already gone */
01348    ast_set_flag(pvt, IAX_ALREADYGONE); 
01349 
01350    AST_LIST_LOCK(&iaxq.queue);
01351    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01352       /* Cancel any pending transmissions */
01353       if (cur->callno == pvt->callno) { 
01354          cur->retries = -1;
01355       }
01356    }
01357    AST_LIST_UNLOCK(&iaxq.queue);
01358 
01359    if (pvt->reg) {
01360       pvt->reg->callno = 0;
01361    }
01362 
01363    if (!pvt->owner) {
01364       jb_frame frame;
01365       if (pvt->vars) {
01366           ast_variables_destroy(pvt->vars);
01367           pvt->vars = NULL;
01368       }
01369 
01370       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01371          iax2_frame_free(frame.data);
01372       }
01373 
01374       jb_destroy(pvt->jb);
01375       ast_string_field_free_memory(pvt);
01376    }
01377 }
01378 
01379 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01380 {
01381    struct chan_iax2_pvt *tmp;
01382    jb_conf jbconf;
01383 
01384    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01385       return NULL;
01386    }
01387 
01388    if (ast_string_field_init(tmp, 32)) {
01389       ao2_ref(tmp, -1);
01390       tmp = NULL;
01391       return NULL;
01392    }
01393       
01394    tmp->prefs = prefs;
01395    tmp->callno = 0;
01396    tmp->peercallno = 0;
01397    tmp->transfercallno = 0;
01398    tmp->bridgecallno = 0;
01399    tmp->pingid = -1;
01400    tmp->lagid = -1;
01401    tmp->autoid = -1;
01402    tmp->authid = -1;
01403    tmp->initid = -1;
01404 
01405    ast_string_field_set(tmp,exten, "s");
01406    ast_string_field_set(tmp,host, host);
01407 
01408    tmp->jb = jb_new();
01409    tmp->jbid = -1;
01410    jbconf.max_jitterbuf = maxjitterbuffer;
01411    jbconf.resync_threshold = resyncthreshold;
01412    jbconf.max_contig_interp = maxjitterinterps;
01413    jb_setconf(tmp->jb,&jbconf);
01414 
01415    return tmp;
01416 }
01417 
01418 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01419 {
01420    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01421    if (new) {
01422       size_t afdatalen = new->afdatalen;
01423       memcpy(new, fr, sizeof(*new));
01424       iax_frame_wrap(new, &fr->af);
01425       new->afdatalen = afdatalen;
01426       new->data = NULL;
01427       new->datalen = 0;
01428       new->direction = DIRECTION_INGRESS;
01429       new->retrans = -1;
01430    }
01431    return new;
01432 }
01433 
01434 #define NEW_PREVENT  0
01435 #define NEW_ALLOW    1
01436 #define NEW_FORCE    2
01437 
01438 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01439 {
01440    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01441       (cur->addr.sin_port == sin->sin_port)) {
01442       /* This is the main host */
01443       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01444           (check_dcallno ? dcallno == cur->callno : 1) ) {
01445          /* That's us.  Be sure we keep track of the peer call number */
01446          return 1;
01447       }
01448    }
01449    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01450        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01451       /* We're transferring */
01452       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01453          return 1;
01454    }
01455    return 0;
01456 }
01457 
01458 static void update_max_nontrunk(void)
01459 {
01460    int max = 1;
01461    int x;
01462    /* XXX Prolly don't need locks here XXX */
01463    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01464       if (iaxs[x])
01465          max = x + 1;
01466    }
01467    maxnontrunkcall = max;
01468    if (option_debug && iaxdebug)
01469       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01470 }
01471 
01472 static int make_trunk(unsigned short callno, int locked)
01473 {
01474    int x;
01475    int res= 0;
01476    struct timeval now;
01477    if (iaxs[callno]->oseqno) {
01478       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01479       return -1;
01480    }
01481    if (callno & TRUNK_CALL_START) {
01482       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01483       return -1;
01484    }
01485    gettimeofday(&now, NULL);
01486    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01487       ast_mutex_lock(&iaxsl[x]);
01488       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01489          iaxs[x] = iaxs[callno];
01490          iaxs[x]->callno = x;
01491          iaxs[callno] = NULL;
01492          /* Update the two timers that should have been started */
01493          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01494          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01495          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01496          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01497          if (locked)
01498             ast_mutex_unlock(&iaxsl[callno]);
01499          res = x;
01500          if (!locked)
01501             ast_mutex_unlock(&iaxsl[x]);
01502          break;
01503       }
01504       ast_mutex_unlock(&iaxsl[x]);
01505    }
01506    if (x >= ARRAY_LEN(iaxs) - 1) {
01507       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01508       return -1;
01509    }
01510    if (option_debug)
01511       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01512    /* We move this call from a non-trunked to a trunked call */
01513    update_max_trunk();
01514    update_max_nontrunk();
01515    return res;
01516 }
01517 
01518 /*!
01519  * \note Calling this function while holding another pvt lock can cause a deadlock.
01520  */
01521 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01522 {
01523    int res = 0;
01524    int x;
01525    struct timeval now;
01526    char host[80];
01527 
01528    if (new <= NEW_ALLOW) {
01529       if (callno) {
01530          struct chan_iax2_pvt *pvt;
01531          struct chan_iax2_pvt tmp_pvt = {
01532             .callno = dcallno,
01533             .peercallno = callno,
01534             /* hack!! */
01535             .frames_received = check_dcallno,
01536          };
01537  
01538          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01539  
01540          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01541             if (return_locked) {
01542                ast_mutex_lock(&iaxsl[pvt->callno]);
01543             }
01544             res = pvt->callno;
01545             ao2_ref(pvt, -1);
01546             pvt = NULL;
01547             return res;
01548          }
01549       }
01550 
01551       /* Look for an existing connection first */
01552       for (x = 1; !res && x < maxnontrunkcall; x++) {
01553          ast_mutex_lock(&iaxsl[x]);
01554          if (iaxs[x]) {
01555             /* Look for an exact match */
01556             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01557                res = x;
01558             }
01559          }
01560          if (!res || !return_locked)
01561             ast_mutex_unlock(&iaxsl[x]);
01562       }
01563       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01564          ast_mutex_lock(&iaxsl[x]);
01565          if (iaxs[x]) {
01566             /* Look for an exact match */
01567             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01568                res = x;
01569             }
01570          }
01571          if (!res || !return_locked)
01572             ast_mutex_unlock(&iaxsl[x]);
01573       }
01574    }
01575    if (!res && (new >= NEW_ALLOW)) {
01576       int start, found = 0;
01577 
01578       /* It may seem odd that we look through the peer list for a name for
01579        * this *incoming* call.  Well, it is weird.  However, users don't
01580        * have an IP address/port number that we can match against.  So,
01581        * this is just checking for a peer that has that IP/port and
01582        * assuming that we have a user of the same name.  This isn't always
01583        * correct, but it will be changed if needed after authentication. */
01584       if (!iax2_getpeername(*sin, host, sizeof(host)))
01585          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01586 
01587       now = ast_tvnow();
01588       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01589       for (x = start; 1; x++) {
01590          if (x == TRUNK_CALL_START) {
01591             x = 1;
01592             continue;
01593          }
01594 
01595          /* Find first unused call number that hasn't been used in a while */
01596          ast_mutex_lock(&iaxsl[x]);
01597          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01598             found = 1;
01599             break;
01600          }
01601          ast_mutex_unlock(&iaxsl[x]);
01602          
01603          if (x == start - 1) {
01604             break;
01605          }
01606       }
01607       /* We've still got lock held if we found a spot */
01608       if (x == start - 1 && !found) {
01609          ast_log(LOG_WARNING, "No more space\n");
01610          return 0;
01611       }
01612       iaxs[x] = new_iax(sin, host);
01613       update_max_nontrunk();
01614       if (iaxs[x]) {
01615          if (option_debug && iaxdebug)
01616             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01617          iaxs[x]->sockfd = sockfd;
01618          iaxs[x]->addr.sin_port = sin->sin_port;
01619          iaxs[x]->addr.sin_family = sin->sin_family;
01620          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01621          iaxs[x]->peercallno = callno;
01622          iaxs[x]->callno = x;
01623          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01624          iaxs[x]->expiry = min_reg_expire;
01625          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01626          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01627          iaxs[x]->amaflags = amaflags;
01628          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01629          
01630          ast_string_field_set(iaxs[x], accountcode, accountcode);
01631          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01632          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01633 
01634          if (iaxs[x]->peercallno) {
01635             store_by_peercallno(iaxs[x]);
01636          }
01637       } else {
01638          ast_log(LOG_WARNING, "Out of resources\n");
01639          ast_mutex_unlock(&iaxsl[x]);
01640          return 0;
01641       }
01642       if (!return_locked)
01643          ast_mutex_unlock(&iaxsl[x]);
01644       res = x;
01645    }
01646    return res;
01647 }
01648 
01649 static int find_callno(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, 0, full_frame);
01652 }
01653 
01654 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01655 
01656    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01657 }
01658 
01659 /*!
01660  * \brief Queue a frame to a call's owning asterisk channel
01661  *
01662  * \pre This function assumes that iaxsl[callno] is locked when called.
01663  *
01664  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01665  * was valid before calling it, it may no longer be valid after calling it.
01666  * This function may unlock and lock the mutex associated with this callno,
01667  * meaning that another thread may grab it and destroy the call.
01668  */
01669 static int iax2_queue_frame(int callno, struct ast_frame *f)
01670 {
01671    for (;;) {
01672       if (iaxs[callno] && iaxs[callno]->owner) {
01673          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01674             /* Avoid deadlock by pausing and trying again */
01675             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01676          } else {
01677             ast_queue_frame(iaxs[callno]->owner, f);
01678             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01679             break;
01680          }
01681       } else
01682          break;
01683    }
01684    return 0;
01685 }
01686 
01687 /*!
01688  * \brief Queue a hangup frame on the ast_channel owner
01689  *
01690  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01691  * is active for the given call number.
01692  *
01693  * \pre Assumes lock for callno is already held.
01694  *
01695  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01696  * was valid before calling it, it may no longer be valid after calling it.
01697  * This function may unlock and lock the mutex associated with this callno,
01698  * meaning that another thread may grab it and destroy the call.
01699  */
01700 static int iax2_queue_hangup(int callno)
01701 {
01702    for (;;) {
01703       if (iaxs[callno] && iaxs[callno]->owner) {
01704          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01705             /* Avoid deadlock by pausing and trying again */
01706             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01707          } else {
01708             ast_queue_hangup(iaxs[callno]->owner);
01709             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01710             break;
01711          }
01712       } else
01713          break;
01714    }
01715    return 0;
01716 }
01717 
01718 /*!
01719  * \brief Queue a control frame on the ast_channel owner
01720  *
01721  * This function queues a control frame on the owner of the IAX2 pvt struct that
01722  * is active for the given call number.
01723  *
01724  * \pre Assumes lock for callno is already held.
01725  *
01726  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01727  * was valid before calling it, it may no longer be valid after calling it.
01728  * This function may unlock and lock the mutex associated with this callno,
01729  * meaning that another thread may grab it and destroy the call.
01730  */
01731 static int iax2_queue_control_data(int callno, 
01732    enum ast_control_frame_type control, const void *data, size_t datalen)
01733 {
01734    for (;;) {
01735       if (iaxs[callno] && iaxs[callno]->owner) {
01736          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01737             /* Avoid deadlock by pausing and trying again */
01738             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01739          } else {
01740             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01741             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01742             break;
01743          }
01744       } else
01745          break;
01746    }
01747    return 0;
01748 }
01749 static void destroy_firmware(struct iax_firmware *cur)
01750 {
01751    /* Close firmware */
01752    if (cur->fwh) {
01753       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01754    }
01755    close(cur->fd);
01756    free(cur);
01757 }
01758 
01759 static int try_firmware(char *s)
01760 {
01761    struct stat stbuf;
01762    struct iax_firmware *cur;
01763    int ifd;
01764    int fd;
01765    int res;
01766    
01767    struct ast_iax2_firmware_header *fwh, fwh2;
01768    struct MD5Context md5;
01769    unsigned char sum[16];
01770    unsigned char buf[1024];
01771    int len, chunk;
01772    char *s2;
01773    char *last;
01774    s2 = alloca(strlen(s) + 100);
01775    if (!s2) {
01776       ast_log(LOG_WARNING, "Alloca failed!\n");
01777       return -1;
01778    }
01779    last = strrchr(s, '/');
01780    if (last)
01781       last++;
01782    else
01783       last = s;
01784    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01785    res = stat(s, &stbuf);
01786    if (res < 0) {
01787       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01788       return -1;
01789    }
01790    /* Make sure it's not a directory */
01791    if (S_ISDIR(stbuf.st_mode))
01792       return -1;
01793    ifd = open(s, O_RDONLY);
01794    if (ifd < 0) {
01795       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01796       return -1;
01797    }
01798    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01799    if (fd < 0) {
01800       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01801       close(ifd);
01802       return -1;
01803    }
01804    /* Unlink our newly created file */
01805    unlink(s2);
01806    
01807    /* Now copy the firmware into it */
01808    len = stbuf.st_size;
01809    while(len) {
01810       chunk = len;
01811       if (chunk > sizeof(buf))
01812          chunk = sizeof(buf);
01813       res = read(ifd, buf, chunk);
01814       if (res != chunk) {
01815          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01816          close(ifd);
01817          close(fd);
01818          return -1;
01819       }
01820       res = write(fd, buf, chunk);
01821       if (res != chunk) {
01822          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01823          close(ifd);
01824          close(fd);
01825          return -1;
01826       }
01827       len -= chunk;
01828    }
01829    close(ifd);
01830    /* Return to the beginning */
01831    lseek(fd, 0, SEEK_SET);
01832    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01833       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01834       close(fd);
01835       return -1;
01836    }
01837    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01838       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01839       close(fd);
01840       return -1;
01841    }
01842    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01843       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01844       close(fd);
01845       return -1;
01846    }
01847    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01848       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01849       close(fd);
01850       return -1;
01851    }
01852    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01853    if (fwh == (void *) -1) {
01854       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01855       close(fd);
01856       return -1;
01857    }
01858    MD5Init(&md5);
01859    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01860    MD5Final(sum, &md5);
01861    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01862       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01863       munmap((void*)fwh, stbuf.st_size);
01864       close(fd);
01865       return -1;
01866    }
01867    cur = waresl.wares;
01868    while(cur) {
01869       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01870          /* Found a candidate */
01871          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01872             /* The version we have on loaded is older, load this one instead */
01873             break;
01874          /* This version is no newer than what we have.  Don't worry about it.
01875             We'll consider it a proper load anyhow though */
01876          munmap((void*)fwh, stbuf.st_size);
01877          close(fd);
01878          return 0;
01879       }
01880       cur = cur->next;
01881    }
01882    if (!cur) {
01883       /* Allocate a new one and link it */
01884       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01885          cur->fd = -1;
01886          cur->next = waresl.wares;
01887          waresl.wares = cur;
01888       }
01889    }
01890    if (cur) {
01891       if (cur->fwh) {
01892          munmap((void*)cur->fwh, cur->mmaplen);
01893       }
01894       if (cur->fd > -1)
01895          close(cur->fd);
01896       cur->fwh = fwh;
01897       cur->fd = fd;
01898       cur->mmaplen = stbuf.st_size;
01899       cur->dead = 0;
01900    }
01901    return 0;
01902 }
01903 
01904 static int iax_check_version(char *dev)
01905 {
01906    int res = 0;
01907    struct iax_firmware *cur;
01908    if (!ast_strlen_zero(dev)) {
01909       ast_mutex_lock(&waresl.lock);
01910       cur = waresl.wares;
01911       while(cur) {
01912          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01913             res = ntohs(cur->fwh->version);
01914             break;
01915          }
01916          cur = cur->next;
01917       }
01918       ast_mutex_unlock(&waresl.lock);
01919    }
01920    return res;
01921 }
01922 
01923 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01924 {
01925    int res = -1;
01926    unsigned int bs = desc & 0xff;
01927    unsigned int start = (desc >> 8) & 0xffffff;
01928    unsigned int bytes;
01929    struct iax_firmware *cur;
01930    if (!ast_strlen_zero((char *)dev) && bs) {
01931       start *= bs;
01932       ast_mutex_lock(&waresl.lock);
01933       cur = waresl.wares;
01934       while(cur) {
01935          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01936             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01937             if (start < ntohl(cur->fwh->datalen)) {
01938                bytes = ntohl(cur->fwh->datalen) - start;
01939                if (bytes > bs)
01940                   bytes = bs;
01941                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01942             } else {
01943                bytes = 0;
01944                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01945             }
01946             if (bytes == bs)
01947                res = 0;
01948             else
01949                res = 1;
01950             break;
01951          }
01952          cur = cur->next;
01953       }
01954       ast_mutex_unlock(&waresl.lock);
01955    }
01956    return res;
01957 }
01958 
01959 
01960 static void reload_firmware(int unload)
01961 {
01962    struct iax_firmware *cur, *curl, *curp;
01963    DIR *fwd;
01964    struct dirent *de;
01965    char dir[256];
01966    char fn[256];
01967    /* Mark all as dead */
01968    ast_mutex_lock(&waresl.lock);
01969    cur = waresl.wares;
01970    while(cur) {
01971       cur->dead = 1;
01972       cur = cur->next;
01973    }
01974 
01975    /* Now that we've freed them, load the new ones */
01976    if (!unload) {
01977       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01978       fwd = opendir(dir);
01979       if (fwd) {
01980          while((de = readdir(fwd))) {
01981             if (de->d_name[0] != '.') {
01982                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01983                if (!try_firmware(fn)) {
01984                   if (option_verbose > 1)
01985                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01986                }
01987             }
01988          }
01989          closedir(fwd);
01990       } else 
01991          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01992    }
01993 
01994    /* Clean up leftovers */
01995    cur = waresl.wares;
01996    curp = NULL;
01997    while(cur) {
01998       curl = cur;
01999       cur = cur->next;
02000       if (curl->dead) {
02001          if (curp) {
02002             curp->next = cur;
02003          } else {
02004             waresl.wares = cur;
02005          }
02006          destroy_firmware(curl);
02007       } else {
02008          curp = cur;
02009       }
02010    }
02011    ast_mutex_unlock(&waresl.lock);
02012 }
02013 
02014 /*!
02015  * \note This function assumes that iaxsl[callno] is locked when called.
02016  *
02017  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02018  * was valid before calling it, it may no longer be valid after calling it.
02019  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02020  * associated with this callno, meaning that another thread may grab it and destroy the call.
02021  */
02022 static int __do_deliver(void *data)
02023 {
02024    /* Just deliver the packet by using queueing.  This is called by
02025      the IAX thread with the iaxsl lock held. */
02026    struct iax_frame *fr = data;
02027    fr->retrans = -1;
02028    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02029    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02030       iax2_queue_frame(fr->callno, &fr->af);
02031    /* Free our iax frame */
02032    iax2_frame_free(fr);
02033    /* And don't run again */
02034    return 0;
02035 }
02036 
02037 static int handle_error(void)
02038 {
02039    /* XXX Ideally we should figure out why an error occured and then abort those
02040       rather than continuing to try.  Unfortunately, the published interface does
02041       not seem to work XXX */
02042 #if 0
02043    struct sockaddr_in *sin;
02044    int res;
02045    struct msghdr m;
02046    struct sock_extended_err e;
02047    m.msg_name = NULL;
02048    m.msg_namelen = 0;
02049    m.msg_iov = NULL;
02050    m.msg_control = &e;
02051    m.msg_controllen = sizeof(e);
02052    m.msg_flags = 0;
02053    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02054    if (res < 0)
02055       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02056    else {
02057       if (m.msg_controllen) {
02058          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02059          if (sin) 
02060             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02061          else
02062             ast_log(LOG_WARNING, "No address detected??\n");
02063       } else {
02064          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02065       }
02066    }
02067 #endif
02068    return 0;
02069 }
02070 
02071 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02072 {
02073    int res;
02074    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02075                sizeof(*sin));
02076    if (res < 0) {
02077       if (option_debug)
02078          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02079       handle_error();
02080    } else
02081       res = 0;
02082    return res;
02083 }
02084 
02085 static int send_packet(struct iax_frame *f)
02086 {
02087    int res;
02088    int callno = f->callno;
02089 
02090    /* Don't send if there was an error, but return error instead */
02091    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02092        return -1;
02093    
02094    /* Called with iaxsl held */
02095    if (option_debug > 2 && iaxdebug)
02096       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));
02097    if (f->transfer) {
02098       if (iaxdebug)
02099          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02100       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02101                sizeof(iaxs[callno]->transfer));
02102    } else {
02103       if (iaxdebug)
02104          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02105       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02106                sizeof(iaxs[callno]->addr));
02107    }
02108    if (res < 0) {
02109       if (option_debug && iaxdebug)
02110          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02111       handle_error();
02112    } else
02113       res = 0;
02114    return res;
02115 }
02116 
02117 /*!
02118  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02119  *       for the given call number may disappear during its execution.
02120  */
02121 static int iax2_predestroy(int callno)
02122 {
02123    struct ast_channel *c;
02124    struct chan_iax2_pvt *pvt = iaxs[callno];
02125 
02126    if (!pvt)
02127       return -1;
02128    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02129       iax2_destroy_helper(pvt);
02130       ast_set_flag(pvt, IAX_ALREADYGONE); 
02131    }
02132    c = pvt->owner;
02133    if (c) {
02134       c->tech_pvt = NULL;
02135       iax2_queue_hangup(callno);
02136       pvt->owner = NULL;
02137       ast_module_unref(ast_module_info->self);
02138    }
02139    return 0;
02140 }
02141 
02142 static int update_packet(struct iax_frame *f)
02143 {
02144    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02145    struct ast_iax2_full_hdr *fh = f->data;
02146    struct ast_frame af;
02147 
02148    /* if frame is encrypted. decrypt before updating it. */
02149    if (f->encmethods) {
02150       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02151    }
02152    /* Mark this as a retransmission */
02153    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02154    /* Update iseqno */
02155    f->iseqno = iaxs[f->callno]->iseqno;
02156    fh->iseqno = f->iseqno;
02157 
02158    /* Now re-encrypt the frame */
02159    if (f->encmethods) {
02160       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02161    }
02162    return 0;
02163 }
02164 
02165 static int attempt_transmit(const void *data);
02166 static void __attempt_transmit(const void *data)
02167 {
02168    /* Attempt to transmit the frame to the remote peer...
02169       Called without iaxsl held. */
02170    struct iax_frame *f = (struct iax_frame *)data;
02171    int freeme=0;
02172    int callno = f->callno;
02173    /* Make sure this call is still active */
02174    if (callno) 
02175       ast_mutex_lock(&iaxsl[callno]);
02176    if (callno && iaxs[callno]) {
02177       if ((f->retries < 0) /* Already ACK'd */ ||
02178           (f->retries >= max_retries) /* Too many attempts */) {
02179             /* Record an error if we've transmitted too many times */
02180             if (f->retries >= max_retries) {
02181                if (f->transfer) {
02182                   /* Transfer timeout */
02183                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02184                } else if (f->final) {
02185                   if (f->final) 
02186                      iax2_destroy(callno);
02187                } else {
02188                   if (iaxs[callno]->owner)
02189                      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);
02190                   iaxs[callno]->error = ETIMEDOUT;
02191                   if (iaxs[callno]->owner) {
02192                      struct ast_frame fr = { 0, };
02193                      /* Hangup the fd */
02194                      fr.frametype = AST_FRAME_CONTROL;
02195                      fr.subclass = AST_CONTROL_HANGUP;
02196                      iax2_queue_frame(callno, &fr); // XXX
02197                      /* Remember, owner could disappear */
02198                      if (iaxs[callno] && iaxs[callno]->owner)
02199                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02200                   } else {
02201                      if (iaxs[callno]->reg) {
02202                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02203                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02204                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02205                      }
02206                      iax2_destroy(callno);
02207                   }
02208                }
02209 
02210             }
02211             freeme++;
02212       } else {
02213          /* Update it if it needs it */
02214          update_packet(f);
02215          /* Attempt transmission */
02216          send_packet(f);
02217          f->retries++;
02218          /* Try again later after 10 times as long */
02219          f->retrytime *= 10;
02220          if (f->retrytime > MAX_RETRY_TIME)
02221             f->retrytime = MAX_RETRY_TIME;
02222          /* Transfer messages max out at one second */
02223          if (f->transfer && (f->retrytime > 1000))
02224             f->retrytime = 1000;
02225          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02226       }
02227    } else {
02228       /* Make sure it gets freed */
02229       f->retries = -1;
02230       freeme++;
02231    }
02232    if (callno)
02233       ast_mutex_unlock(&iaxsl[callno]);
02234    /* Do not try again */
02235    if (freeme) {
02236       /* Don't attempt delivery, just remove it from the queue */
02237       AST_LIST_LOCK(&iaxq.queue);
02238       AST_LIST_REMOVE(&iaxq.queue, f, list);
02239       iaxq.count--;
02240       AST_LIST_UNLOCK(&iaxq.queue);
02241       f->retrans = -1;
02242       /* Free the IAX frame */
02243       iax2_frame_free(f);
02244    }
02245 }
02246 
02247 static int attempt_transmit(const void *data)
02248 {
02249 #ifdef SCHED_MULTITHREADED
02250    if (schedule_action(__attempt_transmit, data))
02251 #endif      
02252       __attempt_transmit(data);
02253    return 0;
02254 }
02255 
02256 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02257 {
02258    struct iax2_peer *peer;
02259 
02260    if (argc != 4)
02261         return RESULT_SHOWUSAGE;
02262    if (!strcmp(argv[3],"all")) {
02263       reload_config();
02264       ast_cli(fd, "OK cache is flushed.\n");
02265    } else if ((peer = find_peer(argv[3], 0))) {
02266       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02267          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02268          expire_registry(peer_ref(peer));
02269          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02270       } else {
02271          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02272       }
02273       peer_unref(peer);
02274    } else {
02275       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02276    }
02277    
02278    return RESULT_SUCCESS;
02279 }
02280 
02281 static int iax2_test_losspct(int fd, int argc, char *argv[])
02282 {
02283        if (argc != 4)
02284                return RESULT_SHOWUSAGE;
02285 
02286        test_losspct = atoi(argv[3]);
02287 
02288        return RESULT_SUCCESS;
02289 }
02290 
02291 #ifdef IAXTESTS
02292 static int iax2_test_late(int fd, int argc, char *argv[])
02293 {
02294    if (argc != 4)
02295       return RESULT_SHOWUSAGE;
02296 
02297    test_late = atoi(argv[3]);
02298 
02299    return RESULT_SUCCESS;
02300 }
02301 
02302 static int iax2_test_resync(int fd, int argc, char *argv[])
02303 {
02304    if (argc != 4)
02305       return RESULT_SHOWUSAGE;
02306 
02307    test_resync = atoi(argv[3]);
02308 
02309    return RESULT_SUCCESS;
02310 }
02311 
02312 static int iax2_test_jitter(int fd, int argc, char *argv[])
02313 {
02314    if (argc < 4 || argc > 5)
02315       return RESULT_SHOWUSAGE;
02316 
02317    test_jit = atoi(argv[3]);
02318    if (argc == 5) 
02319       test_jitpct = atoi(argv[4]);
02320 
02321    return RESULT_SUCCESS;
02322 }
02323 #endif /* IAXTESTS */
02324 
02325 /*! \brief  peer_status: Report Peer status in character string */
02326 /*    returns 1 if peer is online, -1 if unmonitored */
02327 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02328 {
02329    int res = 0;
02330    if (peer->maxms) {
02331       if (peer->lastms < 0) {
02332          ast_copy_string(status, "UNREACHABLE", statuslen);
02333       } else if (peer->lastms > peer->maxms) {
02334          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02335          res = 1;
02336       } else if (peer->lastms) {
02337          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02338          res = 1;
02339       } else {
02340          ast_copy_string(status, "UNKNOWN", statuslen);
02341       }
02342    } else { 
02343       ast_copy_string(status, "Unmonitored", statuslen);
02344       res = -1;
02345    }
02346    return res;
02347 }
02348 
02349 /*! \brief Show one peer in detail */
02350 static int iax2_show_peer(int fd, int argc, char *argv[])
02351 {
02352    char status[30];
02353    char cbuf[256];
02354    struct iax2_peer *peer;
02355    char codec_buf[512];
02356    int x = 0, codec = 0, load_realtime = 0;
02357 
02358    if (argc < 4)
02359       return RESULT_SHOWUSAGE;
02360 
02361    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02362 
02363    peer = find_peer(argv[3], load_realtime);
02364    if (peer) {
02365       ast_cli(fd,"\n\n");
02366       ast_cli(fd, "  * Name       : %s\n", peer->name);
02367       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02368       ast_cli(fd, "  Context      : %s\n", peer->context);
02369       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02370       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02371       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02372       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02373       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02374       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));
02375       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02376       ast_cli(fd, "  Username     : %s\n", peer->username);
02377       ast_cli(fd, "  Codecs       : ");
02378       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02379       ast_cli(fd, "%s\n", codec_buf);
02380 
02381       ast_cli(fd, "  Codec Order  : (");
02382       for(x = 0; x < 32 ; x++) {
02383          codec = ast_codec_pref_index(&peer->prefs,x);
02384          if(!codec)
02385             break;
02386          ast_cli(fd, "%s", ast_getformatname(codec));
02387          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02388             ast_cli(fd, "|");
02389       }
02390 
02391       if (!x)
02392          ast_cli(fd, "none");
02393       ast_cli(fd, ")\n");
02394 
02395       ast_cli(fd, "  Status       : ");
02396       peer_status(peer, status, sizeof(status));   
02397       ast_cli(fd, "%s\n",status);
02398       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02399       ast_cli(fd,"\n");
02400       peer_unref(peer);
02401    } else {
02402       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02403       ast_cli(fd,"\n");
02404    }
02405 
02406    return RESULT_SUCCESS;
02407 }
02408 
02409 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02410 {
02411    int which = 0;
02412    struct iax2_peer *peer;
02413    char *res = NULL;
02414    int wordlen = strlen(word);
02415    struct ao2_iterator i;
02416 
02417    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02418    if (pos != 3)
02419       return NULL;
02420 
02421    i = ao2_iterator_init(peers, 0);
02422    while ((peer = ao2_iterator_next(&i))) {
02423       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02424          res = ast_strdup(peer->name);
02425          peer_unref(peer);
02426          break;
02427       }
02428       peer_unref(peer);
02429    }
02430 
02431    return res;
02432 }
02433 
02434 static int iax2_show_stats(int fd, int argc, char *argv[])
02435 {
02436    struct iax_frame *cur;
02437    int cnt = 0, dead=0, final=0;
02438 
02439    if (argc != 3)
02440       return RESULT_SHOWUSAGE;
02441 
02442    AST_LIST_LOCK(&iaxq.queue);
02443    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02444       if (cur->retries < 0)
02445          dead++;
02446       if (cur->final)
02447          final++;
02448       cnt++;
02449    }
02450    AST_LIST_UNLOCK(&iaxq.queue);
02451 
02452    ast_cli(fd, "    IAX Statistics\n");
02453    ast_cli(fd, "---------------------\n");
02454    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02455    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02456    
02457    return RESULT_SUCCESS;
02458 }
02459 
02460 static int iax2_show_cache(int fd, int argc, char *argv[])
02461 {
02462    struct iax2_dpcache *dp;
02463    char tmp[1024], *pc;
02464    int s;
02465    int x,y;
02466    struct timeval tv;
02467    gettimeofday(&tv, NULL);
02468    ast_mutex_lock(&dpcache_lock);
02469    dp = dpcache;
02470    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02471    while(dp) {
02472       s = dp->expiry.tv_sec - tv.tv_sec;
02473       tmp[0] = '\0';
02474       if (dp->flags & CACHE_FLAG_EXISTS)
02475          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02476       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02477          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02478       if (dp->flags & CACHE_FLAG_CANEXIST)
02479          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02480       if (dp->flags & CACHE_FLAG_PENDING)
02481          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02482       if (dp->flags & CACHE_FLAG_TIMEOUT)
02483          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02484       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02485          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02486       if (dp->flags & CACHE_FLAG_MATCHMORE)
02487          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02488       if (dp->flags & CACHE_FLAG_UNKNOWN)
02489          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02490       /* Trim trailing pipe */
02491       if (!ast_strlen_zero(tmp))
02492          tmp[strlen(tmp) - 1] = '\0';
02493       else
02494          ast_copy_string(tmp, "(none)", sizeof(tmp));
02495       y=0;
02496       pc = strchr(dp->peercontext, '@');
02497       if (!pc)
02498          pc = dp->peercontext;
02499       else
02500          pc++;
02501       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02502          if (dp->waiters[x] > -1)
02503             y++;
02504       if (s > 0)
02505          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02506       else
02507          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02508       dp = dp->next;
02509    }
02510    ast_mutex_unlock(&dpcache_lock);
02511    return RESULT_SUCCESS;
02512 }
02513 
02514 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02515 
02516 static void unwrap_timestamp(struct iax_frame *fr)
02517 {
02518    int x;
02519 
02520    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02521       x = fr->ts - iaxs[fr->callno]->last;
02522       if (x < -50000) {
02523          /* Sudden big jump backwards in timestamp:
02524             What likely happened here is that miniframe timestamp has circled but we haven't
02525             gotten the update from the main packet.  We'll just pretend that we did, and
02526             update the timestamp appropriately. */
02527          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02528          if (option_debug && iaxdebug)
02529             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02530       }
02531       if (x > 50000) {
02532          /* Sudden apparent big jump forwards in timestamp:
02533             What's likely happened is this is an old miniframe belonging to the previous
02534             top-16-bit timestamp that has turned up out of order.
02535             Adjust the timestamp appropriately. */
02536          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02537          if (option_debug && iaxdebug)
02538             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02539       }
02540    }
02541 }
02542 
02543 static int get_from_jb(const void *p);
02544 
02545 static void update_jbsched(struct chan_iax2_pvt *pvt)
02546 {
02547    int when;
02548    
02549    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02550    
02551    when = jb_next(pvt->jb) - when;
02552 
02553    AST_SCHED_DEL(sched, pvt->jbid);
02554 
02555    if(when <= 0) {
02556       /* XXX should really just empty until when > 0.. */
02557       when = 1;
02558    }
02559    
02560    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02561 }
02562 
02563 static void __get_from_jb(const void *p) 
02564 {
02565    int callno = PTR_TO_CALLNO(p);
02566    struct chan_iax2_pvt *pvt = NULL;
02567    struct iax_frame *fr;
02568    jb_frame frame;
02569    int ret;
02570    long now;
02571    long next;
02572    struct timeval tv;
02573    
02574    /* Make sure we have a valid private structure before going on */
02575    ast_mutex_lock(&iaxsl[callno]);
02576    pvt = iaxs[callno];
02577    if (!pvt) {
02578       /* No go! */
02579       ast_mutex_unlock(&iaxsl[callno]);
02580       return;
02581    }
02582 
02583    pvt->jbid = -1;
02584    
02585    gettimeofday(&tv,NULL);
02586    /* round up a millisecond since ast_sched_runq does; */
02587    /* prevents us from spinning while waiting for our now */
02588    /* to catch up with runq's now */
02589    tv.tv_usec += 1000;
02590    
02591    now = ast_tvdiff_ms(tv, pvt->rxcore);
02592    
02593    if(now >= (next = jb_next(pvt->jb))) {
02594       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02595       switch(ret) {
02596       case JB_OK:
02597          fr = frame.data;
02598          __do_deliver(fr);
02599          /* __do_deliver() can cause the call to disappear */
02600          pvt = iaxs[callno];
02601          break;
02602       case JB_INTERP:
02603       {
02604          struct ast_frame af = { 0, };
02605          
02606          /* create an interpolation frame */
02607          af.frametype = AST_FRAME_VOICE;
02608          af.subclass = pvt->voiceformat;
02609          af.samples  = frame.ms * 8;
02610          af.src  = "IAX2 JB interpolation";
02611          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02612          af.offset = AST_FRIENDLY_OFFSET;
02613          
02614          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02615           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02616          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02617             iax2_queue_frame(callno, &af);
02618             /* iax2_queue_frame() could cause the call to disappear */
02619             pvt = iaxs[callno];
02620          }
02621       }
02622          break;
02623       case JB_DROP:
02624          iax2_frame_free(frame.data);
02625          break;
02626       case JB_NOFRAME:
02627       case JB_EMPTY:
02628          /* do nothing */
02629          break;
02630       default:
02631          /* shouldn't happen */
02632          break;
02633       }
02634    }
02635    if (pvt)
02636       update_jbsched(pvt);
02637    ast_mutex_unlock(&iaxsl[callno]);
02638 }
02639 
02640 static int get_from_jb(const void *data)
02641 {
02642 #ifdef SCHED_MULTITHREADED
02643    if (schedule_action(__get_from_jb, data))
02644 #endif      
02645       __get_from_jb(data);
02646    return 0;
02647 }
02648 
02649 /*!
02650  * \note This function assumes fr->callno is locked
02651  *
02652  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02653  * was valid before calling it, it may no longer be valid after calling it.
02654  */
02655 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02656 {
02657    int type, len;
02658    int ret;
02659    int needfree = 0;
02660    struct ast_channel *owner = NULL;
02661    struct ast_channel *bridge = NULL;
02662    
02663    /* Attempt to recover wrapped timestamps */
02664    unwrap_timestamp(fr);
02665 
02666    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02667    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02668       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02669    else {
02670 #if 0
02671       if (option_debug)
02672          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02673 #endif
02674       fr->af.delivery = ast_tv(0,0);
02675    }
02676 
02677    type = JB_TYPE_CONTROL;
02678    len = 0;
02679 
02680    if(fr->af.frametype == AST_FRAME_VOICE) {
02681       type = JB_TYPE_VOICE;
02682       len = ast_codec_get_samples(&fr->af) / 8;
02683    } else if(fr->af.frametype == AST_FRAME_CNG) {
02684       type = JB_TYPE_SILENCE;
02685    }
02686 
02687    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02688       if (tsout)
02689          *tsout = fr->ts;
02690       __do_deliver(fr);
02691       return -1;
02692    }
02693 
02694    if ((owner = iaxs[fr->callno]->owner))
02695       bridge = ast_bridged_channel(owner);
02696 
02697    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02698     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02699    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02700       jb_frame frame;
02701 
02702       /* deliver any frames in the jb */
02703       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02704          __do_deliver(frame.data);
02705          /* __do_deliver() can make the call disappear */
02706          if (!iaxs[fr->callno])
02707             return -1;
02708       }
02709 
02710       jb_reset(iaxs[fr->callno]->jb);
02711 
02712       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02713 
02714       /* deliver this frame now */
02715       if (tsout)
02716          *tsout = fr->ts;
02717       __do_deliver(fr);
02718       return -1;
02719    }
02720 
02721    /* insert into jitterbuffer */
02722    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02723    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02724          calc_rxstamp(iaxs[fr->callno],fr->ts));
02725    if (ret == JB_DROP) {
02726       needfree++;
02727    } else if (ret == JB_SCHED) {
02728       update_jbsched(iaxs[fr->callno]);
02729    }
02730    if (tsout)
02731       *tsout = fr->ts;
02732    if (needfree) {
02733       /* Free our iax frame */
02734       iax2_frame_free(fr);
02735       return -1;
02736    }
02737    return 0;
02738 }
02739 
02740 static int iax2_transmit(struct iax_frame *fr)
02741 {
02742    /* Lock the queue and place this packet at the end */
02743    /* By setting this to 0, the network thread will send it for us, and
02744       queue retransmission if necessary */
02745    fr->sentyet = 0;
02746    AST_LIST_LOCK(&iaxq.queue);
02747    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02748    iaxq.count++;
02749    AST_LIST_UNLOCK(&iaxq.queue);
02750    /* Wake up the network and scheduler thread */
02751    if (netthreadid != AST_PTHREADT_NULL)
02752       pthread_kill(netthreadid, SIGURG);
02753    signal_condition(&sched_lock, &sched_cond);
02754    return 0;
02755 }
02756 
02757 
02758 
02759 static int iax2_digit_begin(struct ast_channel *c, char digit)
02760 {
02761    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02762 }
02763 
02764 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02765 {
02766    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02767 }
02768 
02769 static int iax2_sendtext(struct ast_channel *c, const char *text)
02770 {
02771    
02772    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02773       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02774 }
02775 
02776 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02777 {
02778    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02779 }
02780 
02781 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02782 {
02783    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02784 }
02785 
02786 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02787 {
02788    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02789    ast_mutex_lock(&iaxsl[callno]);
02790    if (iaxs[callno])
02791       iaxs[callno]->owner = newchan;
02792    else
02793       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02794    ast_mutex_unlock(&iaxsl[callno]);
02795    return 0;
02796 }
02797 
02798 /*!
02799  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02800  *       so do not call this with a pvt lock held.
02801  */
02802 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02803 {
02804    struct ast_variable *var = NULL;
02805    struct ast_variable *tmp;
02806    struct iax2_peer *peer=NULL;
02807    time_t regseconds = 0, nowtime;
02808    int dynamic=0;
02809 
02810    if (peername) {
02811       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02812       if (!var && sin)
02813          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02814    } else if (sin) {
02815       char porta[25];
02816       sprintf(porta, "%d", ntohs(sin->sin_port));
02817       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02818       if (var) {
02819          /* We'll need the peer name in order to build the structure! */
02820          for (tmp = var; tmp; tmp = tmp->next) {
02821             if (!strcasecmp(tmp->name, "name"))
02822                peername = tmp->value;
02823          }
02824       }
02825    }
02826    if (!var && peername) { /* Last ditch effort */
02827       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02828       /*!\note
02829        * If this one loaded something, then we need to ensure that the host
02830        * field matched.  The only reason why we can't have this as a criteria
02831        * is because we only have the IP address and the host field might be
02832        * set as a name (and the reverse PTR might not match).
02833        */
02834       if (var && sin) {
02835          for (tmp = var; tmp; tmp = tmp->next) {
02836             if (!strcasecmp(tmp->name, "host")) {
02837                struct ast_hostent ahp;
02838                struct hostent *hp;
02839                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02840                   /* No match */
02841                   ast_variables_destroy(var);
02842                   var = NULL;
02843                }
02844                break;
02845             }
02846          }
02847       }
02848    }
02849    if (!var)
02850       return NULL;
02851 
02852    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02853    
02854    if (!peer) {
02855       ast_variables_destroy(var);
02856       return NULL;
02857    }
02858 
02859    for (tmp = var; tmp; tmp = tmp->next) {
02860       /* Make sure it's not a user only... */
02861       if (!strcasecmp(tmp->name, "type")) {
02862          if (strcasecmp(tmp->value, "friend") &&
02863              strcasecmp(tmp->value, "peer")) {
02864             /* Whoops, we weren't supposed to exist! */
02865             peer = peer_unref(peer);
02866             break;
02867          } 
02868       } else if (!strcasecmp(tmp->name, "regseconds")) {
02869          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02870       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02871          inet_aton(tmp->value, &(peer->addr.sin_addr));
02872       } else if (!strcasecmp(tmp->name, "port")) {
02873          peer->addr.sin_port = htons(atoi(tmp->value));
02874       } else if (!strcasecmp(tmp->name, "host")) {
02875          if (!strcasecmp(tmp->value, "dynamic"))
02876             dynamic = 1;
02877       }
02878    }
02879 
02880    ast_variables_destroy(var);
02881 
02882    if (!peer)
02883       return NULL;
02884 
02885    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02886       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02887       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02888          if (peer->expire > -1) {
02889             if (!ast_sched_del(sched, peer->expire)) {
02890                peer->expire = -1;
02891                peer_unref(peer);
02892             }
02893          }
02894          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02895          if (peer->expire == -1)
02896             peer_unref(peer);
02897       }
02898       ao2_link(peers, peer);
02899       if (ast_test_flag(peer, IAX_DYNAMIC))
02900          reg_source_db(peer);
02901    } else {
02902       ast_set_flag(peer, IAX_TEMPONLY);   
02903    }
02904 
02905    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02906       time(&nowtime);
02907       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02908          memset(&peer->addr, 0, sizeof(peer->addr));
02909          realtime_update_peer(peer->name, &peer->addr, 0);
02910          if (option_debug)
02911             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02912                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02913       }
02914       else {
02915          if (option_debug)
02916             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02917                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02918       }
02919    }
02920 
02921    return peer;
02922 }
02923 
02924 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02925 {
02926    struct ast_variable *var;
02927    struct ast_variable *tmp;
02928    struct iax2_user *user=NULL;
02929 
02930    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02931    if (!var)
02932       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02933    if (!var && sin) {
02934       char porta[6];
02935       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02936       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02937       if (!var)
02938          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02939    }
02940    if (!var) { /* Last ditch effort */
02941       var = ast_load_realtime("iaxusers", "name", username, NULL);
02942       /*!\note
02943        * If this one loaded something, then we need to ensure that the host
02944        * field matched.  The only reason why we can't have this as a criteria
02945        * is because we only have the IP address and the host field might be
02946        * set as a name (and the reverse PTR might not match).
02947        */
02948       if (var) {
02949          for (tmp = var; tmp; tmp = tmp->next) {
02950             if (!strcasecmp(tmp->name, "host")) {
02951                struct ast_hostent ahp;
02952                struct hostent *hp;
02953                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02954                   /* No match */
02955                   ast_variables_destroy(var);
02956                   var = NULL;
02957                }
02958                break;
02959             }
02960          }
02961       }
02962    }
02963    if (!var)
02964       return NULL;
02965 
02966    tmp = var;
02967    while(tmp) {
02968       /* Make sure it's not a peer only... */
02969       if (!strcasecmp(tmp->name, "type")) {
02970          if (strcasecmp(tmp->value, "friend") &&
02971              strcasecmp(tmp->value, "user")) {
02972             return NULL;
02973          } 
02974       }
02975       tmp = tmp->next;
02976    }
02977 
02978    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02979 
02980    ast_variables_destroy(var);
02981 
02982    if (!user)
02983       return NULL;
02984 
02985    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02986       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02987       ao2_link(users, user);
02988    } else {
02989       ast_set_flag(user, IAX_TEMPONLY);   
02990    }
02991 
02992    return user;
02993 }
02994 
02995 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02996 {
02997    char port[10];
02998    char regseconds[20];
02999    
03000    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03001    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03002    ast_update_realtime("iaxpeers", "name", peername, 
03003       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03004       "regseconds", regseconds, NULL);
03005 }
03006 
03007 struct create_addr_info {
03008    int capability;
03009    unsigned int flags;
03010    int maxtime;
03011    int encmethods;
03012    int found;
03013    int sockfd;
03014    int adsi;
03015    char username[80];
03016    char secret[80];
03017    char outkey[80];
03018    char timezone[80];
03019    char prefs[32];
03020    char context[AST_MAX_CONTEXT];
03021    char peercontext[AST_MAX_CONTEXT];
03022    char mohinterpret[MAX_MUSICCLASS];
03023    char mohsuggest[MAX_MUSICCLASS];
03024 };
03025 
03026 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03027 {
03028    struct ast_hostent ahp;
03029    struct hostent *hp;
03030    struct iax2_peer *peer;
03031    int res = -1;
03032    struct ast_codec_pref ourprefs;
03033 
03034    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03035    cai->sockfd = defaultsockfd;
03036    cai->maxtime = 0;
03037    sin->sin_family = AF_INET;
03038 
03039    if (!(peer = find_peer(peername, 1))) {
03040       cai->found = 0;
03041 
03042       hp = ast_gethostbyname(peername, &ahp);
03043       if (hp) {
03044          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03045          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03046          /* use global iax prefs for unknown peer/user */
03047          /* But move the calling channel's native codec to the top of the preference list */
03048          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03049          if (c)
03050             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03051          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03052          return 0;
03053       } else {
03054          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03055          return -1;
03056       }
03057    }
03058 
03059    cai->found = 1;
03060    
03061    /* if the peer has no address (current or default), return failure */
03062    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03063       goto return_unref;
03064 
03065    /* if the peer is being monitored and is currently unreachable, return failure */
03066    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03067       goto return_unref;
03068 
03069    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03070    cai->maxtime = peer->maxms;
03071    cai->capability = peer->capability;
03072    cai->encmethods = peer->encmethods;
03073    cai->sockfd = peer->sockfd;
03074    cai->adsi = peer->adsi;
03075    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03076    /* Move the calling channel's native codec to the top of the preference list */
03077    if (c) {
03078       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03079       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03080    }
03081    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03082    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03083    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03084    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03085    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03086    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03087    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03088    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03089    if (ast_strlen_zero(peer->dbsecret)) {
03090       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03091    } else {
03092       char *family;
03093       char *key = NULL;
03094 
03095       family = ast_strdupa(peer->dbsecret);
03096       key = strchr(family, '/');
03097       if (key)
03098          *key++ = '\0';
03099       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03100          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03101          goto return_unref;
03102       }
03103    }
03104 
03105    if (peer->addr.sin_addr.s_addr) {
03106       sin->sin_addr = peer->addr.sin_addr;
03107       sin->sin_port = peer->addr.sin_port;
03108    } else {
03109       sin->sin_addr = peer->defaddr.sin_addr;
03110       sin->sin_port = peer->defaddr.sin_port;
03111    }
03112 
03113    res = 0;
03114 
03115 return_unref:
03116    peer_unref(peer);
03117 
03118    return res;
03119 }
03120 
03121 static void __auto_congest(const void *nothing)
03122 {
03123    int callno = PTR_TO_CALLNO(nothing);
03124    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03125    ast_mutex_lock(&iaxsl[callno]);
03126    if (iaxs[callno]) {
03127       iaxs[callno]->initid = -1;
03128       iax2_queue_frame(callno, &f);
03129       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03130    }
03131    ast_mutex_unlock(&iaxsl[callno]);
03132 }
03133 
03134 static int auto_congest(const void *data)
03135 {
03136 #ifdef SCHED_MULTITHREADED
03137    if (schedule_action(__auto_congest, data))
03138 #endif      
03139       __auto_congest(data);
03140    return 0;
03141 }
03142 
03143 static unsigned int iax2_datetime(const char *tz)
03144 {
03145    time_t t;
03146    struct tm tm;
03147    unsigned int tmp;
03148    time(&t);
03149    if (!ast_strlen_zero(tz))
03150       ast_localtime(&t, &tm, tz);
03151    else
03152       ast_localtime(&t, &tm, NULL);
03153    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03154    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03155    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03156    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03157    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03158    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03159    return tmp;
03160 }
03161 
03162 struct parsed_dial_string {
03163    char *username;
03164    char *password;
03165    char *key;
03166    char *peer;
03167    char *port;
03168    char *exten;
03169    char *context;
03170    char *options;
03171 };
03172 
03173 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03174 {
03175    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03176       .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03177       .csub = compress_subclass(command) };
03178 
03179    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03180 }
03181 
03182 /*!
03183  * \brief Parses an IAX dial string into its component parts.
03184  * \param data the string to be parsed
03185  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03186  * \return nothing
03187  *
03188  * This function parses the string and fills the structure
03189  * with pointers to its component parts. The input string
03190  * will be modified.
03191  *
03192  * \note This function supports both plaintext passwords and RSA
03193  * key names; if the password string is formatted as '[keyname]',
03194  * then the keyname will be placed into the key field, and the
03195  * password field will be set to NULL.
03196  *
03197  * \note The dial string format is:
03198  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03199  */
03200 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03201 {
03202    if (ast_strlen_zero(data))
03203       return;
03204 
03205    pds->peer = strsep(&data, "/");
03206    pds->exten = strsep(&data, "/");
03207    pds->options = data;
03208 
03209    if (pds->exten) {
03210       data = pds->exten;
03211       pds->exten = strsep(&data, "@");
03212       pds->context = data;
03213    }
03214 
03215    if (strchr(pds->peer, '@')) {
03216       data = pds->peer;
03217       pds->username = strsep(&data, "@");
03218       pds->peer = data;
03219    }
03220 
03221    if (pds->username) {
03222       data = pds->username;
03223       pds->username = strsep(&data, ":");
03224       pds->password = data;
03225    }
03226 
03227    data = pds->peer;
03228    pds->peer = strsep(&data, ":");
03229    pds->port = data;
03230 
03231    /* check for a key name wrapped in [] in the secret position, if found,
03232       move it to the key field instead
03233    */
03234    if (pds->password && (pds->password[0] == '[')) {
03235       pds->key = ast_strip_quoted(pds->password, "[", "]");
03236       pds->password = NULL;
03237    }
03238 }
03239 
03240 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03241 {
03242    struct sockaddr_in sin;
03243    char *l=NULL, *n=NULL, *tmpstr;
03244    struct iax_ie_data ied;
03245    char *defaultrdest = "s";
03246    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03247    struct parsed_dial_string pds;
03248    struct create_addr_info cai;
03249 
03250    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03251       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03252       return -1;
03253    }
03254 
03255    memset(&cai, 0, sizeof(cai));
03256    cai.encmethods = iax2_encryption;
03257 
03258    memset(&pds, 0, sizeof(pds));
03259    tmpstr = ast_strdupa(dest);
03260    parse_dial_string(tmpstr, &pds);
03261 
03262    if (ast_strlen_zero(pds.peer)) {
03263       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03264       return -1;
03265    }
03266 
03267    if (!pds.exten) {
03268       pds.exten = defaultrdest;
03269    }
03270 
03271    if (create_addr(pds.peer, c, &sin, &cai)) {
03272       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03273       return -1;
03274    }
03275 
03276    if (!pds.username && !ast_strlen_zero(cai.username))
03277       pds.username = cai.username;
03278    if (!pds.password && !ast_strlen_zero(cai.secret))
03279       pds.password = cai.secret;
03280    if (!pds.key && !ast_strlen_zero(cai.outkey))
03281       pds.key = cai.outkey;
03282    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03283       pds.context = cai.peercontext;
03284 
03285    /* Keep track of the context for outgoing calls too */
03286    ast_copy_string(c->context, cai.context, sizeof(c->context));
03287 
03288    if (pds.port)
03289       sin.sin_port = htons(atoi(pds.port));
03290 
03291    l = c->cid.cid_num;
03292    n = c->cid.cid_name;
03293 
03294    /* Now build request */ 
03295    memset(&ied, 0, sizeof(ied));
03296 
03297    /* On new call, first IE MUST be IAX version of caller */
03298    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03299    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03300    if (pds.options && strchr(pds.options, 'a')) {
03301       /* Request auto answer */
03302       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03303    }
03304 
03305    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03306 
03307    if (l) {
03308       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03309       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03310    } else {
03311       if (n)
03312          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03313       else
03314          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03315    }
03316 
03317    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03318    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03319 
03320    if (n)
03321       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03322    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03323       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03324 
03325    if (!ast_strlen_zero(c->language))
03326       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03327    if (!ast_strlen_zero(c->cid.cid_dnid))
03328       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03329    if (!ast_strlen_zero(c->cid.cid_rdnis))
03330       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03331 
03332    if (pds.context)
03333       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03334 
03335    if (pds.username)
03336       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03337 
03338    if (cai.encmethods)
03339       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03340 
03341    ast_mutex_lock(&iaxsl[callno]);
03342 
03343    if (!ast_strlen_zero(c->context))
03344       ast_string_field_set(iaxs[callno], context, c->context);
03345 
03346    if (pds.username)
03347       ast_string_field_set(iaxs[callno], username, pds.username);
03348 
03349    iaxs[callno]->encmethods = cai.encmethods;
03350 
03351    iaxs[callno]->adsi = cai.adsi;
03352    
03353    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03354    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03355 
03356    if (pds.key)
03357       ast_string_field_set(iaxs[callno], outkey, pds.key);
03358    if (pds.password)
03359       ast_string_field_set(iaxs[callno], secret, pds.password);
03360 
03361    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03362    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03363    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03364    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03365 
03366    if (iaxs[callno]->maxtime) {
03367       /* Initialize pingtime and auto-congest time */
03368       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03369       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03370    } else if (autokill) {
03371       iaxs[callno]->pingtime = autokill / 2;
03372       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03373    }
03374 
03375    /* send the command using the appropriate socket for this peer */
03376    iaxs[callno]->sockfd = cai.sockfd;
03377 
03378    /* Transmit the string in a "NEW" request */
03379    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03380 
03381    ast_mutex_unlock(&iaxsl[callno]);
03382    ast_setstate(c, AST_STATE_RINGING);
03383    
03384    return 0;
03385 }
03386 
03387 static int iax2_hangup(struct ast_channel *c) 
03388 {
03389    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03390    int alreadygone;
03391    struct iax_ie_data ied;
03392    memset(&ied, 0, sizeof(ied));
03393    ast_mutex_lock(&iaxsl[callno]);
03394    if (callno && iaxs[callno]) {
03395       if (option_debug)
03396          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03397       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03398       /* Send the hangup unless we have had a transmission error or are already gone */
03399       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03400       if (!iaxs[callno]->error && !alreadygone) {
03401          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03402          if (!iaxs[callno]) {
03403             ast_mutex_unlock(&iaxsl[callno]);
03404             return 0;
03405          }
03406       }
03407       /* Explicitly predestroy it */
03408       iax2_predestroy(callno);
03409       /* If we were already gone to begin with, destroy us now */
03410       if (alreadygone && iaxs[callno]) {
03411          if (option_debug)
03412             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03413          iax2_destroy(callno);
03414       }
03415    }
03416    ast_mutex_unlock(&iaxsl[callno]);
03417    if (option_verbose > 2) 
03418       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03419    return 0;
03420 }
03421 
03422 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03423 {
03424    struct ast_option_header *h;
03425    int res;
03426 
03427    switch (option) {
03428    case AST_OPTION_TXGAIN:
03429    case AST_OPTION_RXGAIN:
03430       /* these two cannot be sent, because they require a result */
03431       errno = ENOSYS;
03432       return -1;
03433    default:
03434       if (!(h = ast_malloc(datalen + sizeof(*h))))
03435          return -1;
03436 
03437       h->flag = AST_OPTION_FLAG_REQUEST;
03438       h->option = htons(option);
03439       memcpy(h->data, data, datalen);
03440       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03441                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03442                  datalen + sizeof(*h), -1);
03443       free(h);
03444       return res;
03445    }
03446 }
03447 
03448 static struct ast_frame *iax2_read(struct ast_channel *c) 
03449 {
03450    if (option_verbose > 3)
03451        ast_log(LOG_NOTICE, "I should never be called!\n");
03452    return &ast_null_frame;
03453 }
03454 
03455 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03456 {
03457    int res;
03458    struct iax_ie_data ied0;
03459    struct iax_ie_data ied1;
03460    unsigned int transferid = (unsigned int)ast_random();
03461    memset(&ied0, 0, sizeof(ied0));
03462    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03463    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03464    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03465 
03466    memset(&ied1, 0, sizeof(ied1));
03467    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03468    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03469    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03470    
03471    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03472    if (res)
03473       return -1;
03474    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03475    if (res)
03476       return -1;
03477    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03478    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03479    return 0;
03480 }
03481 
03482 static void lock_both(unsigned short callno0, unsigned short callno1)
03483 {
03484    ast_mutex_lock(&iaxsl[callno0]);
03485    while (ast_mutex_trylock(&iaxsl[callno1])) {
03486       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03487    }
03488 }
03489 
03490 static void unlock_both(unsigned short callno0, unsigned short callno1)
03491 {
03492    ast_mutex_unlock(&iaxsl[callno1]);
03493    ast_mutex_unlock(&iaxsl[callno0]);
03494 }
03495 
03496 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)
03497 {
03498    struct ast_channel *cs[3];
03499    struct ast_channel *who, *other;
03500    int to = -1;
03501    int res = -1;
03502    int transferstarted=0;
03503    struct ast_frame *f;
03504    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03505    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03506    struct timeval waittimer = {0, 0}, tv;
03507 
03508    lock_both(callno0, callno1);
03509    if (!iaxs[callno0] || !iaxs[callno1]) {
03510       unlock_both(callno0, callno1);
03511       return AST_BRIDGE_FAILED;
03512    }
03513    /* Put them in native bridge mode */
03514    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03515       iaxs[callno0]->bridgecallno = callno1;
03516       iaxs[callno1]->bridgecallno = callno0;
03517    }
03518    unlock_both(callno0, callno1);
03519 
03520    /* If not, try to bridge until we can execute a transfer, if we can */
03521    cs[0] = c0;
03522    cs[1] = c1;
03523    for (/* ever */;;) {
03524       /* Check in case we got masqueraded into */
03525       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03526          if (option_verbose > 2)
03527             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03528          /* Remove from native mode */
03529          if (c0->tech == &iax2_tech) {
03530             ast_mutex_lock(&iaxsl[callno0]);
03531             iaxs[callno0]->bridgecallno = 0;
03532             ast_mutex_unlock(&iaxsl[callno0]);
03533          }
03534          if (c1->tech == &iax2_tech) {
03535             ast_mutex_lock(&iaxsl[callno1]);
03536             iaxs[callno1]->bridgecallno = 0;
03537             ast_mutex_unlock(&iaxsl[callno1]);
03538          }
03539          return AST_BRIDGE_FAILED_NOWARN;
03540       }
03541       if (c0->nativeformats != c1->nativeformats) {
03542          if (option_verbose > 2) {
03543             char buf0[255];
03544             char buf1[255];
03545             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03546             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03547             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03548          }
03549          /* Remove from native mode */
03550          lock_both(callno0, callno1);
03551          if (iaxs[callno0])
03552             iaxs[callno0]->bridgecallno = 0;
03553          if (iaxs[callno1])
03554             iaxs[callno1]->bridgecallno = 0;
03555          unlock_both(callno0, callno1);
03556          return AST_BRIDGE_FAILED_NOWARN;
03557       }
03558       /* check if transfered and if we really want native bridging */
03559       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03560          /* Try the transfer */
03561          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03562                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03563             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03564          transferstarted = 1;
03565       }
03566       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03567          /* Call has been transferred.  We're no longer involved */
03568          gettimeofday(&tv, NULL);
03569          if (ast_tvzero(waittimer)) {
03570             waittimer = tv;
03571          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03572             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03573             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03574             *fo = NULL;
03575             *rc = c0;
03576             res = AST_BRIDGE_COMPLETE;
03577             break;
03578          }
03579       }
03580       to = 1000;
03581       who = ast_waitfor_n(cs, 2, &to);
03582       if (timeoutms > -1) {
03583          timeoutms -= (1000 - to);
03584          if (timeoutms < 0)
03585             timeoutms = 0;
03586       }
03587       if (!who) {
03588          if (!timeoutms) {
03589             res = AST_BRIDGE_RETRY;
03590             break;
03591          }
03592          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03593             res = AST_BRIDGE_FAILED;
03594             break;
03595          }
03596          continue;
03597       }
03598       f = ast_read(who);
03599       if (!f) {
03600          *fo = NULL;
03601          *rc = who;
03602          res = AST_BRIDGE_COMPLETE;
03603          break;
03604       }
03605       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03606          *fo = f;
03607          *rc = who;
03608          res =  AST_BRIDGE_COMPLETE;
03609          break;
03610       }
03611       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03612       if ((f->frametype == AST_FRAME_VOICE) ||
03613           (f->frametype == AST_FRAME_TEXT) ||
03614           (f->frametype == AST_FRAME_VIDEO) || 
03615           (f->frametype == AST_FRAME_IMAGE) ||
03616           (f->frametype == AST_FRAME_DTMF)) {
03617          /* monitored dtmf take out of the bridge.
03618           * check if we monitor the specific source.
03619           */
03620          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03621          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03622             *rc = who;
03623             *fo = f;
03624             res = AST_BRIDGE_COMPLETE;
03625             /* Remove from native mode */
03626             break;
03627          }
03628          /* everything else goes to the other side */
03629          ast_write(other, f);
03630       }
03631       ast_frfree(f);
03632       /* Swap who gets priority */
03633       cs[2] = cs[0];
03634       cs[0] = cs[1];
03635       cs[1] = cs[2];
03636    }
03637    lock_both(callno0, callno1);
03638    if(iaxs[callno0])
03639       iaxs[callno0]->bridgecallno = 0;
03640    if(iaxs[callno1])
03641       iaxs[callno1]->bridgecallno = 0;
03642    unlock_both(callno0, callno1);
03643    return res;
03644 }
03645 
03646 static int iax2_answer(struct ast_channel *c)
03647 {
03648    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03649    if (option_debug)
03650       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03651    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03652 }
03653 
03654 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03655 {
03656    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03657    struct chan_iax2_pvt *pvt;
03658    int res = 0;
03659 
03660    if (option_debug && iaxdebug)
03661       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03662 
03663    ast_mutex_lock(&iaxsl[callno]);
03664    pvt = iaxs[callno];
03665 
03666    if (!pvt->peercallno) {
03667       /* We don't know the remote side's call number, yet.  :( */
03668       int count = 10;
03669       while (count-- && pvt && !pvt->peercallno) {
03670          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03671          pvt = iaxs[callno];
03672       }
03673       if (!pvt->peercallno) {
03674          res = -1;
03675          goto done;
03676       }
03677    }
03678 
03679    switch (condition) {
03680    case AST_CONTROL_HOLD:
03681       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03682          ast_moh_start(c, data, pvt->mohinterpret);
03683          goto done;
03684       }
03685       break;
03686    case AST_CONTROL_UNHOLD:
03687       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03688          ast_moh_stop(c);
03689          goto done;
03690       }
03691    }
03692 
03693    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03694 
03695 done:
03696    ast_mutex_unlock(&iaxsl[callno]);
03697 
03698    return res;
03699 }
03700    
03701 static int iax2_transfer(struct ast_channel *c, const char *dest)
03702 {
03703    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03704    struct iax_ie_data ied;
03705    char tmp[256], *context;
03706    ast_copy_string(tmp, dest, sizeof(tmp));
03707    context = strchr(tmp, '@');
03708    if (context) {
03709       *context = '\0';
03710       context++;
03711    }
03712    memset(&ied, 0, sizeof(ied));
03713    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03714    if (context)
03715       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03716    if (option_debug)
03717       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03718    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03719 }
03720    
03721 static int iax2_getpeertrunk(struct sockaddr_in sin)
03722 {
03723    struct iax2_peer *peer;
03724    int res = 0;
03725    struct ao2_iterator i;
03726 
03727    i = ao2_iterator_init(peers, 0);
03728    while ((peer = ao2_iterator_next(&i))) {
03729       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03730           (peer->addr.sin_port == sin.sin_port)) {
03731          res = ast_test_flag(peer, IAX_TRUNK);
03732          peer_unref(peer);
03733          break;
03734       }
03735       peer_unref(peer);
03736    }
03737 
03738    return res;
03739 }
03740 
03741 /*! \brief  Create new call, interface with the PBX core */
03742 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03743 {
03744    struct ast_channel *tmp;
03745    struct chan_iax2_pvt *i;
03746    struct ast_variable *v = NULL;
03747 
03748    if (!(i = iaxs[callno])) {
03749       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03750       return NULL;
03751    }
03752 
03753    /* Don't hold call lock */
03754    ast_mutex_unlock(&iaxsl[callno]);
03755    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);
03756    ast_mutex_lock(&iaxsl[callno]);
03757    if (!iaxs[callno]) {
03758       if (tmp) {
03759          ast_channel_free(tmp);
03760       }
03761       ast_mutex_unlock(&iaxsl[callno]);
03762       return NULL;
03763    }
03764 
03765    if (!tmp)
03766       return NULL;
03767    tmp->tech = &iax2_tech;
03768    /* We can support any format by default, until we get restricted */
03769    tmp->nativeformats = capability;
03770    tmp->readformat = ast_best_codec(capability);
03771    tmp->writeformat = ast_best_codec(capability);
03772    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03773 
03774    /* Don't use ast_set_callerid() here because it will
03775     * generate a NewCallerID event before the NewChannel event */
03776    if (!ast_strlen_zero(i->ani))
03777       tmp->cid.cid_ani = ast_strdup(i->ani);
03778    else
03779       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03780    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03781    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03782    tmp->cid.cid_pres = i->calling_pres;
03783    tmp->cid.cid_ton = i->calling_ton;
03784    tmp->cid.cid_tns = i->calling_tns;
03785    if (!ast_strlen_zero(i->language))
03786       ast_string_field_set(tmp, language, i->language);
03787    if (!ast_strlen_zero(i->accountcode))
03788       ast_string_field_set(tmp, accountcode, i->accountcode);
03789    if (i->amaflags)
03790       tmp->amaflags = i->amaflags;
03791    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03792    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03793    if (i->adsi)
03794       tmp->adsicpe = i->peeradsicpe;
03795    else
03796       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03797    i->owner = tmp;
03798    i->capability = capability;
03799 
03800    for (v = i->vars ; v ; v = v->next)
03801       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03802 
03803    if (state != AST_STATE_DOWN) {
03804       if (ast_pbx_start(tmp)) {
03805          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03806          ast_hangup(tmp);
03807          i->owner = NULL;
03808          return NULL;
03809       }
03810    }
03811 
03812    ast_module_ref(ast_module_info->self);
03813    
03814    return tmp;
03815 }
03816 
03817 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03818 {
03819    unsigned long int mssincetx; /* unsigned to handle overflows */
03820    long int ms, pred;
03821 
03822    tpeer->trunkact = *tv;
03823    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03824    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03825       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03826       tpeer->txtrunktime = *tv;
03827       tpeer->lastsent = 999999;
03828    }
03829    /* Update last transmit time now */
03830    tpeer->lasttxtime = *tv;
03831    
03832    /* Calculate ms offset */
03833    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03834    /* Predict from last value */
03835    pred = tpeer->lastsent + sampms;
03836    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03837       ms = pred;
03838    
03839    /* We never send the same timestamp twice, so fudge a little if we must */
03840    if (ms == tpeer->lastsent)
03841       ms = tpeer->lastsent + 1;
03842    tpeer->lastsent = ms;
03843    return ms;
03844 }
03845 
03846 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03847 {
03848    long ms; /* NOT unsigned */
03849    if (ast_tvzero(iaxs[callno]->rxcore)) {
03850       /* Initialize rxcore time if appropriate */
03851       gettimeofday(&iaxs[callno]->rxcore, NULL);
03852       /* Round to nearest 20ms so traces look pretty */
03853       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03854    }
03855    /* Calculate difference between trunk and channel */
03856    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03857    /* Return as the sum of trunk time and the difference between trunk and real time */
03858    return ms + ts;
03859 }
03860 
03861 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03862 {
03863    int ms;
03864    int voice = 0;
03865    int genuine = 0;
03866    int adjust;
03867    struct timeval *delivery = NULL;
03868 
03869 
03870    /* What sort of frame do we have?: voice is self-explanatory
03871       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03872       non-genuine frames are CONTROL frames [ringing etc], DTMF
03873       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03874       the others need a timestamp slaved to the voice frames so that they go in sequence
03875    */
03876    if (f) {
03877       if (f->frametype == AST_FRAME_VOICE) {
03878          voice = 1;
03879          delivery = &f->delivery;
03880       } else if (f->frametype == AST_FRAME_IAX) {
03881          genuine = 1;
03882       } else if (f->frametype == AST_FRAME_CNG) {
03883          p->notsilenttx = 0;  
03884       }
03885    }
03886    if (ast_tvzero(p->offset)) {
03887       gettimeofday(&p->offset, NULL);
03888       /* Round to nearest 20ms for nice looking traces */
03889       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03890    }
03891    /* If the timestamp is specified, just send it as is */
03892    if (ts)
03893       return ts;
03894    /* If we have a time that the frame arrived, always use it to make our timestamp */
03895    if (delivery && !ast_tvzero(*delivery)) {
03896       ms = ast_tvdiff_ms(*delivery, p->offset);
03897       if (option_debug > 2 && iaxdebug)
03898          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03899    } else {
03900       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03901       if (ms < 0)
03902          ms = 0;
03903       if (voice) {
03904          /* On a voice frame, use predicted values if appropriate */
03905          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03906             /* Adjust our txcore, keeping voice and non-voice synchronized */
03907             /* AN EXPLANATION:
03908                When we send voice, we usually send "calculated" timestamps worked out
03909                on the basis of the number of samples sent. When we send other frames,
03910                we usually send timestamps worked out from the real clock.
03911                The problem is that they can tend to drift out of step because the 
03912                   source channel's clock and our clock may not be exactly at the same rate.
03913                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03914                for this call.  Moving it adjusts timestamps for non-voice frames.
03915                We make the adjustment in the style of a moving average.  Each time we
03916                adjust p->offset by 10% of the difference between our clock-derived
03917                timestamp and the predicted timestamp.  That's why you see "10000"
03918                below even though IAX2 timestamps are in milliseconds.
03919                The use of a moving average avoids offset moving too radically.
03920                Generally, "adjust" roams back and forth around 0, with offset hardly
03921                changing at all.  But if a consistent different starts to develop it
03922                will be eliminated over the course of 10 frames (200-300msecs) 
03923             */
03924             adjust = (ms - p->nextpred);
03925             if (adjust < 0)
03926                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03927             else if (adjust > 0)
03928                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03929 
03930             if (!p->nextpred) {
03931                p->nextpred = ms; /*f->samples / 8;*/
03932                if (p->nextpred <= p->lastsent)
03933                   p->nextpred = p->lastsent + 3;
03934             }
03935             ms = p->nextpred;
03936          } else {
03937                 /* in this case, just use the actual
03938             * time, since we're either way off
03939             * (shouldn't happen), or we're  ending a
03940             * silent period -- and seed the next
03941             * predicted time.  Also, round ms to the
03942             * next multiple of frame size (so our
03943             * silent periods are multiples of
03944             * frame size too) */
03945 
03946             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03947                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03948                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03949 
03950             if (f->samples >= 8) /* check to make sure we dont core dump */
03951             {
03952                int diff = ms % (f->samples / 8);
03953                if (diff)
03954                    ms += f->samples/8 - diff;
03955             }
03956 
03957             p->nextpred = ms;
03958             p->notsilenttx = 1;
03959          }
03960       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03961          /*
03962          * IAX2 draft 03 says that timestamps MUST be in order.
03963          * It does not say anything about several frames having the same timestamp
03964          * When transporting video, we can have a frame that spans multiple iax packets
03965          * (so called slices), so it would make sense to use the same timestamp for all of
03966          * them
03967          * We do want to make sure that frames don't go backwards though
03968          */
03969          if ( (unsigned int)ms < p->lastsent )
03970             ms = p->lastsent;
03971       } else {
03972          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03973             it's a genuine frame */
03974          if (genuine) {
03975             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03976             if (ms <= p->lastsent)
03977                ms = p->lastsent + 3;
03978          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03979             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03980             ms = p->lastsent + 3;
03981          }
03982       }
03983    }
03984    p->lastsent = ms;
03985    if (voice)
03986       p->nextpred = p->nextpred + f->samples / 8;
03987    return ms;
03988 }
03989 
03990 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03991 {
03992    /* Returns where in "receive time" we are.  That is, how many ms
03993       since we received (or would have received) the frame with timestamp 0 */
03994    int ms;
03995 #ifdef IAXTESTS
03996    int jit;
03997 #endif /* IAXTESTS */
03998    /* Setup rxcore if necessary */
03999    if (ast_tvzero(p->rxcore)) {
04000       p->rxcore = ast_tvnow();
04001       if (option_debug && iaxdebug)
04002          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04003                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04004       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04005 #if 1
04006       if (option_debug && iaxdebug)
04007          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04008                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04009 #endif
04010    }
04011 
04012    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04013 #ifdef IAXTESTS
04014    if (test_jit) {
04015       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04016          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04017          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04018             jit = -jit;
04019          ms += jit;
04020       }
04021    }
04022    if (test_late) {
04023       ms += test_late;
04024       test_late = 0;
04025    }
04026 #endif /* IAXTESTS */
04027    return ms;
04028 }
04029 
04030 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04031 {
04032    struct iax2_trunk_peer *tpeer;
04033    
04034    /* Finds and locks trunk peer */
04035    ast_mutex_lock(&tpeerlock);
04036    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04037       /* We don't lock here because tpeer->addr *never* changes */
04038       if (!inaddrcmp(&tpeer->addr, sin)) {
04039          ast_mutex_lock(&tpeer->lock);
04040          break;
04041       }
04042    }
04043    if (!tpeer) {
04044       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04045          ast_mutex_init(&tpeer->lock);
04046          tpeer->lastsent = 9999;
04047          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04048          tpeer->trunkact = ast_tvnow();
04049          ast_mutex_lock(&tpeer->lock);
04050          tpeer->next = tpeers;
04051          tpeer->sockfd = fd;
04052          tpeers = tpeer;
04053 #ifdef SO_NO_CHECK
04054          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04055 #endif
04056          if (option_debug)
04057             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04058       }
04059    }
04060    ast_mutex_unlock(&tpeerlock);
04061    return tpeer;
04062 }
04063 
04064 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04065 {
04066    struct ast_frame *f;
04067    struct iax2_trunk_peer *tpeer;
04068    void *tmp, *ptr;
04069    struct ast_iax2_meta_trunk_entry *met;
04070    struct ast_iax2_meta_trunk_mini *mtm;
04071 
04072    f = &fr->af;
04073    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04074    if (tpeer) {
04075       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04076          /* Need to reallocate space */
04077          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04078             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04079                ast_mutex_unlock(&tpeer->lock);
04080                return -1;
04081             }
04082             
04083             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04084             tpeer->trunkdata = tmp;
04085             if (option_debug)
04086                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);
04087          } else {
04088             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));
04089             ast_mutex_unlock(&tpeer->lock);
04090             return -1;
04091          }
04092       }
04093 
04094       /* Append to meta frame */
04095       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04096       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04097          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04098          mtm->len = htons(f->datalen);
04099          mtm->mini.callno = htons(pvt->callno);
04100          mtm->mini.ts = htons(0xffff & fr->ts);
04101          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04102          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04103       } else {
04104          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04105          /* Store call number and length in meta header */
04106          met->callno = htons(pvt->callno);
04107          met->len = htons(f->datalen);
04108          /* Advance pointers/decrease length past trunk entry header */
04109          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04110          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04111       }
04112       /* Copy actual trunk data */
04113       memcpy(ptr, f->data, f->datalen);
04114       tpeer->trunkdatalen += f->datalen;
04115 
04116       tpeer->calls++;
04117       ast_mutex_unlock(&tpeer->lock);
04118    }
04119    return 0;
04120 }
04121 
04122 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04123 {
04124    build_ecx_key(digest, pvt);
04125    aes_decrypt_key128(digest, &pvt->dcx);
04126 }
04127   
04128 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04129 {
04130    /* it is required to hold the corresponding decrypt key to our encrypt key
04131     * in the pvt struct because queued frames occasionally need to be decrypted and
04132     * re-encrypted when updated for a retransmission */
04133    aes_encrypt_key128(digest, &pvt->ecx);
04134    aes_decrypt_key128(digest, &pvt->mydcx);
04135 }
04136 
04137 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04138 {
04139 #if 0
04140    /* Debug with "fake encryption" */
04141    int x;
04142    if (len % 16)
04143       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04144    for (x=0;x<len;x++)
04145       dst[x] = src[x] ^ 0xff;
04146 #else 
04147    unsigned char lastblock[16] = { 0 };
04148    int x;
04149    while(len > 0) {
04150       aes_decrypt(src, dst, dcx);
04151       for (x=0;x<16;x++)
04152          dst[x] ^= lastblock[x];
04153       memcpy(lastblock, src, sizeof(lastblock));
04154       dst += 16;
04155       src += 16;
04156       len -= 16;
04157    }
04158 #endif
04159 }
04160 
04161 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04162 {
04163 #if 0
04164    /* Debug with "fake encryption" */
04165    int x;
04166    if (len % 16)
04167       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04168    for (x=0;x<len;x++)
04169       dst[x] = src[x] ^ 0xff;
04170 #else
04171    unsigned char curblock[16] = { 0 };
04172    int x;
04173    while(len > 0) {
04174       for (x=0;x<16;x++)
04175          curblock[x] ^= src[x];
04176       aes_encrypt(curblock, dst, ecx);
04177       memcpy(curblock, dst, sizeof(curblock)); 
04178       dst += 16;
04179       src += 16;
04180       len -= 16;
04181    }
04182 #endif
04183 }
04184 
04185 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04186 {
04187    int padding;
04188    unsigned char *workspace;
04189 
04190    workspace = alloca(*datalen);
04191    memset(f, 0, sizeof(*f));
04192    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04193       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04194       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04195          return -1;
04196       /* Decrypt */
04197       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04198 
04199       padding = 16 + (workspace[15] & 0xf);
04200       if (option_debug && iaxdebug)
04201          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04202       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04203          return -1;
04204 
04205       *datalen -= padding;
04206       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04207       f->frametype = fh->type;
04208       if (f->frametype == AST_FRAME_VIDEO) {
04209          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04210       } else {
04211          f->subclass = uncompress_subclass(fh->csub);
04212       }
04213    } else {
04214       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04215       if (option_debug && iaxdebug)
04216          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04217       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04218          return -1;
04219       /* Decrypt */
04220       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04221       padding = 16 + (workspace[15] & 0x0f);
04222       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04223          return -1;
04224       *datalen -= padding;
04225       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04226    }
04227    return 0;
04228 }
04229 
04230 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04231 {
04232    int padding;
04233    unsigned char *workspace;
04234    workspace = alloca(*datalen + 32);
04235    if (!workspace)
04236       return -1;
04237    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04238       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04239       if (option_debug && iaxdebug)
04240          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04241       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04242       padding = 16 + (padding & 0xf);
04243       memcpy(workspace, poo, padding);
04244       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04245       workspace[15] &= 0xf0;
04246       workspace[15] |= (padding & 0xf);
04247       if (option_debug && iaxdebug)
04248          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]);
04249       *datalen += padding;
04250       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04251       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04252          memcpy(poo, workspace + *datalen - 32, 32);
04253    } else {
04254       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04255       if (option_debug && iaxdebug)
04256          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04257       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04258       padding = 16 + (padding & 0xf);
04259       memcpy(workspace, poo, padding);
04260       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04261       workspace[15] &= 0xf0;
04262       workspace[15] |= (padding & 0x0f);
04263       *datalen += padding;
04264       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04265       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04266          memcpy(poo, workspace + *datalen - 32, 32);
04267    }
04268    return 0;
04269 }
04270 
04271 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04272 {
04273    int res=-1;
04274    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04275       /* Search for possible keys, given secrets */
04276       struct MD5Context md5;
04277       unsigned char digest[16];
04278       char *tmppw, *stringp;
04279       
04280       tmppw = ast_strdupa(iaxs[callno]->secret);
04281       stringp = tmppw;
04282       while ((tmppw = strsep(&stringp, ";"))) {
04283          MD5Init(&md5);
04284          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04285          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04286          MD5Final(digest, &md5);
04287          build_encryption_keys(digest, iaxs[callno]);
04288          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04289          if (!res) {
04290             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04291             break;
04292          }
04293       }
04294    } else 
04295       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04296    return res;
04297 }
04298 
04299 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04300 {
04301    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04302       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04303       or delayed, with retransmission */
04304    struct ast_iax2_full_hdr *fh;
04305    struct ast_iax2_mini_hdr *mh;
04306    struct ast_iax2_video_hdr *vh;
04307    struct {
04308       struct iax_frame fr2;
04309       unsigned char buffer[4096];
04310    } frb;
04311    struct iax_frame *fr;
04312    int res;
04313    int sendmini=0;
04314    unsigned int lastsent;
04315    unsigned int fts;
04316 
04317    frb.fr2.afdatalen = sizeof(frb.buffer);
04318 
04319    if (!pvt) {
04320       ast_log(LOG_WARNING, "No private structure for packet?\n");
04321       return -1;
04322    }
04323    
04324    lastsent = pvt->lastsent;
04325 
04326    /* Calculate actual timestamp */
04327    fts = calc_timestamp(pvt, ts, f);
04328 
04329    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04330     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04331     * increment the "predicted timestamps" for voice, if we're predecting */
04332    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04333        return 0;
04334 
04335 
04336    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04337          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04338          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04339       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04340        (f->frametype == AST_FRAME_VOICE) 
04341       /* is a voice frame */ &&
04342       (f->subclass == pvt->svoiceformat) 
04343       /* is the same type */ ) {
04344          /* Force immediate rather than delayed transmission */
04345          now = 1;
04346          /* Mark that mini-style frame is appropriate */
04347          sendmini = 1;
04348    }
04349    if ( f->frametype == AST_FRAME_VIDEO ) {
04350       /*
04351        * If the lower 15 bits of the timestamp roll over, or if
04352        * the video format changed then send a full frame.
04353        * Otherwise send a mini video frame
04354        */
04355       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04356           ((f->subclass & ~0x1) == pvt->svideoformat)
04357          ) {
04358          now = 1;
04359          sendmini = 1;
04360       } else {
04361          now = 0;
04362          sendmini = 0;
04363       }
04364       pvt->lastvsent = fts;
04365    }
04366    /* Allocate an iax_frame */
04367    if (now) {
04368       fr = &frb.fr2;
04369    } else
04370       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));
04371    if (!fr) {
04372       ast_log(LOG_WARNING, "Out of memory\n");
04373       return -1;
04374    }
04375    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04376    iax_frame_wrap(fr, f);
04377 
04378    fr->ts = fts;
04379    fr->callno = pvt->callno;
04380    fr->transfer = transfer;
04381    fr->final = final;
04382    fr->encmethods = 0;
04383    if (!sendmini) {
04384       /* We need a full frame */
04385       if (seqno > -1)
04386          fr->oseqno = seqno;
04387       else
04388          fr->oseqno = pvt->oseqno++;
04389       fr->iseqno = pvt->iseqno;
04390       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04391       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04392       fh->ts = htonl(fr->ts);
04393       fh->oseqno = fr->oseqno;
04394       if (transfer) {
04395          fh->iseqno = 0;
04396       } else
04397          fh->iseqno = fr->iseqno;
04398       /* Keep track of the last thing we've acknowledged */
04399       if (!transfer)
04400          pvt->aseqno = fr->iseqno;
04401       fh->type = fr->af.frametype & 0xFF;
04402       if (fr->af.frametype == AST_FRAME_VIDEO)
04403          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04404       else
04405          fh->csub = compress_subclass(fr->af.subclass);
04406       if (transfer) {
04407          fr->dcallno = pvt->transfercallno;
04408       } else
04409          fr->dcallno = pvt->peercallno;
04410       fh->dcallno = htons(fr->dcallno);
04411       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04412       fr->data = fh;
04413       fr->retries = 0;
04414       /* Retry after 2x the ping time has passed */
04415       fr->retrytime = pvt->pingtime * 2;
04416       if (fr->retrytime < MIN_RETRY_TIME)
04417          fr->retrytime = MIN_RETRY_TIME;
04418       if (fr->retrytime > MAX_RETRY_TIME)
04419          fr->retrytime = MAX_RETRY_TIME;
04420       /* Acks' don't get retried */
04421       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04422          fr->retries = -1;
04423       else if (f->frametype == AST_FRAME_VOICE)
04424          pvt->svoiceformat = f->subclass;
04425       else if (f->frametype == AST_FRAME_VIDEO)
04426          pvt->svideoformat = f->subclass & ~0x1;
04427       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04428          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04429             if (iaxdebug) {
04430                if (fr->transfer)
04431                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04432                else
04433                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04434             }
04435             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04436             fr->encmethods = pvt->encmethods;
04437             fr->ecx = pvt->ecx;
04438             fr->mydcx = pvt->mydcx;
04439             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
04440          } else
04441             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04442       }
04443    
04444       if (now) {
04445          res = send_packet(fr);
04446       } else
04447          res = iax2_transmit(fr);
04448    } else {
04449       if (ast_test_flag(pvt, IAX_TRUNK)) {
04450          iax2_trunk_queue(pvt, fr);
04451          res = 0;
04452       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04453          /* Video frame have no sequence number */
04454          fr->oseqno = -1;
04455          fr->iseqno = -1;
04456          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04457          vh->zeros = 0;
04458          vh->callno = htons(0x8000 | fr->callno);
04459          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04460          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04461          fr->data = vh;
04462          fr->retries = -1;
04463          res = send_packet(fr);        
04464       } else {
04465          /* Mini-frames have no sequence number */
04466          fr->oseqno = -1;
04467          fr->iseqno = -1;
04468          /* Mini frame will do */
04469          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04470          mh->callno = htons(fr->callno);
04471          mh->ts = htons(fr->ts & 0xFFFF);
04472          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04473          fr->data = mh;
04474          fr->retries = -1;
04475          if (pvt->transferring == TRANSFER_MEDIAPASS)
04476             fr->transfer = 1;
04477          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04478             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04479                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04480             } else
04481                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04482          }
04483          res = send_packet(fr);
04484       }
04485    }
04486    return res;
04487 }
04488 
04489 static int iax2_show_users(int fd, int argc, char *argv[])
04490 {
04491    regex_t regexbuf;
04492    int havepattern = 0;
04493 
04494 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04495 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04496 
04497    struct iax2_user *user = NULL;
04498    char auth[90];
04499    char *pstr = "";
04500    struct ao2_iterator i;
04501 
04502    switch (argc) {
04503    case 5:
04504       if (!strcasecmp(argv[3], "like")) {
04505          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04506             return RESULT_SHOWUSAGE;
04507          havepattern = 1;
04508       } else
04509          return RESULT_SHOWUSAGE;
04510    case 3:
04511       break;
04512    default:
04513       return RESULT_SHOWUSAGE;
04514    }
04515 
04516    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04517    i = ao2_iterator_init(users, 0);
04518    for (user = ao2_iterator_next(&i); user; 
04519       user_unref(user), user = ao2_iterator_next(&i)) {
04520       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04521          continue;
04522       
04523       if (!ast_strlen_zero(user->secret)) {
04524          ast_copy_string(auth,user->secret,sizeof(auth));
04525       } else if (!ast_strlen_zero(user->inkeys)) {
04526          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04527       } else
04528          ast_copy_string(auth, "-no secret-", sizeof(auth));
04529       
04530       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04531          pstr = "REQ Only";
04532       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04533          pstr = "Disabled";
04534       else
04535          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04536       
04537       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04538          user->contexts ? user->contexts->context : context,
04539          user->ha ? "Yes" : "No", pstr);
04540    }
04541 
04542    if (havepattern)
04543       regfree(&regexbuf);
04544 
04545    return RESULT_SUCCESS;
04546 #undef FORMAT
04547 #undef FORMAT2
04548 }
04549 
04550 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04551 {
04552    regex_t regexbuf;
04553    int havepattern = 0;
04554    int total_peers = 0;
04555    int online_peers = 0;
04556    int offline_peers = 0;
04557    int unmonitored_peers = 0;
04558    struct ao2_iterator i;
04559 
04560 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04561 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04562 
04563    struct iax2_peer *peer = NULL;
04564    char name[256];
04565    int registeredonly=0;
04566    char *term = manager ? "\r\n" : "\n";
04567 
04568    switch (argc) {
04569    case 6:
04570       if (!strcasecmp(argv[3], "registered"))
04571          registeredonly = 1;
04572       else
04573          return RESULT_SHOWUSAGE;
04574       if (!strcasecmp(argv[4], "like")) {
04575          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04576             return RESULT_SHOWUSAGE;
04577          havepattern = 1;
04578       } else
04579          return RESULT_SHOWUSAGE;
04580       break;
04581    case 5:
04582       if (!strcasecmp(argv[3], "like")) {
04583          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04584             return RESULT_SHOWUSAGE;
04585          havepattern = 1;
04586       } else
04587          return RESULT_SHOWUSAGE;
04588       break;
04589    case 4:
04590       if (!strcasecmp(argv[3], "registered"))
04591          registeredonly = 1;
04592       else
04593          return RESULT_SHOWUSAGE;
04594       break;
04595    case 3:
04596       break;
04597    default:
04598       return RESULT_SHOWUSAGE;
04599    }
04600 
04601 
04602    if (s)
04603       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04604    else
04605       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04606 
04607    i = ao2_iterator_init(peers, 0);
04608    for (peer = ao2_iterator_next(&i); peer; 
04609       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04610       char nm[20];
04611       char status[20];
04612       char srch[2000];
04613       int retstatus;
04614 
04615       if (registeredonly && !peer->addr.sin_addr.s_addr)
04616          continue;
04617       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04618          continue;
04619 
04620       if (!ast_strlen_zero(peer->username))
04621          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04622       else
04623          ast_copy_string(name, peer->name, sizeof(name));
04624       
04625       retstatus = peer_status(peer, status, sizeof(status));
04626       if (retstatus > 0)
04627          online_peers++;
04628       else if (!retstatus)
04629          offline_peers++;
04630       else
04631          unmonitored_peers++;
04632       
04633       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04634       
04635       snprintf(srch, sizeof(srch), FORMAT, name, 
04636           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04637           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04638           nm,
04639           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04640           peer->encmethods ? "(E)" : "   ", status, term);
04641       
04642       if (s)
04643          astman_append(s, FORMAT, name, 
04644                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04645                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04646                   nm,
04647                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04648                   peer->encmethods ? "(E)" : "   ", status, term);
04649       else
04650          ast_cli(fd, FORMAT, name, 
04651             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04652             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04653             nm,
04654             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04655             peer->encmethods ? "(E)" : "   ", status, term);
04656       total_peers++;
04657    }
04658 
04659    if (s)
04660       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04661    else
04662       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04663 
04664    if (havepattern)
04665       regfree(&regexbuf);
04666 
04667    return RESULT_SUCCESS;
04668 #undef FORMAT
04669 #undef FORMAT2
04670 }
04671 
04672 static int iax2_show_threads(int fd, int argc, char *argv[])
04673 {
04674    struct iax2_thread *thread = NULL;
04675    time_t t;
04676    int threadcount = 0, dynamiccount = 0;
04677    char type;
04678 
04679    if (argc != 3)
04680       return RESULT_SHOWUSAGE;
04681       
04682    ast_cli(fd, "IAX2 Thread Information\n");
04683    time(&t);
04684    ast_cli(fd, "Idle Threads:\n");
04685    AST_LIST_LOCK(&idle_list);
04686    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04687 #ifdef DEBUG_SCHED_MULTITHREAD
04688       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04689          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04690 #else
04691       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04692          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04693 #endif
04694       threadcount++;
04695    }
04696    AST_LIST_UNLOCK(&idle_list);
04697    ast_cli(fd, "Active Threads:\n");
04698    AST_LIST_LOCK(&active_list);
04699    AST_LIST_TRAVERSE(&active_list, thread, list) {
04700       if (thread->type == IAX_TYPE_DYNAMIC)
04701          type = 'D';
04702       else
04703          type = 'P';
04704 #ifdef DEBUG_SCHED_MULTITHREAD
04705       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04706          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04707 #else
04708       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04709          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04710 #endif
04711       threadcount++;
04712    }
04713    AST_LIST_UNLOCK(&active_list);
04714    ast_cli(fd, "Dynamic Threads:\n");
04715         AST_LIST_LOCK(&dynamic_list);
04716         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04717 #ifdef DEBUG_SCHED_MULTITHREAD
04718                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04719                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04720 #else
04721                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04722                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04723 #endif
04724       dynamiccount++;
04725         }
04726         AST_LIST_UNLOCK(&dynamic_list);
04727    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04728    return RESULT_SUCCESS;
04729 }
04730 
04731 static int iax2_show_peers(int fd, int argc, char *argv[])
04732 {
04733    return __iax2_show_peers(0, fd, NULL, argc, argv);
04734 }
04735 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04736 {
04737    ast_cli_netstats(s, -1, 0);
04738    astman_append(s, "\r\n");
04739    return RESULT_SUCCESS;
04740 }
04741 
04742 static int iax2_show_firmware(int fd, int argc, char *argv[])
04743 {
04744 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04745 #if !defined(__FreeBSD__)
04746 #define FORMAT "%-15.15s  %-15d %-15d\n"
04747 #else /* __FreeBSD__ */
04748 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04749 #endif /* __FreeBSD__ */
04750    struct iax_firmware *cur;
04751    if ((argc != 3) && (argc != 4))
04752       return RESULT_SHOWUSAGE;
04753    ast_mutex_lock(&waresl.lock);
04754    
04755    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04756    for (cur = waresl.wares;cur;cur = cur->next) {
04757       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04758          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04759             (int)ntohl(cur->fwh->datalen));
04760    }
04761    ast_mutex_unlock(&waresl.lock);
04762    return RESULT_SUCCESS;
04763 #undef FORMAT
04764 #undef FORMAT2
04765 }
04766 
04767 /* JDG: callback to display iax peers in manager */
04768 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04769 {
04770    char *a[] = { "iax2", "show", "users" };
04771    int ret;
04772    const char *id = astman_get_header(m,"ActionID");
04773 
04774    if (!ast_strlen_zero(id))
04775       astman_append(s, "ActionID: %s\r\n",id);
04776    ret = __iax2_show_peers(1, -1, s, 3, a );
04777    astman_append(s, "\r\n\r\n" );
04778    return ret;
04779 } /* /JDG */
04780 
04781 static char *regstate2str(int regstate)
04782 {
04783    switch(regstate) {
04784    case REG_STATE_UNREGISTERED:
04785       return "Unregistered";
04786    case REG_STATE_REGSENT:
04787       return "Request Sent";
04788    case REG_STATE_AUTHSENT:
04789       return "Auth. Sent";
04790    case REG_STATE_REGISTERED:
04791       return "Registered";
04792    case REG_STATE_REJECTED:
04793       return "Rejected";
04794    case REG_STATE_TIMEOUT:
04795       return "Timeout";
04796    case REG_STATE_NOAUTH:
04797       return "No Authentication";
04798    default:
04799       return "Unknown";
04800    }
04801 }
04802 
04803 static int iax2_show_registry(int fd, int argc, char *argv[])
04804 {
04805 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04806 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04807    struct iax2_registry *reg = NULL;
04808 
04809    char host[80];
04810    char perceived[80];
04811    if (argc != 3)
04812       return RESULT_SHOWUSAGE;
04813    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04814    AST_LIST_LOCK(&registrations);
04815    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04816       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04817       if (reg->us.sin_addr.s_addr) 
04818          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04819       else
04820          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04821       ast_cli(fd, FORMAT, host, 
04822                (reg->dnsmgr) ? "Y" : "N", 
04823                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04824    }
04825    AST_LIST_UNLOCK(&registrations);
04826    return RESULT_SUCCESS;
04827 #undef FORMAT
04828 #undef FORMAT2
04829 }
04830 
04831 static int iax2_show_channels(int fd, int argc, char *argv[])
04832 {
04833 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04834 #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"
04835 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04836    int x;
04837    int numchans = 0;
04838 
04839    if (argc != 3)
04840       return RESULT_SHOWUSAGE;
04841    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04842    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04843       ast_mutex_lock(&iaxsl[x]);
04844       if (iaxs[x]) {
04845          int lag, jitter, localdelay;
04846          jb_info jbinfo;
04847          
04848          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04849             jb_getinfo(iaxs[x]->jb, &jbinfo);
04850             jitter = jbinfo.jitter;
04851             localdelay = jbinfo.current - jbinfo.min;
04852          } else {
04853             jitter = -1;
04854             localdelay = 0;
04855          }
04856          lag = iaxs[x]->remote_rr.delay;
04857          ast_cli(fd, FORMAT,
04858             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04859             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04860             S_OR(iaxs[x]->username, "(None)"),
04861             iaxs[x]->callno, iaxs[x]->peercallno,
04862             iaxs[x]->oseqno, iaxs[x]->iseqno,
04863             lag,
04864             jitter,
04865             localdelay,
04866             ast_getformatname(iaxs[x]->voiceformat) );
04867          numchans++;
04868       }
04869       ast_mutex_unlock(&iaxsl[x]);
04870    }
04871    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04872    return RESULT_SUCCESS;
04873 #undef FORMAT
04874 #undef FORMAT2
04875 #undef FORMATB
04876 }
04877 
04878 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04879 {
04880    int x;
04881    int numchans = 0;
04882    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04883       ast_mutex_lock(&iaxsl[x]);
04884       if (iaxs[x]) {
04885          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04886          char *fmt;
04887          jb_info jbinfo;
04888          
04889          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04890             jb_getinfo(iaxs[x]->jb, &jbinfo);
04891             localjitter = jbinfo.jitter;
04892             localdelay = jbinfo.current - jbinfo.min;
04893             locallost = jbinfo.frames_lost;
04894             locallosspct = jbinfo.losspct/1000;
04895             localdropped = jbinfo.frames_dropped;
04896             localooo = jbinfo.frames_ooo;
04897          } else {
04898             localjitter = -1;
04899             localdelay = 0;
04900             locallost = -1;
04901             locallosspct = -1;
04902             localdropped = 0;
04903             localooo = -1;
04904          }
04905          if (limit_fmt)
04906             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04907          else
04908             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04909          if (s)
04910             
04911             astman_append(s, 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          else
04929             ast_cli(fd, fmt,
04930                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04931                iaxs[x]->pingtime,
04932                localjitter, 
04933                localdelay,
04934                locallost,
04935                locallosspct,
04936                localdropped,
04937                localooo,
04938                iaxs[x]->frames_received/1000,
04939                iaxs[x]->remote_rr.jitter,
04940                iaxs[x]->remote_rr.delay,
04941                iaxs[x]->remote_rr.losscnt,
04942                iaxs[x]->remote_rr.losspct,
04943                iaxs[x]->remote_rr.dropped,
04944                iaxs[x]->remote_rr.ooo,
04945                iaxs[x]->remote_rr.packets/1000
04946                );
04947          numchans++;
04948       }
04949       ast_mutex_unlock(&iaxsl[x]);
04950    }
04951    return numchans;
04952 }
04953 
04954 static int iax2_show_netstats(int fd, int argc, char *argv[])
04955 {
04956    int numchans = 0;
04957    if (argc != 3)
04958       return RESULT_SHOWUSAGE;
04959    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04960    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04961    numchans = ast_cli_netstats(NULL, fd, 1);
04962    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04963    return RESULT_SUCCESS;
04964 }
04965 
04966 static int iax2_do_debug(int fd, int argc, char *argv[])
04967 {
04968    if (argc < 2 || argc > 3)
04969       return RESULT_SHOWUSAGE;
04970    iaxdebug = 1;
04971    ast_cli(fd, "IAX2 Debugging Enabled\n");
04972    return RESULT_SUCCESS;
04973 }
04974 
04975 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04976 {
04977    if (argc < 3 || argc > 4)
04978       return RESULT_SHOWUSAGE;
04979    iaxtrunkdebug = 1;
04980    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04981    return RESULT_SUCCESS;
04982 }
04983 
04984 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04985 {
04986    if (argc < 3 || argc > 4)
04987       return RESULT_SHOWUSAGE;
04988    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04989    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04990    return RESULT_SUCCESS;
04991 }
04992 
04993 static int iax2_no_debug(int fd, int argc, char *argv[])
04994 {
04995    if (argc < 3 || argc > 4)
04996       return RESULT_SHOWUSAGE;
04997    iaxdebug = 0;
04998    ast_cli(fd, "IAX2 Debugging Disabled\n");
04999    return RESULT_SUCCESS;
05000 }
05001 
05002 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05003 {
05004    if (argc < 4 || argc > 5)
05005       return RESULT_SHOWUSAGE;
05006    iaxtrunkdebug = 0;
05007    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05008    return RESULT_SUCCESS;
05009 }
05010 
05011 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05012 {
05013    if (argc < 4 || argc > 5)
05014       return RESULT_SHOWUSAGE;
05015    jb_setoutput(jb_error_output, jb_warning_output, NULL);
05016    jb_debug_output("\n");
05017    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05018    return RESULT_SUCCESS;
05019 }
05020 
05021 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05022 {
05023    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05024    int res = -1;
05025    ast_mutex_lock(&iaxsl[callno]);
05026    if (iaxs[callno]) {
05027    /* If there's an outstanding error, return failure now */
05028       if (!iaxs[callno]->error) {
05029          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05030             res = 0;
05031             /* Don't waste bandwidth sending null frames */
05032          else if (f->frametype == AST_FRAME_NULL)
05033             res = 0;
05034          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05035             res = 0;
05036          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05037             res = 0;
05038          else
05039          /* Simple, just queue for transmission */
05040             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05041       } else {
05042          if (option_debug)
05043             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05044       }
05045    }
05046    /* If it's already gone, just return */
05047    ast_mutex_unlock(&iaxsl[callno]);
05048    return res;
05049 }
05050 
05051 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05052       int now, int transfer, int final)
05053 {
05054    struct ast_frame f = { 0, };
05055 
05056    f.frametype = type;
05057    f.subclass = command;
05058    f.datalen = datalen;
05059    f.src = __FUNCTION__;
05060    f.data = (void *) data;
05061 
05062    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05063 }
05064 
05065 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05066 {
05067    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05068 }
05069 
05070 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05071 {
05072    int res;
05073    ast_mutex_lock(&iaxsl[callno]);
05074    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05075    ast_mutex_unlock(&iaxsl[callno]);
05076    return res;
05077 }
05078 
05079 /*!
05080  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05081  *       the pvt struct for the given call number may disappear during its 
05082  *       execution.
05083  */
05084 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)
05085 {
05086    int call_num = i->callno;
05087    /* It is assumed that the callno has already been locked */
05088    iax2_predestroy(i->callno);
05089    if (!iaxs[call_num])
05090       return -1;
05091    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05092 }
05093 
05094 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)
05095 {
05096    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05097 }
05098 
05099 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05100 {
05101    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05102 }
05103 
05104 static int apply_context(struct iax2_context *con, const char *context)
05105 {
05106    while(con) {
05107       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05108          return -1;
05109       con = con->next;
05110    }
05111    return 0;
05112 }
05113 
05114 
05115 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05116 {
05117    /* Start pessimistic */
05118    int res = -1;
05119    int version = 2;
05120    struct iax2_user *user = NULL, *best = NULL;
05121    int bestscore = 0;
05122    int gotcapability = 0;
05123    struct ast_variable *v = NULL, *tmpvar = NULL;
05124    struct ao2_iterator i;
05125 
05126    if (!iaxs[callno])
05127       return res;
05128    if (ies->called_number)
05129       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05130    if (ies->calling_number) {
05131       ast_shrink_phone_number(ies->calling_number);
05132       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05133    }
05134    if (ies->calling_name)
05135       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05136    if (ies->calling_ani)
05137       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05138    if (ies->dnid)
05139       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05140    if (ies->rdnis)
05141       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05142    if (ies->called_context)
05143       ast_string_field_set(iaxs[callno], context, ies->called_context);
05144    if (ies->language)
05145       ast_string_field_set(iaxs[callno], language, ies->language);
05146    if (ies->username)
05147       ast_string_field_set(iaxs[callno], username, ies->username);
05148    if (ies->calling_ton > -1)
05149       iaxs[callno]->calling_ton = ies->calling_ton;
05150    if (ies->calling_tns > -1)
05151       iaxs[callno]->calling_tns = ies->calling_tns;
05152    if (ies->calling_pres > -1)
05153       iaxs[callno]->calling_pres = ies->calling_pres;
05154    if (ies->format)
05155       iaxs[callno]->peerformat = ies->format;
05156    if (ies->adsicpe)
05157       iaxs[callno]->peeradsicpe = ies->adsicpe;
05158    if (ies->capability) {
05159       gotcapability = 1;
05160       iaxs[callno]->peercapability = ies->capability;
05161    } 
05162    if (ies->version)
05163       version = ies->version;
05164 
05165    /* Use provided preferences until told otherwise for actual preferences */
05166    if(ies->codec_prefs) {
05167       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05168       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05169    }
05170 
05171    if (!gotcapability) 
05172       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05173    if (version > IAX_PROTO_VERSION) {
05174       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05175          ast_inet_ntoa(sin->sin_addr), version);
05176       return res;
05177    }
05178    /* Search the userlist for a compatible entry, and fill in the rest */
05179    i = ao2_iterator_init(users, 0);
05180    while ((user = ao2_iterator_next(&i))) {
05181       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05182          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05183          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05184          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05185               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05186          if (!ast_strlen_zero(iaxs[callno]->username)) {
05187             /* Exact match, stop right now. */
05188             if (best)
05189                user_unref(best);
05190             best = user;
05191             break;
05192          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05193             /* No required authentication */
05194             if (user->ha) {
05195                /* There was host authentication and we passed, bonus! */
05196                if (bestscore < 4) {
05197                   bestscore = 4;
05198                   if (best)
05199                      user_unref(best);
05200                   best = user;
05201                   continue;
05202                }
05203             } else {
05204                /* No host access, but no secret, either, not bad */
05205                if (bestscore < 3) {
05206                   bestscore = 3;
05207                   if (best)
05208                      user_unref(best);
05209                   best = user;
05210                   continue;
05211                }
05212             }
05213          } else {
05214             if (user->ha) {
05215                /* Authentication, but host access too, eh, it's something.. */
05216                if (bestscore < 2) {
05217                   bestscore = 2;
05218                   if (best)
05219                      user_unref(best);
05220                   best = user;
05221                   continue;
05222                }
05223             } else {
05224                /* Authentication and no host access...  This is our baseline */
05225                if (bestscore < 1) {
05226                   bestscore = 1;
05227                   if (best)
05228                      user_unref(best);
05229                   best = user;
05230                   continue;
05231                }
05232             }
05233          }
05234       }
05235       user_unref(user);
05236    }
05237    user = best;
05238    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05239       user = realtime_user(iaxs[callno]->username, sin);
05240       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05241           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05242          user = user_unref(user);
05243       }
05244    }
05245    if (user) {
05246       /* We found our match (use the first) */
05247       /* copy vars */
05248       for (v = user->vars ; v ; v = v->next) {
05249          if((tmpvar = ast_variable_new(v->name, v->value))) {
05250             tmpvar->next = iaxs[callno]->vars; 
05251             iaxs[callno]->vars = tmpvar;
05252          }
05253       }
05254       /* If a max AUTHREQ restriction is in place, activate it */
05255       if (user->maxauthreq > 0)
05256          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05257       iaxs[callno]->prefs = user->prefs;
05258       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05259       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05260       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05261       iaxs[callno]->encmethods = user->encmethods;
05262       /* Store the requested username if not specified */
05263       if (ast_strlen_zero(iaxs[callno]->username))
05264          ast_string_field_set(iaxs[callno], username, user->name);
05265       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05266       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05267       iaxs[callno]->capability = user->capability;
05268       /* And use the default context */
05269       if (ast_strlen_zero(iaxs[callno]->context)) {
05270          if (user->contexts)
05271             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05272          else
05273             ast_string_field_set(iaxs[callno], context, context);
05274       }
05275       /* And any input keys */
05276       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05277       /* And the permitted authentication methods */
05278       iaxs[callno]->authmethods = user->authmethods;
05279       iaxs[callno]->adsi = user->adsi;
05280       /* If they have callerid, override the given caller id.  Always store the ANI */
05281       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05282          if (ast_test_flag(user, IAX_HASCALLERID)) {
05283             iaxs[callno]->calling_tns = 0;
05284             iaxs[callno]->calling_ton = 0;
05285             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05286             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05287             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05288          }
05289          if (ast_strlen_zero(iaxs[callno]->ani))
05290             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05291       } else {
05292          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05293       }
05294       if (!ast_strlen_zero(user->accountcode))
05295          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05296       if (!ast_strlen_zero(user->mohinterpret))
05297          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05298       if (!ast_strlen_zero(user->mohsuggest))
05299          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05300       if (user->amaflags)
05301          iaxs[callno]->amaflags = user->amaflags;
05302       if (!ast_strlen_zero(user->language))
05303          ast_string_field_set(iaxs[callno], language, user->language);
05304       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05305       /* Keep this check last */
05306       if (!ast_strlen_zero(user->dbsecret)) {
05307          char *family, *key=NULL;
05308          char buf[80];
05309          family = ast_strdupa(user->dbsecret);
05310          key = strchr(family, '/');
05311          if (key) {
05312             *key = '\0';
05313             key++;
05314          }
05315          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05316             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05317          else
05318             ast_string_field_set(iaxs[callno], secret, buf);
05319       } else
05320          ast_string_field_set(iaxs[callno], secret, user->secret);
05321       res = 0;
05322       user = user_unref(user);
05323    }
05324    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05325    return res;
05326 }
05327 
05328 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05329 {
05330    struct ast_iax2_full_hdr fh;
05331    fh.scallno = htons(src | IAX_FLAG_FULL);
05332    fh.dcallno = htons(dst);
05333    fh.ts = 0;
05334    fh.oseqno = 0;
05335    fh.iseqno = 0;
05336    fh.type = AST_FRAME_IAX;
05337    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05338    if (iaxdebug)
05339        iax_showframe(NULL, &fh, 0, sin, 0);
05340    if (option_debug)
05341       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05342          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05343    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05344 }
05345 
05346 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05347 {
05348    /* Select exactly one common encryption if there are any */
05349    p->encmethods &= enc;
05350    if (p->encmethods) {
05351       if (p->encmethods & IAX_ENCRYPT_AES128)
05352          p->encmethods = IAX_ENCRYPT_AES128;
05353       else
05354          p->encmethods = 0;
05355    }
05356 }
05357 
05358 /*!
05359  * \pre iaxsl[call_num] is locked
05360  *
05361  * \note Since this function calls send_command_final(), the pvt struct for the given
05362  *       call number may disappear while executing this function.
05363  */
05364 static int authenticate_request(int call_num)
05365 {
05366    struct iax_ie_data ied;
05367    int res = -1, authreq_restrict = 0;
05368    char challenge[10];
05369    struct chan_iax2_pvt *p = iaxs[call_num];
05370 
05371    memset(&ied, 0, sizeof(ied));
05372 
05373    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05374    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05375       struct iax2_user *user, tmp_user = {
05376          .name = p->username, 
05377       };
05378 
05379       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05380       if (user) {
05381          if (user->curauthreq == user->maxauthreq)
05382             authreq_restrict = 1;
05383          else
05384             user->curauthreq++;
05385          user = user_unref(user);
05386       }
05387    }
05388 
05389    /* If the AUTHREQ limit test failed, send back an error */
05390    if (authreq_restrict) {
05391       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05392       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05393       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05394       return 0;
05395    }
05396 
05397    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05398    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05399       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05400       ast_string_field_set(p, challenge, challenge);
05401       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05402       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05403    }
05404    if (p->encmethods)
05405       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05406 
05407    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05408 
05409    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05410 
05411    if (p->encmethods)
05412       ast_set_flag(p, IAX_ENCRYPTED);
05413 
05414    return res;
05415 }
05416 
05417 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05418 {
05419    char requeststr[256];
05420    char md5secret[256] = "";
05421    char secret[256] = "";
05422    char rsasecret[256] = "";
05423    int res = -1; 
05424    int x;
05425    struct iax2_user *user, tmp_user = {
05426       .name = p->username, 
05427    };
05428 
05429    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05430    if (user) {
05431       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05432          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05433          ast_clear_flag(p, IAX_MAXAUTHREQ);
05434       }
05435       ast_string_field_set(p, host, user->name);
05436       user = user_unref(user);
05437    }
05438 
05439    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05440       return res;
05441    if (ies->password)
05442       ast_copy_string(secret, ies->password, sizeof(secret));
05443    if (ies->md5_result)
05444       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05445    if (ies->rsa_result)
05446       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05447    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05448       struct ast_key *key;
05449       char *keyn;
05450       char tmpkey[256];
05451       char *stringp=NULL;
05452       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05453       stringp=tmpkey;
05454       keyn = strsep(&stringp, ":");
05455       while(keyn) {
05456          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05457          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05458             res = 0;
05459             break;
05460          } else if (!key)
05461             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05462          keyn = strsep(&stringp, ":");
05463       }
05464    } else if (p->authmethods & IAX_AUTH_MD5) {
05465       struct MD5Context md5;
05466       unsigned char digest[16];
05467       char *tmppw, *stringp;
05468       
05469       tmppw = ast_strdupa(p->secret);
05470       stringp = tmppw;
05471       while((tmppw = strsep(&stringp, ";"))) {
05472          MD5Init(&md5);
05473          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05474          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05475          MD5Final(digest, &md5);
05476          /* If they support md5, authenticate with it.  */
05477          for (x=0;x<16;x++)
05478             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05479          if (!strcasecmp(requeststr, md5secret)) {
05480             res = 0;
05481             break;
05482          }
05483       }
05484    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05485       if (!strcmp(secret, p->secret))
05486          res = 0;
05487    }
05488    return res;
05489 }
05490 
05491 /*! \brief Verify inbound registration */
05492 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05493 {
05494    char requeststr[256] = "";
05495    char peer[256] = "";
05496    char md5secret[256] = "";
05497    char rsasecret[256] = "";
05498    char secret[256] = "";
05499    struct iax2_peer *p = NULL;
05500    struct ast_key *key;
05501    char *keyn;
05502    int x;
05503    int expire = 0;
05504    int res = -1;
05505 
05506    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05507    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05508    if (ies->username)
05509       ast_copy_string(peer, ies->username, sizeof(peer));
05510    if (ies->password)
05511       ast_copy_string(secret, ies->password, sizeof(secret));
05512    if (ies->md5_result)
05513       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05514    if (ies->rsa_result)
05515       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05516    if (ies->refresh)
05517       expire = ies->refresh;
05518 
05519    if (ast_strlen_zero(peer)) {
05520       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05521       return -1;
05522    }
05523 
05524    /* SLD: first call to lookup peer during registration */
05525    ast_mutex_unlock(&iaxsl[callno]);
05526    p = find_peer(peer, 1);
05527    ast_mutex_lock(&iaxsl[callno]);
05528    if (!p || !iaxs[callno]) {
05529       if (authdebug && !p)
05530          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05531       goto return_unref;
05532    }
05533 
05534    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05535       if (authdebug)
05536          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05537       goto return_unref;
05538    }
05539 
05540    if (!ast_apply_ha(p->ha, sin)) {
05541       if (authdebug)
05542          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05543       goto return_unref;
05544    }
05545    if (!inaddrcmp(&p->addr, sin))
05546       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05547    ast_string_field_set(iaxs[callno], secret, p->secret);
05548    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05549    /* Check secret against what we have on file */
05550    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05551       if (!ast_strlen_zero(p->inkeys)) {
05552          char tmpkeys[256];
05553          char *stringp=NULL;
05554          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05555          stringp=tmpkeys;
05556          keyn = strsep(&stringp, ":");
05557          while(keyn) {
05558             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05559             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05560                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05561                break;
05562             } else if (!key) 
05563                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05564             keyn = strsep(&stringp, ":");
05565          }
05566          if (!keyn) {
05567             if (authdebug)
05568                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05569             goto return_unref;
05570          }
05571       } else {
05572          if (authdebug)
05573             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05574          goto return_unref;
05575       }
05576    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05577       struct MD5Context md5;
05578       unsigned char digest[16];
05579       char *tmppw, *stringp;
05580       
05581       tmppw = ast_strdupa(p->secret);
05582       stringp = tmppw;
05583       while((tmppw = strsep(&stringp, ";"))) {
05584          MD5Init(&md5);
05585          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05586          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05587          MD5Final(digest, &md5);
05588          for (x=0;x<16;x++)
05589             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05590          if (!strcasecmp(requeststr, md5secret)) 
05591             break;
05592       }
05593       if (tmppw) {
05594          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05595       } else {
05596          if (authdebug)
05597             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05598          goto return_unref;
05599       }
05600    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05601       /* They've provided a plain text password and we support that */
05602       if (strcmp(secret, p->secret)) {
05603          if (authdebug)
05604             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05605          goto return_unref;
05606       } else
05607          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05608    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05609       if (authdebug)
05610          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05611       goto return_unref;
05612    }
05613    ast_string_field_set(iaxs[callno], peer, peer);
05614    /* Choose lowest expiry number */
05615    if (expire && (expire < iaxs[callno]->expiry)) 
05616       iaxs[callno]->expiry = expire;
05617 
05618    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05619 
05620    res = 0;
05621 
05622 return_unref:
05623    if (p)
05624       peer_unref(p);
05625 
05626    return res;
05627 }
05628 
05629 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
05630 {
05631    int res = -1;
05632    int x;
05633    if (!ast_strlen_zero(keyn)) {
05634       if (!(authmethods & IAX_AUTH_RSA)) {
05635          if (ast_strlen_zero(secret)) 
05636             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));
05637       } else if (ast_strlen_zero(challenge)) {
05638          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05639       } else {
05640          char sig[256];
05641          struct ast_key *key;
05642          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05643          if (!key) {
05644             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05645          } else {
05646             if (ast_sign(key, (char*)challenge, sig)) {
05647                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05648                res = -1;
05649             } else {
05650                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05651                res = 0;
05652             }
05653          }
05654       }
05655    } 
05656    /* Fall back */
05657    if (res && !ast_strlen_zero(secret)) {
05658       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05659          struct MD5Context md5;
05660          unsigned char digest[16];
05661          char digres[128];
05662          MD5Init(&md5);
05663          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05664          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05665          MD5Final(digest, &md5);
05666          /* If they support md5, authenticate with it.  */
05667          for (x=0;x<16;x++)
05668             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05669          if (pvt) {
05670             build_encryption_keys(digest, pvt);
05671          }
05672          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05673          res = 0;
05674       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05675          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05676          res = 0;
05677       } else
05678          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05679    }
05680    return res;
05681 }
05682 
05683 /*!
05684  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05685  *       so do not call this function with a pvt lock held.
05686  */
05687 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05688 {
05689    struct iax2_peer *peer = NULL;
05690    /* Start pessimistic */
05691    int res = -1;
05692    int authmethods = 0;
05693    struct iax_ie_data ied;
05694    uint16_t callno = p->callno;
05695 
05696    memset(&ied, 0, sizeof(ied));
05697    
05698    if (ies->username)
05699       ast_string_field_set(p, username, ies->username);
05700    if (ies->challenge)
05701       ast_string_field_set(p, challenge, ies->challenge);
05702    if (ies->authmethods)
05703       authmethods = ies->authmethods;
05704    if (authmethods & IAX_AUTH_MD5)
05705       merge_encryption(p, ies->encmethods);
05706    else
05707       p->encmethods = 0;
05708 
05709    /* Check for override RSA authentication first */
05710    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05711       /* Normal password authentication */
05712       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
05713    } else {
05714       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05715       while ((peer = ao2_iterator_next(&i))) {
05716          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05717              /* No peer specified at our end, or this is the peer */
05718              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05719              /* No username specified in peer rule, or this is the right username */
05720              && (!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)))
05721              /* No specified host, or this is our host */
05722             ) {
05723             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
05724             if (!res) {
05725                peer_unref(peer);
05726                break;
05727             }
05728          }
05729          peer_unref(peer);
05730       }
05731       if (!peer) {
05732          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05733             that we're trying to authenticate *to* a realtime peer */
05734          const char *peer_name = ast_strdupa(p->peer);
05735          ast_mutex_unlock(&iaxsl[callno]);
05736          if ((peer = realtime_peer(peer_name, NULL))) {
05737             ast_mutex_lock(&iaxsl[callno]);
05738             if (!(p = iaxs[callno])) {
05739                peer_unref(peer);
05740                return -1;
05741             }
05742             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
05743             peer_unref(peer);
05744          }
05745          if (!peer) {
05746             ast_mutex_lock(&iaxsl[callno]);
05747             if (!(p = iaxs[callno]))
05748                return -1;
05749          }
05750       }
05751    }
05752    if (ies->encmethods)
05753       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05754    if (!res)
05755       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05756    return res;
05757 }
05758 
05759 static int iax2_do_register(struct iax2_registry *reg);
05760 
05761 static void __iax2_do_register_s(const void *data)
05762 {
05763    struct iax2_registry *reg = (struct iax2_registry *)data;
05764    reg->expire = -1;
05765    iax2_do_register(reg);
05766 }
05767 
05768 static int iax2_do_register_s(const void *data)
05769 {
05770 #ifdef SCHED_MULTITHREADED
05771    if (schedule_action(__iax2_do_register_s, data))
05772 #endif      
05773       __iax2_do_register_s(data);
05774    return 0;
05775 }
05776 
05777 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05778 {
05779    int newcall = 0;
05780    char newip[256];
05781    struct iax_ie_data ied;
05782    struct sockaddr_in new;
05783    
05784    
05785    memset(&ied, 0, sizeof(ied));
05786    if (ies->apparent_addr)
05787       bcopy(ies->apparent_addr, &new, sizeof(new));
05788    if (ies->callno)
05789       newcall = ies->callno;
05790    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05791       ast_log(LOG_WARNING, "Invalid transfer request\n");
05792       return -1;
05793    }
05794    pvt->transfercallno = newcall;
05795    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05796    inet_aton(newip, &pvt->transfer.sin_addr);
05797    pvt->transfer.sin_family = AF_INET;
05798    pvt->transferring = TRANSFER_BEGIN;
05799    pvt->transferid = ies->transferid;
05800    if (ies->transferid)
05801       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05802    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05803    return 0; 
05804 }
05805 
05806 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05807 {
05808    char exten[256] = "";
05809    int status = CACHE_FLAG_UNKNOWN;
05810    int expiry = iaxdefaultdpcache;
05811    int x;
05812    int matchmore = 0;
05813    struct iax2_dpcache *dp, *prev;
05814    
05815    if (ies->called_number)
05816       ast_copy_string(exten, ies->called_number, sizeof(exten));
05817 
05818    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05819       status = CACHE_FLAG_EXISTS;
05820    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05821       status = CACHE_FLAG_CANEXIST;
05822    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05823       status = CACHE_FLAG_NONEXISTENT;
05824 
05825    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05826       /* Don't really do anything with this */
05827    }
05828    if (ies->refresh)
05829       expiry = ies->refresh;
05830    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05831       matchmore = CACHE_FLAG_MATCHMORE;
05832    ast_mutex_lock(&dpcache_lock);
05833    prev = NULL;
05834    dp = pvt->dpentries;
05835    while(dp) {
05836       if (!strcmp(dp->exten, exten)) {
05837          /* Let them go */
05838          if (prev)
05839             prev->peer = dp->peer;
05840          else
05841             pvt->dpentries = dp->peer;
05842          dp->peer = NULL;
05843          dp->callno = 0;
05844          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05845          if (dp->flags & CACHE_FLAG_PENDING) {
05846             dp->flags &= ~CACHE_FLAG_PENDING;
05847             dp->flags |= status;
05848             dp->flags |= matchmore;
05849          }
05850          /* Wake up waiters */
05851          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05852             if (dp->waiters[x] > -1)
05853                write(dp->waiters[x], "asdf", 4);
05854       }
05855       prev = dp;
05856       dp = dp->peer;
05857    }
05858    ast_mutex_unlock(&dpcache_lock);
05859    return 0;
05860 }
05861 
05862 static int complete_transfer(int callno, struct iax_ies *ies)
05863 {
05864    int peercallno = 0;
05865    struct chan_iax2_pvt *pvt = iaxs[callno];
05866    struct iax_frame *cur;
05867    jb_frame frame;
05868 
05869    if (ies->callno)
05870       peercallno = ies->callno;
05871 
05872    if (peercallno < 1) {
05873       ast_log(LOG_WARNING, "Invalid transfer request\n");
05874       return -1;
05875    }
05876    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05877    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05878    /* Reset sequence numbers */
05879    pvt->oseqno = 0;
05880    pvt->rseqno = 0;
05881    pvt->iseqno = 0;
05882    pvt->aseqno = 0;
05883 
05884    if (pvt->peercallno) {
05885       remove_by_peercallno(pvt);
05886    }
05887    pvt->peercallno = peercallno;
05888    store_by_peercallno(pvt);
05889 
05890    pvt->transferring = TRANSFER_NONE;
05891    pvt->svoiceformat = -1;
05892    pvt->voiceformat = 0;
05893    pvt->svideoformat = -1;
05894    pvt->videoformat = 0;
05895    pvt->transfercallno = -1;
05896    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05897    memset(&pvt->offset, 0, sizeof(pvt->offset));
05898    /* reset jitterbuffer */
05899    while(jb_getall(pvt->jb,&frame) == JB_OK)
05900       iax2_frame_free(frame.data);
05901    jb_reset(pvt->jb);
05902    pvt->lag = 0;
05903    pvt->last = 0;
05904    pvt->lastsent = 0;
05905    pvt->nextpred = 0;
05906    pvt->pingtime = DEFAULT_RETRY_TIME;
05907    AST_LIST_LOCK(&iaxq.queue);
05908    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05909       /* We must cancel any packets that would have been transmitted
05910          because now we're talking to someone new.  It's okay, they
05911          were transmitted to someone that didn't care anyway. */
05912       if (callno == cur->callno) 
05913          cur->retries = -1;
05914    }
05915    AST_LIST_UNLOCK(&iaxq.queue);
05916    return 0; 
05917 }
05918 
05919 /*! \brief Acknowledgment received for OUR registration */
05920 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05921 {
05922    struct iax2_registry *reg;
05923    /* Start pessimistic */
05924    char peer[256] = "";
05925    char msgstatus[60];
05926    int refresh = 60;
05927    char ourip[256] = "<Unspecified>";
05928    struct sockaddr_in oldus;
05929    struct sockaddr_in us;
05930    int oldmsgs;
05931 
05932    memset(&us, 0, sizeof(us));
05933    if (ies->apparent_addr)
05934       bcopy(ies->apparent_addr, &us, sizeof(us));
05935    if (ies->username)
05936       ast_copy_string(peer, ies->username, sizeof(peer));
05937    if (ies->refresh)
05938       refresh = ies->refresh;
05939    if (ies->calling_number) {
05940       /* We don't do anything with it really, but maybe we should */
05941    }
05942    reg = iaxs[callno]->reg;
05943    if (!reg) {
05944       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05945       return -1;
05946    }
05947    memcpy(&oldus, &reg->us, sizeof(oldus));
05948    oldmsgs = reg->messages;
05949    if (inaddrcmp(&reg->addr, sin)) {
05950       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05951       return -1;
05952    }
05953    memcpy(&reg->us, &us, sizeof(reg->us));
05954    if (ies->msgcount >= 0)
05955       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05956    /* always refresh the registration at the interval requested by the server
05957       we are registering to
05958    */
05959    reg->refresh = refresh;
05960    AST_SCHED_DEL(sched, reg->expire);
05961    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05962    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05963       if (option_verbose > 2) {
05964          if (reg->messages > 255)
05965             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05966          else if (reg->messages > 1)
05967             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05968          else if (reg->messages > 0)
05969             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05970          else
05971             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05972          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05973          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05974       }
05975       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05976    }
05977    reg->regstate = REG_STATE_REGISTERED;
05978    return 0;
05979 }
05980 
05981 static int iax2_register(char *value, int lineno)
05982 {
05983    struct iax2_registry *reg;
05984    char copy[256];
05985    char *username, *hostname, *secret;
05986    char *porta;
05987    char *stringp=NULL;
05988    
05989    if (!value)
05990       return -1;
05991    ast_copy_string(copy, value, sizeof(copy));
05992    stringp=copy;
05993    username = strsep(&stringp, "@");
05994    hostname = strsep(&stringp, "@");
05995    if (!hostname) {
05996       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05997       return -1;
05998    }
05999    stringp=username;
06000    username = strsep(&stringp, ":");
06001    secret = strsep(&stringp, ":");
06002    stringp=hostname;
06003    hostname = strsep(&stringp, ":");
06004    porta = strsep(&stringp, ":");
06005    
06006    if (porta && !atoi(porta)) {
06007       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06008       return -1;
06009    }
06010    if (!(reg = ast_calloc(1, sizeof(*reg))))
06011       return -1;
06012    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06013       free(reg);
06014       return -1;
06015    }
06016    ast_copy_string(reg->username, username, sizeof(reg->username));
06017    if (secret)
06018       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06019    reg->expire = -1;
06020    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06021    reg->addr.sin_family = AF_INET;
06022    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06023    AST_LIST_LOCK(&registrations);
06024    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06025    AST_LIST_UNLOCK(&registrations);
06026    
06027    return 0;
06028 }
06029 
06030 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06031 {
06032    char multi[256];
06033    char *stringp, *ext;
06034    if (!ast_strlen_zero(regcontext)) {
06035       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06036       stringp = multi;
06037       while((ext = strsep(&stringp, "&"))) {
06038          if (onoff) {
06039             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06040                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06041                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06042          } else
06043             ast_context_remove_extension(regcontext, ext, 1, NULL);
06044       }
06045    }
06046 }
06047 static void prune_peers(void);
06048 
06049 static void unlink_peer(struct iax2_peer *peer)
06050 {
06051    if (peer->expire > -1) {
06052       if (!ast_sched_del(sched, peer->expire)) {
06053          peer->expire = -1;
06054          peer_unref(peer);
06055       }
06056    }
06057 
06058    if (peer->pokeexpire > -1) {
06059       if (!ast_sched_del(sched, peer->pokeexpire)) {
06060          peer->pokeexpire = -1;
06061          peer_unref(peer);
06062       }
06063    }
06064 
06065    ao2_unlink(peers, peer);
06066 }
06067 
06068 static void __expire_registry(const void *data)
06069 {
06070    struct iax2_peer *peer = (struct iax2_peer *) data;
06071 
06072    if (!peer)
06073       return;
06074 
06075    peer->expire = -1;
06076 
06077    if (option_debug)
06078       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06079    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06080       realtime_update_peer(peer->name, &peer->addr, 0);
06081    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06082    /* Reset the address */
06083    memset(&peer->addr, 0, sizeof(peer->addr));
06084    /* Reset expiry value */
06085    peer->expiry = min_reg_expire;
06086    if (!ast_test_flag(peer, IAX_TEMPONLY))
06087       ast_db_del("IAX/Registry", peer->name);
06088    register_peer_exten(peer, 0);
06089    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06090    if (iax2_regfunk)
06091       iax2_regfunk(peer->name, 0);
06092 
06093    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06094       unlink_peer(peer);
06095 
06096    peer_unref(peer);
06097 }
06098 
06099 static int expire_registry(const void *data)
06100 {
06101 #ifdef SCHED_MULTITHREADED
06102    if (schedule_action(__expire_registry, data))
06103 #endif      
06104       __expire_registry(data);
06105    return 0;
06106 }
06107 
06108 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06109 
06110 static void reg_source_db(struct iax2_peer *p)
06111 {
06112    char data[80];
06113    struct in_addr in;
06114    char *c, *d;
06115    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06116       c = strchr(data, ':');
06117       if (c) {
06118          *c = '\0';
06119          c++;
06120          if (inet_aton(data, &in)) {
06121             d = strchr(c, ':');
06122             if (d) {
06123                *d = '\0';
06124                d++;
06125                if (option_verbose > 2)
06126                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06127                   ast_inet_ntoa(in), atoi(c), atoi(d));
06128                iax2_poke_peer(p, 0);
06129                p->expiry = atoi(d);
06130                memset(&p->addr, 0, sizeof(p->addr));
06131                p->addr.sin_family = AF_INET;
06132                p->addr.sin_addr = in;
06133                p->addr.sin_port = htons(atoi(c));
06134                if (p->expire > -1) {
06135                   if (!ast_sched_del(sched, p->expire)) {
06136                      p->expire = -1;
06137                      peer_unref(p);
06138                   }
06139                }
06140                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06141                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06142                if (p->expire == -1)
06143                   peer_unref(p);
06144                if (iax2_regfunk)
06145                   iax2_regfunk(p->name, 1);
06146                register_peer_exten(p, 1);
06147             }              
06148                
06149          }
06150       }
06151    }
06152 }
06153 
06154 /*!
06155  * \pre iaxsl[callno] is locked
06156  *
06157  * \note Since this function calls send_command_final(), the pvt struct for
06158  *       the given call number may disappear while executing this function.
06159  */
06160 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06161 {
06162    /* Called from IAX thread only, with proper iaxsl lock */
06163    struct iax_ie_data ied;
06164    struct iax2_peer *p;
06165    int msgcount;
06166    char data[80];
06167    int version;
06168    const char *peer_name;
06169    int res = -1;
06170 
06171    memset(&ied, 0, sizeof(ied));
06172 
06173    peer_name = ast_strdupa(iaxs[callno]->peer);
06174 
06175    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06176    ast_mutex_unlock(&iaxsl[callno]);
06177    if (!(p = find_peer(peer_name, 1))) {
06178       ast_mutex_lock(&iaxsl[callno]);
06179       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06180       return -1;
06181    }
06182    ast_mutex_lock(&iaxsl[callno]);
06183    if (!iaxs[callno])
06184       goto return_unref;
06185 
06186    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06187       if (sin->sin_addr.s_addr) {
06188          time_t nowtime;
06189          time(&nowtime);
06190          realtime_update_peer(peer_name, sin, nowtime);
06191       } else {
06192          realtime_update_peer(peer_name, sin, 0);
06193       }
06194    }
06195    if (inaddrcmp(&p->addr, sin)) {
06196       if (iax2_regfunk)
06197          iax2_regfunk(p->name, 1);
06198       /* Stash the IP address from which they registered */
06199       memcpy(&p->addr, sin, sizeof(p->addr));
06200       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06201       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06202          ast_db_put("IAX/Registry", p->name, data);
06203          if  (option_verbose > 2)
06204             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06205                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06206          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06207          register_peer_exten(p, 1);
06208          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06209       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06210          if  (option_verbose > 2)
06211             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06212                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06213          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06214          register_peer_exten(p, 0);
06215          ast_db_del("IAX/Registry", p->name);
06216          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06217       }
06218       /* Update the host */
06219       /* Verify that the host is really there */
06220       iax2_poke_peer(p, callno);
06221    }     
06222 
06223    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06224    if (!iaxs[callno]) {
06225       res = 0;
06226       goto return_unref;
06227    }
06228 
06229    /* Store socket fd */
06230    p->sockfd = fd;
06231    /* Setup the expiry */
06232    if (p->expire > -1) {
06233       if (!ast_sched_del(sched, p->expire)) {
06234          p->expire = -1;
06235          peer_unref(p);
06236       }
06237    }
06238    /* treat an unspecified refresh interval as the minimum */
06239    if (!refresh)
06240       refresh = min_reg_expire;
06241    if (refresh > max_reg_expire) {
06242       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06243          p->name, max_reg_expire, refresh);
06244       p->expiry = max_reg_expire;
06245    } else if (refresh < min_reg_expire) {
06246       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06247          p->name, min_reg_expire, refresh);
06248       p->expiry = min_reg_expire;
06249    } else {
06250       p->expiry = refresh;
06251    }
06252    if (p->expiry && sin->sin_addr.s_addr) {
06253       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06254       if (p->expire == -1)
06255          peer_unref(p);
06256    }
06257    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06258    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06259    if (sin->sin_addr.s_addr) {
06260       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06261       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06262       if (!ast_strlen_zero(p->mailbox)) {
06263          int new, old;
06264          ast_app_inboxcount(p->mailbox, &new, &old);
06265          if (new > 255)
06266             new = 255;
06267          if (old > 255)
06268             old = 255;
06269          msgcount = (old << 8) | new;
06270          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06271       }
06272       if (ast_test_flag(p, IAX_HASCALLERID)) {
06273          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06274          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06275       }
06276    }
06277    version = iax_check_version(devtype);
06278    if (version) 
06279       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06280 
06281    res = 0;
06282 
06283 return_unref:
06284    peer_unref(p);
06285 
06286    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06287 }
06288 
06289 static int registry_authrequest(int callno)
06290 {
06291    struct iax_ie_data ied;
06292    struct iax2_peer *p;
06293    char challenge[10];
06294    const char *peer_name;
06295    int res = -1;
06296 
06297    peer_name = ast_strdupa(iaxs[callno]->peer);
06298 
06299    /* SLD: third call to find_peer in registration */
06300    ast_mutex_unlock(&iaxsl[callno]);
06301    p = find_peer(peer_name, 1);
06302    ast_mutex_lock(&iaxsl[callno]);
06303    if (!iaxs[callno])
06304       goto return_unref;
06305    if (!p) {
06306       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06307       goto return_unref;
06308    }
06309    
06310    memset(&ied, 0, sizeof(ied));
06311    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06312    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06313       /* Build the challenge */
06314       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06315       ast_string_field_set(iaxs[callno], challenge, challenge);
06316       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06317    }
06318    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06319 
06320    res = 0;
06321 
06322 return_unref:
06323    peer_unref(p);
06324 
06325    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06326 }
06327 
06328 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06329 {
06330    struct iax2_registry *reg;
06331    /* Start pessimistic */
06332    struct iax_ie_data ied;
06333    char peer[256] = "";
06334    char challenge[256] = "";
06335    int res;
06336    int authmethods = 0;
06337    if (ies->authmethods)
06338       authmethods = ies->authmethods;
06339    if (ies->username)
06340       ast_copy_string(peer, ies->username, sizeof(peer));
06341    if (ies->challenge)
06342       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06343    memset(&ied, 0, sizeof(ied));
06344    reg = iaxs[callno]->reg;
06345    if (reg) {
06346          if (inaddrcmp(&reg->addr, sin)) {
06347             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06348             return -1;
06349          }
06350          if (ast_strlen_zero(reg->secret)) {
06351             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06352             reg->regstate = REG_STATE_NOAUTH;
06353             return -1;
06354          }
06355          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06356          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06357          if (reg->secret[0] == '[') {
06358             char tmpkey[256];
06359             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06360             tmpkey[strlen(tmpkey) - 1] = '\0';
06361             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
06362          } else
06363             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
06364          if (!res) {
06365             reg->regstate = REG_STATE_AUTHSENT;
06366             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06367          } else
06368             return -1;
06369          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06370    } else   
06371       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06372    return -1;
06373 }
06374 
06375 static void stop_stuff(int callno)
06376 {
06377    iax2_destroy_helper(iaxs[callno]);
06378 }
06379 
06380 static void __auth_reject(const void *nothing)
06381 {
06382    /* Called from IAX thread only, without iaxs lock */
06383    int callno = (int)(long)(nothing);
06384    struct iax_ie_data ied;
06385    ast_mutex_lock(&iaxsl[callno]);
06386    if (iaxs[callno]) {
06387       memset(&ied, 0, sizeof(ied));
06388       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06389          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06390          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06391       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06392          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06393          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06394       }
06395       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06396    }
06397    ast_mutex_unlock(&iaxsl[callno]);
06398 }
06399 
06400 static int auth_reject(const void *data)
06401 {
06402    int callno = (int)(long)(data);
06403    ast_mutex_lock(&iaxsl[callno]);
06404    if (iaxs[callno])
06405       iaxs[callno]->authid = -1;
06406    ast_mutex_unlock(&iaxsl[callno]);
06407 #ifdef SCHED_MULTITHREADED
06408    if (schedule_action(__auth_reject, data))
06409 #endif      
06410       __auth_reject(data);
06411    return 0;
06412 }
06413 
06414 static int auth_fail(int callno, int failcode)
06415 {
06416    /* Schedule sending the authentication failure in one second, to prevent
06417       guessing */
06418    if (iaxs[callno]) {
06419       iaxs[callno]->authfail = failcode;
06420       if (delayreject) {
06421          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06422          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06423       } else
06424          auth_reject((void *)(long)callno);
06425    }
06426    return 0;
06427 }
06428 
06429 static void __auto_hangup(const void *nothing)
06430 {
06431    /* Called from IAX thread only, without iaxs lock */
06432    int callno = (int)(long)(nothing);
06433    struct iax_ie_data ied;
06434    ast_mutex_lock(&iaxsl[callno]);
06435    if (iaxs[callno]) {
06436       memset(&ied, 0, sizeof(ied));
06437       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06438       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06439       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06440    }
06441    ast_mutex_unlock(&iaxsl[callno]);
06442 }
06443 
06444 static int auto_hangup(const void *data)
06445 {
06446    int callno = (int)(long)(data);
06447    ast_mutex_lock(&iaxsl[callno]);
06448    if (iaxs[callno]) {
06449       iaxs[callno]->autoid = -1;
06450    }
06451    ast_mutex_unlock(&iaxsl[callno]);
06452 #ifdef SCHED_MULTITHREADED
06453    if (schedule_action(__auto_hangup, data))
06454 #endif      
06455       __auto_hangup(data);
06456    return 0;
06457 }
06458 
06459 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06460 {
06461    struct iax_ie_data ied;
06462    /* Auto-hangup with 30 seconds of inactivity */
06463    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06464    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06465    memset(&ied, 0, sizeof(ied));
06466    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06467    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06468    dp->flags |= CACHE_FLAG_TRANSMITTED;
06469 }
06470 
06471 static int iax2_vnak(int callno)
06472 {
06473    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06474 }
06475 
06476 static void vnak_retransmit(int callno, int last)
06477 {
06478    struct iax_frame *f;
06479 
06480    AST_LIST_LOCK(&iaxq.queue);
06481    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06482       /* Send a copy immediately */
06483       if ((f->callno == callno) && iaxs[f->callno] &&
06484          ((unsigned char ) (f->oseqno - last) < 128) &&
06485          (f->retries >= 0)) {
06486          send_packet(f);
06487       }
06488    }
06489    AST_LIST_UNLOCK(&iaxq.queue);
06490 }
06491 
06492 static void __iax2_poke_peer_s(const void *data)
06493 {
06494    struct iax2_peer *peer = (struct iax2_peer *)data;
06495    iax2_poke_peer(peer, 0);
06496    peer_unref(peer);
06497 }
06498 
06499 static int iax2_poke_peer_s(const void *data)
06500 {
06501    struct iax2_peer *peer = (struct iax2_peer *)data;
06502    peer->pokeexpire = -1;
06503 #ifdef SCHED_MULTITHREADED
06504    if (schedule_action(__iax2_poke_peer_s, data))
06505 #endif      
06506       __iax2_poke_peer_s(data);
06507    return 0;
06508 }
06509 
06510 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06511 {
06512    int res = 0;
06513    struct iax_frame *fr;
06514    struct ast_iax2_meta_hdr *meta;
06515    struct ast_iax2_meta_trunk_hdr *mth;
06516    int calls = 0;
06517    
06518    /* Point to frame */
06519    fr = (struct iax_frame *)tpeer->trunkdata;
06520    /* Point to meta data */
06521    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06522    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06523    if (tpeer->trunkdatalen) {
06524       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06525       meta->zeros = 0;
06526       meta->metacmd = IAX_META_TRUNK;
06527       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06528          meta->cmddata = IAX_META_TRUNK_MINI;
06529       else
06530          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06531       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06532       /* And the rest of the ast_iax2 header */
06533       fr->direction = DIRECTION_OUTGRESS;
06534       fr->retrans = -1;
06535       fr->transfer = 0;
06536       /* Any appropriate call will do */
06537       fr->data = fr->afdata;
06538       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06539       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06540       calls = tpeer->calls;
06541 #if 0
06542       if (option_debug)
06543          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));
06544 #endif      
06545       /* Reset transmit trunk side data */
06546       tpeer->trunkdatalen = 0;
06547       tpeer->calls = 0;
06548    }
06549    if (res < 0)
06550       return res;
06551    return calls;
06552 }
06553 
06554 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06555 {
06556    /* Drop when trunk is about 5 seconds idle */
06557    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06558       return 1;
06559    return 0;
06560 }
06561 
06562 static int timing_read(int *id, int fd, short events, void *cbdata)
06563 {
06564    char buf[1024];
06565    int res;
06566    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06567    int processed = 0;
06568    int totalcalls = 0;
06569 #ifdef ZT_TIMERACK
06570    int x = 1;
06571 #endif
06572    struct timeval now;
06573    if (iaxtrunkdebug)
06574       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06575    gettimeofday(&now, NULL);
06576    if (events & AST_IO_PRI) {
06577 #ifdef ZT_TIMERACK
06578       /* Great, this is a timing interface, just call the ioctl */
06579       if (ioctl(fd, ZT_TIMERACK, &x)) {
06580          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06581          usleep(1);
06582          return -1;
06583       }
06584 #endif      
06585    } else {
06586       /* Read and ignore from the pseudo channel for timing */
06587       res = read(fd, buf, sizeof(buf));
06588       if (res < 1) {
06589          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06590          return 1;
06591       }
06592    }
06593    /* For each peer that supports trunking... */
06594    ast_mutex_lock(&tpeerlock);
06595    tpeer = tpeers;
06596    while(tpeer) {
06597       processed++;
06598       res = 0;
06599       ast_mutex_lock(&tpeer->lock);
06600       /* We can drop a single tpeer per pass.  That makes all this logic
06601          substantially easier */
06602       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06603          /* Take it out of the list, but don't free it yet, because it
06604             could be in use */
06605          if (prev)
06606             prev->next = tpeer->next;
06607          else
06608             tpeers = tpeer->next;
06609          drop = tpeer;
06610       } else {
06611          res = send_trunk(tpeer, &now);
06612          if (iaxtrunkdebug)
06613             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);
06614       }     
06615       totalcalls += res;   
06616       res = 0;
06617       ast_mutex_unlock(&tpeer->lock);
06618       prev = tpeer;
06619       tpeer = tpeer->next;
06620    }
06621    ast_mutex_unlock(&tpeerlock);
06622    if (drop) {
06623       ast_mutex_lock(&drop->lock);
06624       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06625          because by the time they could get tpeerlock, we've already grabbed it */
06626       if (option_debug)
06627          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06628       if (drop->trunkdata) {
06629          free(drop->trunkdata);
06630          drop->trunkdata = NULL;
06631       }
06632       ast_mutex_unlock(&drop->lock);
06633       ast_mutex_destroy(&drop->lock);
06634       free(drop);
06635       
06636    }
06637    if (iaxtrunkdebug)
06638       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06639    iaxtrunkdebug =0;
06640    return 1;
06641 }
06642 
06643 struct dpreq_data {
06644    int callno;
06645    char context[AST_MAX_EXTENSION];
06646    char callednum[AST_MAX_EXTENSION];
06647    char *callerid;
06648 };
06649 
06650 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06651 {
06652    unsigned short dpstatus = 0;
06653    struct iax_ie_data ied1;
06654    int mm;
06655 
06656    memset(&ied1, 0, sizeof(ied1));
06657    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06658    /* Must be started */
06659    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06660       dpstatus = IAX_DPSTATUS_EXISTS;
06661    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06662       dpstatus = IAX_DPSTATUS_CANEXIST;
06663    } else {
06664       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06665    }
06666    if (ast_ignore_pattern(context, callednum))
06667       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06668    if (mm)
06669       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06670    if (!skiplock)
06671       ast_mutex_lock(&iaxsl[callno]);
06672    if (iaxs[callno]) {
06673       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06674       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06675       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06676       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06677    }
06678    if (!skiplock)
06679       ast_mutex_unlock(&iaxsl[callno]);
06680 }
06681 
06682 static void *dp_lookup_thread(void *data)
06683 {
06684    /* Look up for dpreq */
06685    struct dpreq_data *dpr = data;
06686    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06687    if (dpr->callerid)
06688       free(dpr->callerid);
06689    free(dpr);
06690    return NULL;
06691 }
06692 
06693 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06694 {
06695    pthread_t newthread;
06696    struct dpreq_data *dpr;
06697    pthread_attr_t attr;
06698    
06699    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06700       return;
06701 
06702    pthread_attr_init(&attr);
06703    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06704 
06705    dpr->callno = callno;
06706    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06707    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06708    if (callerid)
06709       dpr->callerid = ast_strdup(callerid);
06710    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06711       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06712    }
06713 
06714    pthread_attr_destroy(&attr);
06715 }
06716 
06717 struct iax_dual {
06718    struct ast_channel *chan1;
06719    struct ast_channel *chan2;
06720 };
06721 
06722 static void *iax_park_thread(void *stuff)
06723 {
06724    struct ast_channel *chan1, *chan2;
06725    struct iax_dual *d;
06726    struct ast_frame *f;
06727    int ext;
06728    int res;
06729    d = stuff;
06730    chan1 = d->chan1;
06731    chan2 = d->chan2;
06732    free(d);
06733    f = ast_read(chan1);
06734    if (f)
06735       ast_frfree(f);
06736    res = ast_park_call(chan1, chan2, 0, &ext);
06737    ast_hangup(chan2);
06738    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06739    return NULL;
06740 }
06741 
06742 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06743 {
06744    struct iax_dual *d;
06745    struct ast_channel *chan1m, *chan2m;
06746    pthread_t th;
06747    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06748    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06749    if (chan2m && chan1m) {
06750       /* Make formats okay */
06751       chan1m->readformat = chan1->readformat;
06752       chan1m->writeformat = chan1->writeformat;
06753       ast_channel_masquerade(chan1m, chan1);
06754       /* Setup the extensions and such */
06755       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06756       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06757       chan1m->priority = chan1->priority;
06758       
06759       /* We make a clone of the peer channel too, so we can play
06760          back the announcement */
06761       /* Make formats okay */
06762       chan2m->readformat = chan2->readformat;
06763       chan2m->writeformat = chan2->writeformat;
06764       ast_channel_masquerade(chan2m, chan2);
06765       /* Setup the extensions and such */
06766       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06767       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06768       chan2m->priority = chan2->priority;
06769       if (ast_do_masquerade(chan2m)) {
06770          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06771          ast_hangup(chan2m);
06772          return -1;
06773       }
06774    } else {
06775       if (chan1m)
06776          ast_hangup(chan1m);
06777       if (chan2m)
06778          ast_hangup(chan2m);
06779       return -1;
06780    }
06781    if ((d = ast_calloc(1, sizeof(*d)))) {
06782       pthread_attr_t attr;
06783 
06784       pthread_attr_init(&attr);
06785       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06786 
06787       d->chan1 = chan1m;
06788       d->chan2 = chan2m;
06789       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06790          pthread_attr_destroy(&attr);
06791          return 0;
06792       }
06793       pthread_attr_destroy(&attr);
06794       free(d);
06795    }
06796    return -1;
06797 }
06798 
06799 
06800 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06801 
06802 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06803 {
06804    unsigned int ourver;
06805    char rsi[80];
06806    snprintf(rsi, sizeof(rsi), "si-%s", si);
06807    if (iax_provision_version(&ourver, rsi, 1))
06808       return 0;
06809    if (option_debug)
06810       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06811    if (ourver != ver) 
06812       iax2_provision(sin, sockfd, NULL, rsi, 1);
06813    return 0;
06814 }
06815 
06816 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06817 {
06818    jb_info stats;
06819    jb_getinfo(pvt->jb, &stats);
06820    
06821    memset(iep, 0, sizeof(*iep));
06822 
06823    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06824    if(stats.frames_in == 0) stats.frames_in = 1;
06825    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06826    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06827    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06828    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06829    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06830 }
06831 
06832 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06833 {
06834    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06835    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06836    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06837    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06838    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06839    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06840    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06841 }
06842 
06843 static int socket_process(struct iax2_thread *thread);
06844 
06845 /*!
06846  * \brief Handle any deferred full frames for this thread
06847  */
06848 static void handle_deferred_full_frames(struct iax2_thread *thread)
06849 {
06850    struct iax2_pkt_buf *pkt_buf;
06851 
06852    ast_mutex_lock(&thread->lock);
06853 
06854    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06855       ast_mutex_unlock(&thread->lock);
06856 
06857       thread->buf = pkt_buf->buf;
06858       thread->buf_len = pkt_buf->len;
06859       thread->buf_size = pkt_buf->len + 1;
06860       
06861       socket_process(thread);
06862 
06863       thread->buf = NULL;
06864       ast_free(pkt_buf);
06865 
06866       ast_mutex_lock(&thread->lock);
06867    }
06868 
06869    ast_mutex_unlock(&thread->lock);
06870 }
06871 
06872 /*!
06873  * \brief Queue the last read full frame for processing by a certain thread
06874  *
06875  * If there are already any full frames queued, they are sorted
06876  * by sequence number.
06877  */
06878 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06879 {
06880    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06881    struct ast_iax2_full_hdr *fh, *cur_fh;
06882 
06883    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06884       return;
06885 
06886    pkt_buf->len = from_here->buf_len;
06887    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06888 
06889    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06890    ast_mutex_lock(&to_here->lock);
06891    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06892       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06893       if (fh->oseqno < cur_fh->oseqno) {
06894          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06895          break;
06896       }
06897    }
06898    AST_LIST_TRAVERSE_SAFE_END
06899 
06900    if (!cur_pkt_buf)
06901       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06902    
06903    ast_mutex_unlock(&to_here->lock);
06904 }
06905 
06906 static int socket_read(int *id, int fd, short events, void *cbdata)
06907 {
06908    struct iax2_thread *thread;
06909    socklen_t len;
06910    time_t t;
06911    static time_t last_errtime = 0;
06912    struct ast_iax2_full_hdr *fh;
06913 
06914    if (!(thread = find_idle_thread())) {
06915       time(&t);
06916       if (t != last_errtime && option_debug)
06917          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06918       last_errtime = t;
06919       usleep(1);
06920       return 1;
06921    }
06922 
06923    len = sizeof(thread->iosin);
06924    thread->iofd = fd;
06925    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06926    thread->buf_size = sizeof(thread->readbuf);
06927    thread->buf = thread->readbuf;
06928    if (thread->buf_len < 0) {
06929       if (errno != ECONNREFUSED && errno != EAGAIN)
06930          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06931       handle_error();
06932       thread->iostate = IAX_IOSTATE_IDLE;
06933       signal_condition(&thread->lock, &thread->cond);
06934       return 1;
06935    }
06936    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06937       thread->iostate = IAX_IOSTATE_IDLE;
06938       signal_condition(&thread->lock, &thread->cond);
06939       return 1;
06940    }
06941    
06942    /* Determine if this frame is a full frame; if so, and any thread is currently
06943       processing a full frame for the same callno from this peer, then drop this
06944       frame (and the peer will retransmit it) */
06945    fh = (struct ast_iax2_full_hdr *) thread->buf;
06946    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06947       struct iax2_thread *cur = NULL;
06948       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06949       
06950       AST_LIST_LOCK(&active_list);
06951       AST_LIST_TRAVERSE(&active_list, cur, list) {
06952          if ((cur->ffinfo.callno == callno) &&
06953              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06954             break;
06955       }
06956       if (cur) {
06957          /* we found another thread processing a full frame for this call,
06958             so queue it up for processing later. */
06959          defer_full_frame(thread, cur);
06960          AST_LIST_UNLOCK(&active_list);
06961          thread->iostate = IAX_IOSTATE_IDLE;
06962          signal_condition(&thread->lock, &thread->cond);
06963          return 1;
06964       } else {
06965          /* this thread is going to process this frame, so mark it */
06966          thread->ffinfo.callno = callno;
06967          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06968          thread->ffinfo.type = fh->type;
06969          thread->ffinfo.csub = fh->csub;
06970       }
06971       AST_LIST_UNLOCK(&active_list);
06972    }
06973    
06974    /* Mark as ready and send on its way */
06975    thread->iostate = IAX_IOSTATE_READY;
06976 #ifdef DEBUG_SCHED_MULTITHREAD
06977    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06978 #endif
06979    signal_condition(&thread->lock, &thread->cond);
06980 
06981    return 1;
06982 }
06983 
06984 static int socket_process(struct iax2_thread *thread)
06985 {
06986    struct sockaddr_in sin;
06987    int res;
06988    int updatehistory=1;
06989    int new = NEW_PREVENT;
06990    void *ptr;
06991    int dcallno = 0;
06992    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06993    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06994    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06995    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06996    struct ast_iax2_meta_trunk_hdr *mth;
06997    struct ast_iax2_meta_trunk_entry *mte;
06998    struct ast_iax2_meta_trunk_mini *mtm;
06999    struct iax_frame *fr;
07000    struct iax_frame *cur;
07001    struct ast_frame f = { 0, };
07002    struct ast_channel *c;
07003    struct iax2_dpcache *dp;
07004    struct iax2_peer *peer;
07005    struct iax2_trunk_peer *tpeer;
07006    struct timeval rxtrunktime;
07007    struct iax_ies ies;
07008    struct iax_ie_data ied0, ied1;
07009    int format;
07010    int fd;
07011    int exists;
07012    int minivid = 0;
07013    unsigned int ts;
07014    char empty[32]="";      /* Safety measure */
07015    struct iax_frame *duped_fr;
07016    char host_pref_buf[128];
07017    char caller_pref_buf[128];
07018    struct ast_codec_pref pref;
07019    char *using_prefs = "mine";
07020 
07021    /* allocate an iax_frame with 4096 bytes of data buffer */
07022    fr = alloca(sizeof(*fr) + 4096);
07023    memset(fr, 0, sizeof(*fr));
07024    fr->afdatalen = 4096; /* From alloca() above */
07025 
07026    /* Copy frequently used parameters to the stack */
07027    res = thread->buf_len;
07028    fd = thread->iofd;
07029    memcpy(&sin, &thread->iosin, sizeof(sin));
07030 
07031    if (res < sizeof(*mh)) {
07032       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07033       return 1;
07034    }
07035    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07036       if (res < sizeof(*vh)) {
07037          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));
07038          return 1;
07039       }
07040 
07041       /* This is a video frame, get call number */
07042       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07043       minivid = 1;
07044    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07045       unsigned char metatype;
07046 
07047       if (res < sizeof(*meta)) {
07048          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));
07049          return 1;
07050       }
07051 
07052       /* This is a meta header */
07053       switch(meta->metacmd) {
07054       case IAX_META_TRUNK:
07055          if (res < (sizeof(*meta) + sizeof(*mth))) {
07056             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07057                sizeof(*meta) + sizeof(*mth));
07058             return 1;
07059          }
07060          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07061          ts = ntohl(mth->ts);
07062          metatype = meta->cmddata;
07063          res -= (sizeof(*meta) + sizeof(*mth));
07064          ptr = mth->data;
07065          tpeer = find_tpeer(&sin, fd);
07066          if (!tpeer) {
07067             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));
07068             return 1;
07069          }
07070          tpeer->trunkact = ast_tvnow();
07071          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07072             tpeer->rxtrunktime = tpeer->trunkact;
07073          rxtrunktime = tpeer->rxtrunktime;
07074          ast_mutex_unlock(&tpeer->lock);
07075          while(res >= sizeof(*mte)) {
07076             /* Process channels */
07077             unsigned short callno, trunked_ts, len;
07078 
07079             if (metatype == IAX_META_TRUNK_MINI) {
07080                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07081                ptr += sizeof(*mtm);
07082                res -= sizeof(*mtm);
07083                len = ntohs(mtm->len);
07084                callno = ntohs(mtm->mini.callno);
07085                trunked_ts = ntohs(mtm->mini.ts);
07086             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07087                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07088                ptr += sizeof(*mte);
07089                res -= sizeof(*mte);
07090                len = ntohs(mte->len);
07091                callno = ntohs(mte->callno);
07092                trunked_ts = 0;
07093             } else {
07094                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07095                break;
07096             }
07097             /* Stop if we don't have enough data */
07098             if (len > res)
07099                break;
07100             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07101             if (fr->callno) {
07102                /* If it's a valid call, deliver the contents.  If not, we
07103                   drop it, since we don't have a scallno to use for an INVAL */
07104                /* Process as a mini frame */
07105                memset(&f, 0, sizeof(f));
07106                f.frametype = AST_FRAME_VOICE;
07107                if (iaxs[fr->callno]) {
07108                   if (iaxs[fr->callno]->voiceformat > 0) {
07109                      f.subclass = iaxs[fr->callno]->voiceformat;
07110                      f.datalen = len;
07111                      if (f.datalen >= 0) {
07112                         if (f.datalen)
07113                            f.data = ptr;
07114                         if(trunked_ts) {
07115                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07116                         } else
07117                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07118                         /* Don't pass any packets until we're started */
07119                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07120                            /* Common things */
07121                            f.src = "IAX2";
07122                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07123                               f.samples = ast_codec_get_samples(&f);
07124                            iax_frame_wrap(fr, &f);
07125                            duped_fr = iaxfrdup2(fr);
07126                            if (duped_fr) {
07127                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07128                            }
07129                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07130                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07131                               iaxs[fr->callno]->last = fr->ts;
07132 #if 1
07133                               if (option_debug && iaxdebug)
07134                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07135 #endif
07136                            }
07137                         }
07138                      } else {
07139                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07140                      }
07141                   } else {
07142                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07143                      iax2_vnak(fr->callno);
07144                   }
07145                }
07146                ast_mutex_unlock(&iaxsl[fr->callno]);
07147             }
07148             ptr += len;
07149             res -= len;
07150          }
07151          
07152       }
07153       return 1;
07154    }
07155 
07156 #ifdef DEBUG_SUPPORT
07157    if (iaxdebug && (res >= sizeof(*fh)))
07158       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07159 #endif
07160    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07161       if (res < sizeof(*fh)) {
07162          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));
07163          return 1;
07164       }
07165 
07166       /* Get the destination call number */
07167       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07168       /* Retrieve the type and subclass */
07169       f.frametype = fh->type;
07170       if (f.frametype == AST_FRAME_VIDEO) {
07171          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07172       } else {
07173          f.subclass = uncompress_subclass(fh->csub);
07174       }
07175 
07176       /* Deal with POKE/PONG without allocating a callno */
07177       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07178          /* Reply back with a PONG, but don't care about the result. */
07179          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07180          return 1;
07181       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07182          /* Ignore */
07183          return 1;
07184       }
07185 
07186       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07187                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07188                          (f.subclass == IAX_COMMAND_REGREL)))
07189          new = NEW_ALLOW;
07190    } else {
07191       /* Don't know anything about it yet */
07192       f.frametype = AST_FRAME_NULL;
07193       f.subclass = 0;
07194    }
07195 
07196    if (!fr->callno) {
07197       int check_dcallno = 0;
07198 
07199       /*
07200        * We enforce accurate destination call numbers for all full frames except
07201        * LAGRQ and PING commands.  This is because older versions of Asterisk
07202        * schedule these commands to get sent very quickly, and they will sometimes
07203        * be sent before they receive the first frame from the other side.  When
07204        * that happens, it doesn't contain the destination call number.  However,
07205        * not checking it for these frames is safe.
07206        * 
07207        * Discussed in the following thread:
07208        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07209        */
07210 
07211       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07212          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07213       }
07214 
07215       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07216    }
07217 
07218    if (fr->callno > 0)
07219       ast_mutex_lock(&iaxsl[fr->callno]);
07220 
07221    if (!fr->callno || !iaxs[fr->callno]) {
07222       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07223          frame, reply with an inval */
07224       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07225          /* We can only raw hangup control frames */
07226          if (((f.subclass != IAX_COMMAND_INVAL) &&
07227              (f.subclass != IAX_COMMAND_TXCNT) &&
07228              (f.subclass != IAX_COMMAND_TXACC) &&
07229              (f.subclass != IAX_COMMAND_FWDOWNL))||
07230              (f.frametype != AST_FRAME_IAX))
07231             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07232             fd);
07233       }
07234       if (fr->callno > 0) 
07235          ast_mutex_unlock(&iaxsl[fr->callno]);
07236       return 1;
07237    }
07238    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07239       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07240          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07241          ast_mutex_unlock(&iaxsl[fr->callno]);
07242          return 1;
07243       }
07244 #ifdef DEBUG_SUPPORT
07245       else if (iaxdebug)
07246          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07247 #endif
07248    }
07249 
07250    /* count this frame */
07251    iaxs[fr->callno]->frames_received++;
07252 
07253    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07254       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07255       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07256       unsigned short new_peercallno;
07257 
07258       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07259       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07260          if (iaxs[fr->callno]->peercallno) {
07261             remove_by_peercallno(iaxs[fr->callno]);
07262          }
07263          iaxs[fr->callno]->peercallno = new_peercallno;
07264          store_by_peercallno(iaxs[fr->callno]);
07265       }
07266    }
07267    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07268       if (option_debug  && iaxdebug)
07269          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07270       /* Check if it's out of order (and not an ACK or INVAL) */
07271       fr->oseqno = fh->oseqno;
07272       fr->iseqno = fh->iseqno;
07273       fr->ts = ntohl(fh->ts);
07274 #ifdef IAXTESTS
07275       if (test_resync) {
07276          if (option_debug)
07277             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07278          fr->ts += test_resync;
07279       }
07280 #endif /* IAXTESTS */
07281 #if 0
07282       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07283            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07284                         (f.subclass == IAX_COMMAND_NEW ||
07285                          f.subclass == IAX_COMMAND_AUTHREQ ||
07286                          f.subclass == IAX_COMMAND_ACCEPT ||
07287                          f.subclass == IAX_COMMAND_REJECT))      ) )
07288 #endif
07289       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07290          updatehistory = 0;
07291       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07292          (iaxs[fr->callno]->iseqno ||
07293             ((f.subclass != IAX_COMMAND_TXCNT) &&
07294             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07295             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07296             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07297             (f.subclass != IAX_COMMAND_TXACC)) ||
07298             (f.frametype != AST_FRAME_IAX))) {
07299          if (
07300           ((f.subclass != IAX_COMMAND_ACK) &&
07301            (f.subclass != IAX_COMMAND_INVAL) &&
07302            (f.subclass != IAX_COMMAND_TXCNT) &&
07303            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07304            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07305            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07306            (f.subclass != IAX_COMMAND_TXACC) &&
07307            (f.subclass != IAX_COMMAND_VNAK)) ||
07308            (f.frametype != AST_FRAME_IAX)) {
07309             /* If it's not an ACK packet, it's out of order. */
07310             if (option_debug)
07311                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07312                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07313             /* Check to see if we need to request retransmission,
07314              * and take sequence number wraparound into account */
07315             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07316                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07317                if ((f.frametype != AST_FRAME_IAX) || 
07318                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07319                   if (option_debug)
07320                      ast_log(LOG_DEBUG, "Acking anyway\n");
07321                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07322                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07323                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07324                }
07325             } else {
07326                /* Send a VNAK requesting retransmission */
07327                iax2_vnak(fr->callno);
07328             }
07329             ast_mutex_unlock(&iaxsl[fr->callno]);
07330             return 1;
07331          }
07332       } else {
07333          /* Increment unless it's an ACK or VNAK */
07334          if (((f.subclass != IAX_COMMAND_ACK) &&
07335              (f.subclass != IAX_COMMAND_INVAL) &&
07336              (f.subclass != IAX_COMMAND_TXCNT) &&
07337              (f.subclass != IAX_COMMAND_TXACC) &&
07338             (f.subclass != IAX_COMMAND_VNAK)) ||
07339              (f.frametype != AST_FRAME_IAX))
07340             iaxs[fr->callno]->iseqno++;
07341       }
07342       /* A full frame */
07343       if (res < sizeof(*fh)) {
07344          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07345          ast_mutex_unlock(&iaxsl[fr->callno]);
07346          return 1;
07347       }
07348       /* Ensure text frames are NULL-terminated */
07349       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07350          if (res < thread->buf_size)
07351             thread->buf[res++] = '\0';
07352          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07353             thread->buf[res - 1] = '\0';
07354       }
07355       f.datalen = res - sizeof(*fh);
07356 
07357       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07358          from the real peer, not the transfer peer */
07359       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07360           ((f.subclass != IAX_COMMAND_INVAL) ||
07361            (f.frametype != AST_FRAME_IAX))) {
07362          unsigned char x;
07363          int call_to_destroy;
07364          /* XXX This code is not very efficient.  Surely there is a better way which still
07365                 properly handles boundary conditions? XXX */
07366          /* First we have to qualify that the ACKed value is within our window */
07367          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07368             if (fr->iseqno == x)
07369                break;
07370          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07371             /* The acknowledgement is within our window.  Time to acknowledge everything
07372                that it says to */
07373             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07374                /* Ack the packet with the given timestamp */
07375                if (option_debug && iaxdebug)
07376                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07377                call_to_destroy = 0;
07378                AST_LIST_LOCK(&iaxq.queue);
07379                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07380                   /* If it's our call, and our timestamp, mark -1 retries */
07381                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07382                      cur->retries = -1;
07383                      /* Destroy call if this is the end */
07384                      if (cur->final)
07385                         call_to_destroy = fr->callno;
07386                   }
07387                }
07388                AST_LIST_UNLOCK(&iaxq.queue);
07389                if (call_to_destroy) {
07390                   if (iaxdebug && option_debug)
07391                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07392                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07393                   iax2_destroy(call_to_destroy);
07394                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07395                }
07396             }
07397             /* Note how much we've received acknowledgement for */
07398             if (iaxs[fr->callno])
07399                iaxs[fr->callno]->rseqno = fr->iseqno;
07400             else {
07401                /* Stop processing now */
07402                ast_mutex_unlock(&iaxsl[fr->callno]);
07403                return 1;
07404             }
07405          } else if (option_debug)
07406             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07407       }
07408       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07409          ((f.frametype != AST_FRAME_IAX) || 
07410           ((f.subclass != IAX_COMMAND_TXACC) &&
07411            (f.subclass != IAX_COMMAND_TXCNT)))) {
07412          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07413          ast_mutex_unlock(&iaxsl[fr->callno]);
07414          return 1;
07415       }
07416 
07417       if (f.datalen) {
07418          if (f.frametype == AST_FRAME_IAX) {
07419             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07420                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07421                ast_mutex_unlock(&iaxsl[fr->callno]);
07422                return 1;
07423             }
07424             f.data = NULL;
07425             f.datalen = 0;
07426          } else
07427             f.data = thread->buf + sizeof(*fh);
07428       } else {
07429          if (f.frametype == AST_FRAME_IAX)
07430             f.data = NULL;
07431          else
07432             f.data = empty;
07433          memset(&ies, 0, sizeof(ies));
07434       }
07435 
07436       /* when we receive the first full frame for a new incoming channel,
07437          it is safe to start the PBX on the channel because we have now
07438          completed a 3-way handshake with the peer */
07439       if ((f.frametype == AST_FRAME_VOICE) ||
07440           (f.frametype == AST_FRAME_VIDEO) ||
07441           (f.frametype == AST_FRAME_IAX)) {
07442          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07443             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07444             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07445                ast_mutex_unlock(&iaxsl[fr->callno]);
07446                return 1;
07447             }
07448          }
07449       }
07450 
07451       if (f.frametype == AST_FRAME_VOICE) {
07452          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07453                iaxs[fr->callno]->voiceformat = f.subclass;
07454                if (option_debug)
07455                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07456                if (iaxs[fr->callno]->owner) {
07457                   int orignative;
07458 retryowner:
07459                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07460                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07461                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07462                   }
07463                   if (iaxs[fr->callno]) {
07464                      if (iaxs[fr->callno]->owner) {
07465                         orignative = iaxs[fr->callno]->owner->nativeformats;
07466                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07467                         if (iaxs[fr->callno]->owner->readformat)
07468                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07469                         iaxs[fr->callno]->owner->nativeformats = orignative;
07470                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07471                      }
07472                   } else {
07473                      if (option_debug)
07474                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07475                      ast_mutex_unlock(&iaxsl[fr->callno]);
07476                      return 1;
07477                   }
07478                }
07479          }
07480       }
07481       if (f.frametype == AST_FRAME_VIDEO) {
07482          if (f.subclass != iaxs[fr->callno]->videoformat) {
07483             if (option_debug)
07484                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07485             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07486          }
07487       }
07488       if (f.frametype == AST_FRAME_IAX) {
07489          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07490          /* Handle the IAX pseudo frame itself */
07491          if (option_debug && iaxdebug)
07492             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07493 
07494                         /* Update last ts unless the frame's timestamp originated with us. */
07495          if (iaxs[fr->callno]->last < fr->ts &&
07496                             f.subclass != IAX_COMMAND_ACK &&
07497                             f.subclass != IAX_COMMAND_PONG &&
07498                             f.subclass != IAX_COMMAND_LAGRP) {
07499             iaxs[fr->callno]->last = fr->ts;
07500             if (option_debug && iaxdebug)
07501                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07502          }
07503 
07504          switch(f.subclass) {
07505          case IAX_COMMAND_ACK:
07506             /* Do nothing */
07507             break;
07508          case IAX_COMMAND_QUELCH:
07509             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07510                     /* Generate Manager Hold event, if necessary*/
07511                if (iaxs[fr->callno]->owner) {
07512                   manager_event(EVENT_FLAG_CALL, "Hold",
07513                      "Channel: %s\r\n"
07514                      "Uniqueid: %s\r\n",
07515                      iaxs[fr->callno]->owner->name, 
07516                      iaxs[fr->callno]->owner->uniqueid);
07517                }
07518 
07519                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07520                if (ies.musiconhold) {
07521                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07522                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07523                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07524                         S_OR(mohsuggest, NULL),
07525                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07526                      if (!iaxs[fr->callno]) {
07527                         ast_mutex_unlock(&iaxsl[fr->callno]);
07528                         return 1;
07529                      }
07530                   }
07531                }
07532             }
07533             break;
07534          case IAX_COMMAND_UNQUELCH:
07535             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07536                     /* Generate Manager Unhold event, if necessary*/
07537                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07538                   manager_event(EVENT_FLAG_CALL, "Unhold",
07539                      "Channel: %s\r\n"
07540                      "Uniqueid: %s\r\n",
07541                      iaxs[fr->callno]->owner->name, 
07542                      iaxs[fr->callno]->owner->uniqueid);
07543                }
07544 
07545                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07546                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07547                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07548                   if (!iaxs[fr->callno]) {
07549                      ast_mutex_unlock(&iaxsl[fr->callno]);
07550                      return 1;
07551                   }
07552                }
07553             }
07554             break;
07555          case IAX_COMMAND_TXACC:
07556             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07557                /* Ack the packet with the given timestamp */
07558                AST_LIST_LOCK(&iaxq.queue);
07559                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07560                   /* Cancel any outstanding txcnt's */
07561                   if ((fr->callno == cur->callno) && (cur->transfer))
07562                      cur->retries = -1;
07563                }
07564                AST_LIST_UNLOCK(&iaxq.queue);
07565                memset(&ied1, 0, sizeof(ied1));
07566                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07567                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07568                iaxs[fr->callno]->transferring = TRANSFER_READY;
07569             }
07570             break;
07571          case IAX_COMMAND_NEW:
07572             /* Ignore if it's already up */
07573             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07574                break;
07575             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07576                ast_mutex_unlock(&iaxsl[fr->callno]);
07577                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07578                ast_mutex_lock(&iaxsl[fr->callno]);
07579                if (!iaxs[fr->callno]) {
07580                   ast_mutex_unlock(&iaxsl[fr->callno]);
07581                   return 1;
07582                }
07583             }
07584             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07585             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07586                int new_callno;
07587                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07588                   fr->callno = new_callno;
07589             }
07590             /* For security, always ack immediately */
07591             if (delayreject)
07592                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07593             if (check_access(fr->callno, &sin, &ies)) {
07594                /* They're not allowed on */
07595                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07596                if (authdebug)
07597                   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);
07598                break;
07599             }
07600             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07601                const char *context, *exten, *cid_num;
07602 
07603                context = ast_strdupa(iaxs[fr->callno]->context);
07604                exten = ast_strdupa(iaxs[fr->callno]->exten);
07605                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07606 
07607                /* This might re-enter the IAX code and need the lock */
07608                ast_mutex_unlock(&iaxsl[fr->callno]);
07609                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07610                ast_mutex_lock(&iaxsl[fr->callno]);
07611 
07612                if (!iaxs[fr->callno]) {
07613                   ast_mutex_unlock(&iaxsl[fr->callno]);
07614                   return 1;
07615                }
07616             } else
07617                exists = 0;
07618             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07619                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07620                   memset(&ied0, 0, sizeof(ied0));
07621                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07622                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07623                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07624                   if (!iaxs[fr->callno]) {
07625                      ast_mutex_unlock(&iaxsl[fr->callno]);
07626                      return 1;
07627                   }
07628                   if (authdebug)
07629                      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);
07630                } else {
07631                   /* Select an appropriate format */
07632 
07633                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07634                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07635                         using_prefs = "reqonly";
07636                      } else {
07637                         using_prefs = "disabled";
07638                      }
07639                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07640                      memset(&pref, 0, sizeof(pref));
07641                      strcpy(caller_pref_buf, "disabled");
07642                      strcpy(host_pref_buf, "disabled");
07643                   } else {
07644                      using_prefs = "mine";
07645                      /* If the information elements are in here... use them */
07646                      if (ies.codec_prefs)
07647                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07648                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07649                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07650                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07651                            pref = iaxs[fr->callno]->rprefs;
07652                            using_prefs = "caller";
07653                         } else {
07654                            pref = iaxs[fr->callno]->prefs;
07655                         }
07656                      } else
07657                         pref = iaxs[fr->callno]->prefs;
07658                      
07659                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07660                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07661                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07662                   }
07663                   if (!format) {
07664                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07665                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07666                      if (!format) {
07667                         memset(&ied0, 0, sizeof(ied0));
07668                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07669                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07670                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07671                         if (!iaxs[fr->callno]) {
07672                            ast_mutex_unlock(&iaxsl[fr->callno]);
07673                            return 1;
07674                         }
07675                         if (authdebug) {
07676                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07677                               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);
07678                            else 
07679                               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);
07680                         }
07681                      } else {
07682                         /* Pick one... */
07683                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07684                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07685                               format = 0;
07686                         } else {
07687                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07688                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07689                               memset(&pref, 0, sizeof(pref));
07690                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07691                               strcpy(caller_pref_buf,"disabled");
07692                               strcpy(host_pref_buf,"disabled");
07693                            } else {
07694                               using_prefs = "mine";
07695                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07696                                  /* Do the opposite of what we tried above. */
07697                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07698                                     pref = iaxs[fr->callno]->prefs;                       
07699                                  } else {
07700                                     pref = iaxs[fr->callno]->rprefs;
07701                                     using_prefs = "caller";
07702                                  }
07703                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07704                            
07705                               } else /* if no codec_prefs IE do it the old way */
07706                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07707                            }
07708                         }
07709 
07710                         if (!format) {
07711                            memset(&ied0, 0, sizeof(ied0));
07712                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07713                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07714                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07715                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07716                            if (!iaxs[fr->callno]) {
07717                               ast_mutex_unlock(&iaxsl[fr->callno]);
07718                               return 1;
07719                            }
07720                            if (authdebug)
07721                               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);
07722                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07723                            break;
07724                         }
07725                      }
07726                   }
07727                   if (format) {
07728                      /* No authentication required, let them in */
07729                      memset(&ied1, 0, sizeof(ied1));
07730                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07731                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07732                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07733                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07734                         if (option_verbose > 2) 
07735                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07736                                     "%srequested format = %s,\n"
07737                                     "%srequested prefs = %s,\n"
07738                                     "%sactual format = %s,\n"
07739                                     "%shost prefs = %s,\n"
07740                                     "%spriority = %s\n",
07741                                     ast_inet_ntoa(sin.sin_addr), 
07742                                     VERBOSE_PREFIX_4,
07743                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07744                                     VERBOSE_PREFIX_4,
07745                                     caller_pref_buf,
07746                                     VERBOSE_PREFIX_4,
07747                                     ast_getformatname(format), 
07748                                     VERBOSE_PREFIX_4,
07749                                     host_pref_buf, 
07750                                     VERBOSE_PREFIX_4,
07751                                     using_prefs);
07752                         
07753                         iaxs[fr->callno]->chosenformat = format;
07754                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07755                      } else {
07756                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07757                         /* If this is a TBD call, we're ready but now what...  */
07758                         if (option_verbose > 2)
07759                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07760                      }
07761                   }
07762                }
07763                break;
07764             }
07765             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07766                merge_encryption(iaxs[fr->callno],ies.encmethods);
07767             else
07768                iaxs[fr->callno]->encmethods = 0;
07769             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07770                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07771             if (!iaxs[fr->callno]) {
07772                ast_mutex_unlock(&iaxsl[fr->callno]);
07773                return 1;
07774             }
07775             break;
07776          case IAX_COMMAND_DPREQ:
07777             /* Request status in the dialplan */
07778             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07779                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07780                if (iaxcompat) {
07781                   /* Spawn a thread for the lookup */
07782                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07783                } else {
07784                   /* Just look it up */
07785                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07786                }
07787             }
07788             break;
07789          case IAX_COMMAND_HANGUP:
07790             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07791             if (option_debug)
07792                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07793             /* Set hangup cause according to remote */
07794             if (ies.causecode && iaxs[fr->callno]->owner)
07795                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07796             /* Send ack immediately, before we destroy */
07797             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07798             iax2_destroy(fr->callno);
07799             break;
07800          case IAX_COMMAND_REJECT:
07801             /* Set hangup cause according to remote */
07802             if (ies.causecode && iaxs[fr->callno]->owner)
07803                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07804 
07805             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07806                if (iaxs[fr->callno]->owner && authdebug)
07807                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07808                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07809                      ies.cause ? ies.cause : "<Unknown>");
07810                if (option_debug)
07811                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07812                      fr->callno);
07813             }
07814             /* Send ack immediately, before we destroy */
07815             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07816                          fr->ts, NULL, 0, fr->iseqno);
07817             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07818                iaxs[fr->callno]->error = EPERM;
07819             iax2_destroy(fr->callno);
07820             break;
07821          case IAX_COMMAND_TRANSFER:
07822          {
07823             struct ast_channel *bridged_chan;
07824 
07825             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07826                /* Set BLINDTRANSFER channel variables */
07827 
07828                ast_mutex_unlock(&iaxsl[fr->callno]);
07829                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07830                ast_mutex_lock(&iaxsl[fr->callno]);
07831                if (!iaxs[fr->callno]) {
07832                   ast_mutex_unlock(&iaxsl[fr->callno]);
07833                   return 1;
07834                }
07835 
07836                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07837                if (!strcmp(ies.called_number, ast_parking_ext())) {
07838                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07839                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07840                   } else {
07841                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07842                   }
07843                } else {
07844                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07845                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07846                         ies.called_number, iaxs[fr->callno]->context);
07847                   else
07848                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07849                         ies.called_number, iaxs[fr->callno]->context);
07850                }
07851             } else
07852                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07853 
07854             break;
07855          }
07856          case IAX_COMMAND_ACCEPT:
07857             /* Ignore if call is already up or needs authentication or is a TBD */
07858             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07859                break;
07860             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07861                /* Send ack immediately, before we destroy */
07862                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07863                iax2_destroy(fr->callno);
07864                break;
07865             }
07866             if (ies.format) {
07867                iaxs[fr->callno]->peerformat = ies.format;
07868             } else {
07869                if (iaxs[fr->callno]->owner)
07870                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07871                else
07872                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07873             }
07874             if (option_verbose > 2)
07875                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));
07876             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07877                memset(&ied0, 0, sizeof(ied0));
07878                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07879                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07880                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07881                if (!iaxs[fr->callno]) {
07882                   ast_mutex_unlock(&iaxsl[fr->callno]);
07883                   return 1;
07884                }
07885                if (authdebug)
07886                   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);
07887             } else {
07888                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07889                if (iaxs[fr->callno]->owner) {
07890                   /* Switch us to use a compatible format */
07891                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07892                   if (option_verbose > 2)
07893                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07894 retryowner2:
07895                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07896                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07897                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07898                   }
07899                   
07900                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07901                      /* Setup read/write formats properly. */
07902                      if (iaxs[fr->callno]->owner->writeformat)
07903                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07904                      if (iaxs[fr->callno]->owner->readformat)
07905                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07906                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07907                   }
07908                }
07909             }
07910             if (iaxs[fr->callno]) {
07911                ast_mutex_lock(&dpcache_lock);
07912                dp = iaxs[fr->callno]->dpentries;
07913                while(dp) {
07914                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07915                      iax2_dprequest(dp, fr->callno);
07916                   }
07917                   dp = dp->peer;
07918                }
07919                ast_mutex_unlock(&dpcache_lock);
07920             }
07921             break;
07922          case IAX_COMMAND_POKE:
07923             /* Send back a pong packet with the original timestamp */
07924             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07925             if (!iaxs[fr->callno]) {
07926                ast_mutex_unlock(&iaxsl[fr->callno]);
07927                return 1;
07928             }
07929             break;
07930          case IAX_COMMAND_PING:
07931          {
07932             struct iax_ie_data pingied;
07933             construct_rr(iaxs[fr->callno], &pingied);
07934             /* Send back a pong packet with the original timestamp */
07935             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07936          }
07937             break;
07938          case IAX_COMMAND_PONG:
07939             /* Calculate ping time */
07940             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07941             /* save RR info */
07942             save_rr(fr, &ies);
07943 
07944             if (iaxs[fr->callno]->peerpoke) {
07945                peer = iaxs[fr->callno]->peerpoke;
07946                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07947                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07948                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07949                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07950                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07951                   }
07952                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07953                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07954                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07955                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07956                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07957                   }
07958                }
07959                peer->lastms = iaxs[fr->callno]->pingtime;
07960                if (peer->smoothing && (peer->lastms > -1))
07961                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07962                else if (peer->smoothing && peer->lastms < 0)
07963                   peer->historicms = (0 + peer->historicms) / 2;
07964                else              
07965                   peer->historicms = iaxs[fr->callno]->pingtime;
07966 
07967                /* Remove scheduled iax2_poke_noanswer */
07968                if (peer->pokeexpire > -1) {
07969                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07970                      peer_unref(peer);
07971                      peer->pokeexpire = -1;
07972                   }
07973                }
07974                /* Schedule the next cycle */
07975                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07976                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07977                else
07978                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07979                if (peer->pokeexpire == -1)
07980                   peer_unref(peer);
07981                /* and finally send the ack */
07982                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07983                /* And wrap up the qualify call */
07984                iax2_destroy(fr->callno);
07985                peer->callno = 0;
07986                if (option_debug)
07987                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07988             }
07989             break;
07990          case IAX_COMMAND_LAGRQ:
07991          case IAX_COMMAND_LAGRP:
07992             f.src = "LAGRQ";
07993             f.mallocd = 0;
07994             f.offset = 0;
07995             f.samples = 0;
07996             iax_frame_wrap(fr, &f);
07997             if(f.subclass == IAX_COMMAND_LAGRQ) {
07998                /* Received a LAGRQ - echo back a LAGRP */
07999                fr->af.subclass = IAX_COMMAND_LAGRP;
08000                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08001             } else {
08002                /* Received LAGRP in response to our LAGRQ */
08003                unsigned int ts;
08004                /* This is a reply we've been given, actually measure the difference */
08005                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08006                iaxs[fr->callno]->lag = ts - fr->ts;
08007                if (option_debug && iaxdebug)
08008                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08009                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08010             }
08011             break;
08012          case IAX_COMMAND_AUTHREQ:
08013             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08014                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>");
08015                break;
08016             }
08017             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08018                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08019                         .subclass = AST_CONTROL_HANGUP,
08020                };
08021                ast_log(LOG_WARNING, 
08022                   "I don't know how to authenticate %s to %s\n", 
08023                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08024                iax2_queue_frame(fr->callno, &hangup_fr);
08025             }
08026             if (!iaxs[fr->callno]) {
08027                ast_mutex_unlock(&iaxsl[fr->callno]);
08028                return 1;
08029             }
08030             break;
08031          case IAX_COMMAND_AUTHREP:
08032             /* For security, always ack immediately */
08033             if (delayreject)
08034                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08035             /* Ignore once we've started */
08036             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08037                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>");
08038                break;
08039             }
08040             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08041                if (authdebug)
08042                   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);
08043                memset(&ied0, 0, sizeof(ied0));
08044                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08045                break;
08046             }
08047             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08048                /* This might re-enter the IAX code and need the lock */
08049                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08050             } else
08051                exists = 0;
08052             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08053                if (authdebug)
08054                   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);
08055                memset(&ied0, 0, sizeof(ied0));
08056                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08057                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08058                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08059                if (!iaxs[fr->callno]) {
08060                   ast_mutex_unlock(&iaxsl[fr->callno]);
08061                   return 1;
08062                }
08063             } else {
08064                /* Select an appropriate format */
08065                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08066                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08067                      using_prefs = "reqonly";
08068                   } else {
08069                      using_prefs = "disabled";
08070                   }
08071                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08072                   memset(&pref, 0, sizeof(pref));
08073                   strcpy(caller_pref_buf, "disabled");
08074                   strcpy(host_pref_buf, "disabled");
08075                } else {
08076                   using_prefs = "mine";
08077                   if (ies.codec_prefs)
08078                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08079                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08080                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08081                         pref = iaxs[fr->callno]->rprefs;
08082                         using_prefs = "caller";
08083                      } else {
08084                         pref = iaxs[fr->callno]->prefs;
08085                      }
08086                   } else /* if no codec_prefs IE do it the old way */
08087                      pref = iaxs[fr->callno]->prefs;
08088                
08089                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08090                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08091                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08092                }
08093                if (!format) {
08094                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08095                      if (option_debug)
08096                         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);
08097                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08098                   }
08099                   if (!format) {
08100                      if (authdebug) {
08101                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08102                            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);
08103                         else
08104                            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);
08105                      }
08106                      memset(&ied0, 0, sizeof(ied0));
08107                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08108                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08109                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08110                      if (!iaxs[fr->callno]) {
08111                         ast_mutex_unlock(&iaxsl[fr->callno]);
08112                         return 1;
08113                      }
08114                   } else {
08115                      /* Pick one... */
08116                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08117                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08118                            format = 0;
08119                      } else {
08120                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08121                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08122                            memset(&pref, 0, sizeof(pref));
08123                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08124                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08125                            strcpy(caller_pref_buf,"disabled");
08126                            strcpy(host_pref_buf,"disabled");
08127                         } else {
08128                            using_prefs = "mine";
08129                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08130                               /* Do the opposite of what we tried above. */
08131                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08132                                  pref = iaxs[fr->callno]->prefs;                 
08133                               } else {
08134                                  pref = iaxs[fr->callno]->rprefs;
08135                                  using_prefs = "caller";
08136                               }
08137                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08138                            } else /* if no codec_prefs IE do it the old way */
08139                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08140                         }
08141                      }
08142                      if (!format) {
08143                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08144                         if (authdebug) {
08145                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08146                               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);
08147                            else
08148                               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);
08149                         }
08150                         memset(&ied0, 0, sizeof(ied0));
08151                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08152                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08153                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08154                         if (!iaxs[fr->callno]) {
08155                            ast_mutex_unlock(&iaxsl[fr->callno]);
08156                            return 1;
08157                         }
08158                      }
08159                   }
08160                }
08161                if (format) {
08162                   /* Authentication received */
08163                   memset(&ied1, 0, sizeof(ied1));
08164                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08165                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08166                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08167                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08168                      if (option_verbose > 2) 
08169                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08170                                  "%srequested format = %s,\n"
08171                                  "%srequested prefs = %s,\n"
08172                                  "%sactual format = %s,\n"
08173                                  "%shost prefs = %s,\n"
08174                                  "%spriority = %s\n", 
08175                                  ast_inet_ntoa(sin.sin_addr), 
08176                                  VERBOSE_PREFIX_4,
08177                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08178                                  VERBOSE_PREFIX_4,
08179                                  caller_pref_buf,
08180                                  VERBOSE_PREFIX_4,
08181                                  ast_getformatname(format),
08182                                  VERBOSE_PREFIX_4,
08183                                  host_pref_buf,
08184                                  VERBOSE_PREFIX_4,
08185                                  using_prefs);
08186 
08187                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08188                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08189                         iax2_destroy(fr->callno);
08190                   } else {
08191                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08192                      /* If this is a TBD call, we're ready but now what...  */
08193                      if (option_verbose > 2)
08194                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08195                   }
08196                }
08197             }
08198             break;
08199          case IAX_COMMAND_DIAL:
08200             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08201                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08202                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08203                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08204                   if (authdebug)
08205                      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);
08206                   memset(&ied0, 0, sizeof(ied0));
08207                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08208                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08209                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08210                   if (!iaxs[fr->callno]) {
08211                      ast_mutex_unlock(&iaxsl[fr->callno]);
08212                      return 1;
08213                   }
08214                } else {
08215                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08216                   if (option_verbose > 2) 
08217                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08218                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08219                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08220                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08221                      iax2_destroy(fr->callno);
08222                }
08223             }
08224             break;
08225          case IAX_COMMAND_INVAL:
08226             iaxs[fr->callno]->error = ENOTCONN;
08227             if (option_debug)
08228                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08229             iax2_destroy(fr->callno);
08230             if (option_debug)
08231                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08232             break;
08233          case IAX_COMMAND_VNAK:
08234             if (option_debug)
08235                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08236             /* Force retransmission */
08237             vnak_retransmit(fr->callno, fr->iseqno);
08238             break;
08239          case IAX_COMMAND_REGREQ:
08240          case IAX_COMMAND_REGREL:
08241             /* For security, always ack immediately */
08242             if (delayreject)
08243                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08244             if (register_verify(fr->callno, &sin, &ies)) {
08245                if (!iaxs[fr->callno]) {
08246                   ast_mutex_unlock(&iaxsl[fr->callno]);
08247                   return 1;
08248                }
08249                /* Send delayed failure */
08250                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08251                break;
08252             }
08253             if (!iaxs[fr->callno]) {
08254                ast_mutex_unlock(&iaxsl[fr->callno]);
08255                return 1;
08256             }
08257             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08258                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08259                if (f.subclass == IAX_COMMAND_REGREL)
08260                   memset(&sin, 0, sizeof(sin));
08261                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08262                   ast_log(LOG_WARNING, "Registry error\n");
08263                if (!iaxs[fr->callno]) {
08264                   ast_mutex_unlock(&iaxsl[fr->callno]);
08265                   return 1;
08266                }
08267                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08268                   ast_mutex_unlock(&iaxsl[fr->callno]);
08269                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08270                   ast_mutex_lock(&iaxsl[fr->callno]);
08271                   if (!iaxs[fr->callno]) {
08272                      ast_mutex_unlock(&iaxsl[fr->callno]);
08273                      return 1;
08274                   }
08275                }
08276                break;
08277             }
08278             registry_authrequest(fr->callno);
08279             if (!iaxs[fr->callno]) {
08280                ast_mutex_unlock(&iaxsl[fr->callno]);
08281                return 1;
08282             }
08283             break;
08284          case IAX_COMMAND_REGACK:
08285             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08286                ast_log(LOG_WARNING, "Registration failure\n");
08287             /* Send ack immediately, before we destroy */
08288             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08289             iax2_destroy(fr->callno);
08290             break;
08291          case IAX_COMMAND_REGREJ:
08292             if (iaxs[fr->callno]->reg) {
08293                if (authdebug) {
08294                   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));
08295                   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>");
08296                }
08297                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08298             }
08299             /* Send ack immediately, before we destroy */
08300             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08301             iax2_destroy(fr->callno);
08302             break;
08303          case IAX_COMMAND_REGAUTH:
08304             /* Authentication request */
08305             if (registry_rerequest(&ies, fr->callno, &sin)) {
08306                memset(&ied0, 0, sizeof(ied0));
08307                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08308                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08309                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08310                if (!iaxs[fr->callno]) {
08311                   ast_mutex_unlock(&iaxsl[fr->callno]);
08312                   return 1;
08313                }
08314             }
08315             break;
08316          case IAX_COMMAND_TXREJ:
08317             iaxs[fr->callno]->transferring = 0;
08318             if (option_verbose > 2) 
08319                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08320             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08321             if (iaxs[fr->callno]->bridgecallno) {
08322                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08323                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08324                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08325                }
08326             }
08327             break;
08328          case IAX_COMMAND_TXREADY:
08329             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08330                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08331                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08332                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08333                else
08334                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08335                if (option_verbose > 2) 
08336                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08337                if (iaxs[fr->callno]->bridgecallno) {
08338                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08339                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08340                      /* They're both ready, now release them. */
08341                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08342                         if (option_verbose > 2) 
08343                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08344                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08345 
08346                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08347                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08348 
08349                         memset(&ied0, 0, sizeof(ied0));
08350                         memset(&ied1, 0, sizeof(ied1));
08351                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08352                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08353                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08354                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08355                      } else {
08356                         if (option_verbose > 2) 
08357                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08358                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08359 
08360                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08361                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08362                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08363                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08364 
08365                         /* Stop doing lag & ping requests */
08366                         stop_stuff(fr->callno);
08367                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08368 
08369                         memset(&ied0, 0, sizeof(ied0));
08370                         memset(&ied1, 0, sizeof(ied1));
08371                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08372                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08373                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08374                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08375                      }
08376 
08377                   }
08378                }
08379             }
08380             break;
08381          case IAX_COMMAND_TXREQ:
08382             try_transfer(iaxs[fr->callno], &ies);
08383             break;
08384          case IAX_COMMAND_TXCNT:
08385             if (iaxs[fr->callno]->transferring)
08386                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08387             break;
08388          case IAX_COMMAND_TXREL:
08389             /* Send ack immediately, rather than waiting until we've changed addresses */
08390             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08391             complete_transfer(fr->callno, &ies);
08392             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08393             break;   
08394          case IAX_COMMAND_TXMEDIA:
08395             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08396                                         AST_LIST_LOCK(&iaxq.queue);
08397                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08398                                                 /* Cancel any outstanding frames and start anew */
08399                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08400                                                         cur->retries = -1;
08401                                                 }
08402                                         }
08403                                         AST_LIST_UNLOCK(&iaxq.queue);
08404                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08405                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08406             }
08407             break;   
08408          case IAX_COMMAND_DPREP:
08409             complete_dpreply(iaxs[fr->callno], &ies);
08410             break;
08411          case IAX_COMMAND_UNSUPPORT:
08412             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08413             break;
08414          case IAX_COMMAND_FWDOWNL:
08415             /* Firmware download */
08416             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08417                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08418                break;
08419             }
08420             memset(&ied0, 0, sizeof(ied0));
08421             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08422             if (res < 0)
08423                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08424             else if (res > 0)
08425                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08426             else
08427                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08428             if (!iaxs[fr->callno]) {
08429                ast_mutex_unlock(&iaxsl[fr->callno]);
08430                return 1;
08431             }
08432             break;
08433          default:
08434             if (option_debug)
08435                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08436             memset(&ied0, 0, sizeof(ied0));
08437             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08438             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08439          }
08440          /* Don't actually pass these frames along */
08441          if ((f.subclass != IAX_COMMAND_ACK) && 
08442            (f.subclass != IAX_COMMAND_TXCNT) && 
08443            (f.subclass != IAX_COMMAND_TXACC) && 
08444            (f.subclass != IAX_COMMAND_INVAL) &&
08445            (f.subclass != IAX_COMMAND_VNAK)) { 
08446             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08447                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08448          }
08449          ast_mutex_unlock(&iaxsl[fr->callno]);
08450          return 1;
08451       }
08452       /* Unless this is an ACK or INVAL frame, ack it */
08453       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08454          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08455    } else if (minivid) {
08456       f.frametype = AST_FRAME_VIDEO;
08457       if (iaxs[fr->callno]->videoformat > 0) 
08458          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08459       else {
08460          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08461          iax2_vnak(fr->callno);
08462          ast_mutex_unlock(&iaxsl[fr->callno]);
08463          return 1;
08464       }
08465       f.datalen = res - sizeof(*vh);
08466       if (f.datalen)
08467          f.data = thread->buf + sizeof(*vh);
08468       else
08469          f.data = NULL;
08470 #ifdef IAXTESTS
08471       if (test_resync) {
08472          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08473       } else
08474 #endif /* IAXTESTS */
08475          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08476    } else {
08477       /* A mini frame */
08478       f.frametype = AST_FRAME_VOICE;
08479       if (iaxs[fr->callno]->voiceformat > 0)
08480          f.subclass = iaxs[fr->callno]->voiceformat;
08481       else {
08482          if (option_debug)
08483             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08484          iax2_vnak(fr->callno);
08485          ast_mutex_unlock(&iaxsl[fr->callno]);
08486          return 1;
08487       }
08488       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08489       if (f.datalen < 0) {
08490          ast_log(LOG_WARNING, "Datalen < 0?\n");
08491          ast_mutex_unlock(&iaxsl[fr->callno]);
08492          return 1;
08493       }
08494       if (f.datalen)
08495          f.data = thread->buf + sizeof(*mh);
08496       else
08497          f.data = NULL;
08498 #ifdef IAXTESTS
08499       if (test_resync) {
08500          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08501       } else
08502 #endif /* IAXTESTS */
08503       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08504       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08505    }
08506    /* Don't pass any packets until we're started */
08507    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08508       ast_mutex_unlock(&iaxsl[fr->callno]);
08509       return 1;
08510    }
08511    /* Common things */
08512    f.src = "IAX2";
08513    f.mallocd = 0;
08514    f.offset = 0;
08515    f.len = 0;
08516    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08517       f.samples = ast_codec_get_samples(&f);
08518       /* We need to byteswap incoming slinear samples from network byte order */
08519       if (f.subclass == AST_FORMAT_SLINEAR)
08520          ast_frame_byteswap_be(&f);
08521    } else
08522       f.samples = 0;
08523    iax_frame_wrap(fr, &f);
08524 
08525    /* If this is our most recent packet, use it as our basis for timestamping */
08526    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08527       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08528       fr->outoforder = 0;
08529    } else {
08530       if (option_debug && iaxdebug && iaxs[fr->callno])
08531          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);
08532       fr->outoforder = -1;
08533    }
08534    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08535    duped_fr = iaxfrdup2(fr);
08536    if (duped_fr) {
08537       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08538    }
08539    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08540       iaxs[fr->callno]->last = fr->ts;
08541 #if 1
08542       if (option_debug && iaxdebug)
08543          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08544 #endif
08545    }
08546 
08547    /* Always run again */
08548    ast_mutex_unlock(&iaxsl[fr->callno]);
08549    return 1;
08550 }
08551 
08552 /* Function to clean up process thread if it is cancelled */
08553 static void iax2_process_thread_cleanup(void *data)
08554 {
08555    struct iax2_thread *thread = data;
08556    ast_mutex_destroy(&thread->lock);
08557    ast_cond_destroy(&thread->cond);
08558    free(thread);
08559    ast_atomic_dec_and_test(&iaxactivethreadcount);
08560 }
08561 
08562 static void *iax2_process_thread(void *data)
08563 {
08564    struct iax2_thread *thread = data;
08565    struct timeval tv;
08566    struct timespec ts;
08567    int put_into_idle = 0;
08568 
08569    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08570    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08571    for(;;) {
08572       /* Wait for something to signal us to be awake */
08573       ast_mutex_lock(&thread->lock);
08574 
08575       /* Flag that we're ready to accept signals */
08576       thread->ready_for_signal = 1;
08577       
08578       /* Put into idle list if applicable */
08579       if (put_into_idle)
08580          insert_idle_thread(thread);
08581 
08582       if (thread->type == IAX_TYPE_DYNAMIC) {
08583          struct iax2_thread *t = NULL;
08584          /* Wait to be signalled or time out */
08585          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08586          ts.tv_sec = tv.tv_sec;
08587          ts.tv_nsec = tv.tv_usec * 1000;
08588          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08589             /* This thread was never put back into the available dynamic
08590              * thread list, so just go away. */
08591             if (!put_into_idle) {
08592                ast_mutex_unlock(&thread->lock);
08593                break;
08594             }
08595             AST_LIST_LOCK(&dynamic_list);
08596             /* Account for the case where this thread is acquired *right* after a timeout */
08597             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08598                iaxdynamicthreadcount--;
08599             AST_LIST_UNLOCK(&dynamic_list);
08600             if (t) {
08601                /* This dynamic thread timed out waiting for a task and was
08602                 * not acquired immediately after the timeout, 
08603                 * so it's time to go away. */
08604                ast_mutex_unlock(&thread->lock);
08605                break;
08606             }
08607             /* Someone grabbed our thread *right* after we timed out.
08608              * Wait for them to set us up with something to do and signal
08609              * us to continue. */
08610             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08611             ts.tv_sec = tv.tv_sec;
08612             ts.tv_nsec = tv.tv_usec * 1000;
08613             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08614             {
08615                ast_mutex_unlock(&thread->lock);
08616                break;
08617             }
08618          }
08619       } else {
08620          ast_cond_wait(&thread->cond, &thread->lock);
08621       }
08622 
08623       /* Go back into our respective list */
08624       put_into_idle = 1;
08625 
08626       ast_mutex_unlock(&thread->lock);
08627 
08628       if (thread->iostate == IAX_IOSTATE_IDLE)
08629          continue;
08630 
08631       /* Add ourselves to the active list now */
08632       AST_LIST_LOCK(&active_list);
08633       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08634       AST_LIST_UNLOCK(&active_list);
08635 
08636       /* See what we need to do */
08637       switch(thread->iostate) {
08638       case IAX_IOSTATE_READY:
08639          thread->actions++;
08640          thread->iostate = IAX_IOSTATE_PROCESSING;
08641          socket_process(thread);
08642          handle_deferred_full_frames(thread);
08643          break;
08644       case IAX_IOSTATE_SCHEDREADY:
08645          thread->actions++;
08646          thread->iostate = IAX_IOSTATE_PROCESSING;
08647 #ifdef SCHED_MULTITHREADED
08648          thread->schedfunc(thread->scheddata);
08649 #endif      
08650          break;
08651       }
08652       time(&thread->checktime);
08653       thread->iostate = IAX_IOSTATE_IDLE;
08654 #ifdef DEBUG_SCHED_MULTITHREAD
08655       thread->curfunc[0]='\0';
08656 #endif      
08657 
08658       /* Now... remove ourselves from the active list, and return to the idle list */
08659       AST_LIST_LOCK(&active_list);
08660       AST_LIST_REMOVE(&active_list, thread, list);
08661       AST_LIST_UNLOCK(&active_list);
08662 
08663       /* Make sure another frame didn't sneak in there after we thought we were done. */
08664       handle_deferred_full_frames(thread);
08665    }
08666 
08667    /*!\note For some reason, idle threads are exiting without being removed
08668     * from an idle list, which is causing memory corruption.  Forcibly remove
08669     * it from the list, if it's there.
08670     */
08671    AST_LIST_LOCK(&idle_list);
08672    AST_LIST_REMOVE(&idle_list, thread, list);
08673    AST_LIST_UNLOCK(&idle_list);
08674 
08675    AST_LIST_LOCK(&dynamic_list);
08676    AST_LIST_REMOVE(&dynamic_list, thread, list);
08677    AST_LIST_UNLOCK(&dynamic_list);
08678 
08679    /* I am exiting here on my own volition, I need to clean up my own data structures
08680    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08681    */
08682    pthread_cleanup_pop(1);
08683 
08684    return NULL;
08685 }
08686 
08687 static int iax2_do_register(struct iax2_registry *reg)
08688 {
08689    struct iax_ie_data ied;
08690    if (option_debug && iaxdebug)
08691       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08692 
08693    if (reg->dnsmgr && 
08694        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08695       /* Maybe the IP has changed, force DNS refresh */
08696       ast_dnsmgr_refresh(reg->dnsmgr);
08697    }
08698    
08699    /*
08700     * if IP has Changed, free allocated call to create a new one with new IP
08701     * call has the pointer to IP and must be updated to the new one
08702     */
08703    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08704       ast_mutex_lock(&iaxsl[reg->callno]);
08705       iax2_destroy(reg->callno);
08706       ast_mutex_unlock(&iaxsl[reg->callno]);
08707       reg->callno = 0;
08708    }
08709    if (!reg->addr.sin_addr.s_addr) {
08710       if (option_debug && iaxdebug)
08711          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08712       /* Setup the next registration attempt */
08713       AST_SCHED_DEL(sched, reg->expire);
08714       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08715       return -1;
08716    }
08717 
08718    if (!reg->callno) {
08719       if (option_debug)
08720          ast_log(LOG_DEBUG, "Allocate call number\n");
08721       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08722       if (reg->callno < 1) {
08723          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08724          return -1;
08725       } else if (option_debug)
08726          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08727       iaxs[reg->callno]->reg = reg;
08728       ast_mutex_unlock(&iaxsl[reg->callno]);
08729    }
08730    /* Schedule the next registration attempt */
08731    AST_SCHED_DEL(sched, reg->expire);
08732    /* Setup the next registration a little early */
08733    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08734    /* Send the request */
08735    memset(&ied, 0, sizeof(ied));
08736    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08737    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08738    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08739    reg->regstate = REG_STATE_REGSENT;
08740    return 0;
08741 }
08742 
08743 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08744 {
08745    if (pos != 3)
08746       return NULL;
08747    return iax_prov_complete_template(line, word, pos, state);
08748 }
08749 
08750 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08751 {
08752    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08753       is found for template */
08754    struct iax_ie_data provdata;
08755    struct iax_ie_data ied;
08756    unsigned int sig;
08757    struct sockaddr_in sin;
08758    int callno;
08759    struct create_addr_info cai;
08760 
08761    memset(&cai, 0, sizeof(cai));
08762 
08763    if (option_debug)
08764       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08765 
08766    if (iax_provision_build(&provdata, &sig, template, force)) {
08767       if (option_debug)
08768          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08769       return 0;
08770    }
08771 
08772    if (end) {
08773       memcpy(&sin, end, sizeof(sin));
08774       cai.sockfd = sockfd;
08775    } else if (create_addr(dest, NULL, &sin, &cai))
08776       return -1;
08777 
08778    /* Build the rest of the message */
08779    memset(&ied, 0, sizeof(ied));
08780    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08781 
08782    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08783    if (!callno)
08784       return -1;
08785 
08786    if (iaxs[callno]) {
08787       /* Schedule autodestruct in case they don't ever give us anything back */
08788       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08789       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08790       ast_set_flag(iaxs[callno], IAX_PROVISION);
08791       /* Got a call number now, so go ahead and send the provisioning information */
08792       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08793    }
08794    ast_mutex_unlock(&iaxsl[callno]);
08795 
08796    return 1;
08797 }
08798 
08799 static char *papp = "IAX2Provision";
08800 static char *psyn = "Provision a calling IAXy with a given template";
08801 static char *pdescrip = 
08802 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08803 "the calling entity is in fact an IAXy) with the given template or\n"
08804 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08805 
08806 /*! iax2provision
08807 \ingroup applications
08808 */
08809 static int iax2_prov_app(struct ast_channel *chan, void *data)
08810 {
08811    int res;
08812    char *sdata;
08813    char *opts;
08814    int force =0;
08815    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08816    if (ast_strlen_zero(data))
08817       data = "default";
08818    sdata = ast_strdupa(data);
08819    opts = strchr(sdata, '|');
08820    if (opts)
08821       *opts='\0';
08822 
08823    if (chan->tech != &iax2_tech) {
08824       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08825       return -1;
08826    } 
08827    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08828       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08829       return -1;
08830    }
08831    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08832    if (option_verbose > 2)
08833       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08834       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08835       sdata, res);
08836    return res;
08837 }
08838 
08839 
08840 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08841 {
08842    int force = 0;
08843    int res;
08844    if (argc < 4)
08845       return RESULT_SHOWUSAGE;
08846    if ((argc > 4)) {
08847       if (!strcasecmp(argv[4], "forced"))
08848          force = 1;
08849       else
08850          return RESULT_SHOWUSAGE;
08851    }
08852    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08853    if (res < 0)
08854       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08855    else if (res < 1)
08856       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08857    else
08858       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08859    return RESULT_SUCCESS;
08860 }
08861 
08862 static void __iax2_poke_noanswer(const void *data)
08863 {
08864    struct iax2_peer *peer = (struct iax2_peer *)data;
08865    int callno;
08866 
08867    if (peer->lastms > -1) {
08868       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08869       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08870       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08871    }
08872    if ((callno = peer->callno) > 0) {
08873       ast_mutex_lock(&iaxsl[callno]);
08874       iax2_destroy(callno);
08875       ast_mutex_unlock(&iaxsl[callno]);
08876    }
08877    peer->callno = 0;
08878    peer->lastms = -1;
08879    /* Try again quickly */
08880    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08881    if (peer->pokeexpire == -1)
08882       peer_unref(peer);
08883 }
08884 
08885 static int iax2_poke_noanswer(const void *data)
08886 {
08887    struct iax2_peer *peer = (struct iax2_peer *)data;
08888    peer->pokeexpire = -1;
08889 #ifdef SCHED_MULTITHREADED
08890    if (schedule_action(__iax2_poke_noanswer, data))
08891 #endif      
08892       __iax2_poke_noanswer(data);
08893    peer_unref(peer);
08894    return 0;
08895 }
08896 
08897 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08898 {
08899    struct iax2_peer *peer = obj;
08900 
08901    iax2_poke_peer(peer, 0);
08902 
08903    return 0;
08904 }
08905 
08906 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08907 {
08908    int callno;
08909    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08910       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08911         immediately after clearing things out */
08912       peer->lastms = 0;
08913       peer->historicms = 0;
08914       peer->pokeexpire = -1;
08915       peer->callno = 0;
08916       return 0;
08917    }
08918 
08919    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
08920    if ((callno = peer->callno) > 0) {
08921       ast_log(LOG_NOTICE, "Still have a callno...\n");
08922       ast_mutex_lock(&iaxsl[callno]);
08923       iax2_destroy(callno);
08924       ast_mutex_unlock(&iaxsl[callno]);
08925    }
08926    if (heldcall)
08927       ast_mutex_unlock(&iaxsl[heldcall]);
08928    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08929    if (heldcall)
08930       ast_mutex_lock(&iaxsl[heldcall]);
08931    if (peer->callno < 1) {
08932       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08933       return -1;
08934    }
08935 
08936    /* Speed up retransmission times for this qualify call */
08937    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08938    iaxs[peer->callno]->peerpoke = peer;
08939    
08940    /* Remove any pending pokeexpire task */
08941    if (peer->pokeexpire > -1) {
08942       if (!ast_sched_del(sched, peer->pokeexpire)) {
08943          peer->pokeexpire = -1;
08944          peer_unref(peer);
08945       }
08946    }
08947 
08948    /* Queue up a new task to handle no reply */
08949    /* If the host is already unreachable then use the unreachable interval instead */
08950    if (peer->lastms < 0) {
08951       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08952    } else
08953       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08954 
08955    if (peer->pokeexpire == -1)
08956       peer_unref(peer);
08957 
08958    /* And send the poke */
08959    ast_mutex_lock(&iaxsl[callno]);
08960    if (iaxs[callno]) {
08961       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08962    }
08963    ast_mutex_unlock(&iaxsl[callno]);
08964 
08965    return 0;
08966 }
08967 
08968 static void free_context(struct iax2_context *con)
08969 {
08970    struct iax2_context *conl;
08971    while(con) {
08972       conl = con;
08973       con = con->next;
08974       free(conl);
08975    }
08976 }
08977 
08978 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08979 {
08980    int callno;
08981    int res;
08982    int fmt, native;
08983    struct sockaddr_in sin;
08984    struct ast_channel *c;
08985    struct parsed_dial_string pds;
08986    struct create_addr_info cai;
08987    char *tmpstr;
08988 
08989    memset(&pds, 0, sizeof(pds));
08990    tmpstr = ast_strdupa(data);
08991    parse_dial_string(tmpstr, &pds);
08992 
08993    if (ast_strlen_zero(pds.peer)) {
08994       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
08995       return NULL;
08996    }
08997           
08998    memset(&cai, 0, sizeof(cai));
08999    cai.capability = iax2_capability;
09000 
09001    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09002    
09003    /* Populate our address from the given */
09004    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09005       *cause = AST_CAUSE_UNREGISTERED;
09006       return NULL;
09007    }
09008 
09009    if (pds.port)
09010       sin.sin_port = htons(atoi(pds.port));
09011 
09012    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09013    if (callno < 1) {
09014       ast_log(LOG_WARNING, "Unable to create call\n");
09015       *cause = AST_CAUSE_CONGESTION;
09016       return NULL;
09017    }
09018 
09019    /* If this is a trunk, update it now */
09020    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09021    if (ast_test_flag(&cai, IAX_TRUNK)) {
09022       int new_callno;
09023       if ((new_callno = make_trunk(callno, 1)) != -1)
09024          callno = new_callno;
09025    }
09026    iaxs[callno]->maxtime = cai.maxtime;
09027    if (cai.found)
09028       ast_string_field_set(iaxs[callno], host, pds.peer);
09029 
09030    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09031 
09032    ast_mutex_unlock(&iaxsl[callno]);
09033 
09034    if (c) {
09035       /* Choose a format we can live with */
09036       if (c->nativeformats & format) 
09037          c->nativeformats &= format;
09038       else {
09039          native = c->nativeformats;
09040          fmt = format;
09041          res = ast_translator_best_choice(&fmt, &native);
09042          if (res < 0) {
09043             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09044                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09045             ast_hangup(c);
09046             return NULL;
09047          }
09048          c->nativeformats = native;
09049       }
09050       c->readformat = ast_best_codec(c->nativeformats);
09051       c->writeformat = c->readformat;
09052    }
09053 
09054    return c;
09055 }
09056 
09057 static void *sched_thread(void *ignore)
09058 {
09059    int count;
09060    int res;
09061    struct timeval tv;
09062    struct timespec ts;
09063 
09064    for (;;) {
09065       res = ast_sched_wait(sched);
09066       if ((res > 1000) || (res < 0))
09067          res = 1000;
09068       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09069       ts.tv_sec = tv.tv_sec;
09070       ts.tv_nsec = tv.tv_usec * 1000;
09071 
09072       pthread_testcancel();
09073       ast_mutex_lock(&sched_lock);
09074       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09075       ast_mutex_unlock(&sched_lock);
09076       pthread_testcancel();
09077 
09078       count = ast_sched_runq(sched);
09079       if (option_debug && count >= 20)
09080          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09081    }
09082    return NULL;
09083 }
09084 
09085 static void *network_thread(void *ignore)
09086 {
09087    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09088       from the network, and queue them for delivery to the channels */
09089    int res, count, wakeup;
09090    struct iax_frame *f;
09091 
09092    if (timingfd > -1)
09093       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09094    
09095    for(;;) {
09096       pthread_testcancel();
09097 
09098       /* Go through the queue, sending messages which have not yet been
09099          sent, and scheduling retransmissions if appropriate */
09100       AST_LIST_LOCK(&iaxq.queue);
09101       count = 0;
09102       wakeup = -1;
09103       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09104          if (f->sentyet)
09105             continue;
09106          
09107          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09108          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09109             wakeup = 1;
09110             continue;
09111          }
09112 
09113          f->sentyet++;
09114 
09115          if (iaxs[f->callno]) {
09116             send_packet(f);
09117             count++;
09118          } 
09119 
09120          ast_mutex_unlock(&iaxsl[f->callno]);
09121 
09122          if (f->retries < 0) {
09123             /* This is not supposed to be retransmitted */
09124             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09125             iaxq.count--;
09126             /* Free the iax frame */
09127             iax_frame_free(f);
09128          } else {
09129             /* We need reliable delivery.  Schedule a retransmission */
09130             f->retries++;
09131             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09132          }
09133       }
09134       AST_LIST_TRAVERSE_SAFE_END
09135       AST_LIST_UNLOCK(&iaxq.queue);
09136 
09137       pthread_testcancel();
09138 
09139       if (option_debug && count >= 20)
09140          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09141 
09142       /* Now do the IO, and run scheduled tasks */
09143       res = ast_io_wait(io, wakeup);
09144       if (res >= 0) {
09145          if (option_debug && res >= 20)
09146             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09147       }
09148    }
09149    return NULL;
09150 }
09151 
09152 static int start_network_thread(void)
09153 {
09154    pthread_attr_t attr;
09155    int threadcount = 0;
09156    int x;
09157    for (x = 0; x < iaxthreadcount; x++) {
09158       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09159       if (thread) {
09160          thread->type = IAX_TYPE_POOL;
09161          thread->threadnum = ++threadcount;
09162          ast_mutex_init(&thread->lock);
09163          ast_cond_init(&thread->cond, NULL);
09164          pthread_attr_init(&attr);
09165          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09166          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09167             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09168             free(thread);
09169             thread = NULL;
09170          }
09171          AST_LIST_LOCK(&idle_list);
09172          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09173          AST_LIST_UNLOCK(&idle_list);
09174       }
09175    }
09176    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09177    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09178    if (option_verbose > 1)
09179       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09180    return 0;
09181 }
09182 
09183 static struct iax2_context *build_context(char *context)
09184 {
09185    struct iax2_context *con;
09186 
09187    if ((con = ast_calloc(1, sizeof(*con))))
09188       ast_copy_string(con->context, context, sizeof(con->context));
09189    
09190    return con;
09191 }
09192 
09193 static int get_auth_methods(char *value)
09194 {
09195    int methods = 0;
09196    if (strstr(value, "rsa"))
09197       methods |= IAX_AUTH_RSA;
09198    if (strstr(value, "md5"))
09199       methods |= IAX_AUTH_MD5;
09200    if (strstr(value, "plaintext"))
09201       methods |= IAX_AUTH_PLAINTEXT;
09202    return methods;
09203 }
09204 
09205 
09206 /*! \brief Check if address can be used as packet source.
09207  \return 0  address available, 1  address unavailable, -1  error
09208 */
09209 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09210 {
09211    int sd;
09212    int res;
09213    
09214    sd = socket(AF_INET, SOCK_DGRAM, 0);
09215    if (sd < 0) {
09216       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09217       return -1;
09218    }
09219 
09220    res = bind(sd, sa, salen);
09221    if (res < 0) {
09222       if (option_debug)
09223          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09224       close(sd);
09225       return 1;
09226    }
09227 
09228    close(sd);
09229    return 0;
09230 }
09231 
09232 /*! \brief Parse the "sourceaddress" value,
09233   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09234   not found. */
09235 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09236 {
09237    struct sockaddr_in sin;
09238    int nonlocal = 1;
09239    int port = IAX_DEFAULT_PORTNO;
09240    int sockfd = defaultsockfd;
09241    char *tmp;
09242    char *addr;
09243    char *portstr;
09244 
09245    if (!(tmp = ast_strdupa(srcaddr)))
09246       return -1;
09247 
09248    addr = strsep(&tmp, ":");
09249    portstr = tmp;
09250 
09251    if (portstr) {
09252       port = atoi(portstr);
09253       if (port < 1)
09254          port = IAX_DEFAULT_PORTNO;
09255    }
09256    
09257    if (!ast_get_ip(&sin, addr)) {
09258       struct ast_netsock *sock;
09259       int res;
09260 
09261       sin.sin_port = 0;
09262       sin.sin_family = AF_INET;
09263       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09264       if (res == 0) {
09265          /* ip address valid. */
09266          sin.sin_port = htons(port);
09267          if (!(sock = ast_netsock_find(netsock, &sin)))
09268             sock = ast_netsock_find(outsock, &sin);
09269          if (sock) {
09270             sockfd = ast_netsock_sockfd(sock);
09271             nonlocal = 0;
09272          } else {
09273             unsigned int orig_saddr = sin.sin_addr.s_addr;
09274             /* INADDR_ANY matches anyway! */
09275             sin.sin_addr.s_addr = INADDR_ANY;
09276             if (ast_netsock_find(netsock, &sin)) {
09277                sin.sin_addr.s_addr = orig_saddr;
09278                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09279                if (sock) {
09280                   sockfd = ast_netsock_sockfd(sock);
09281                   ast_netsock_unref(sock);
09282                   nonlocal = 0;
09283                } else {
09284                   nonlocal = 2;
09285                }
09286             }
09287          }
09288       }
09289    }
09290       
09291    peer->sockfd = sockfd;
09292 
09293    if (nonlocal == 1) {
09294       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09295          srcaddr, peer->name);
09296       return -1;
09297         } else if (nonlocal == 2) {
09298       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09299          srcaddr, peer->name);
09300          return -1;
09301    } else {
09302       if (option_debug)
09303          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09304       return 0;
09305    }
09306 }
09307 
09308 static void peer_destructor(void *obj)
09309 {
09310    struct iax2_peer *peer = obj;
09311 
09312    ast_free_ha(peer->ha);
09313 
09314    if (peer->callno > 0) {
09315       ast_mutex_lock(&iaxsl[peer->callno]);
09316       iax2_destroy(peer->callno);
09317       ast_mutex_unlock(&iaxsl[peer->callno]);
09318    }
09319 
09320    register_peer_exten(peer, 0);
09321 
09322    if (peer->dnsmgr)
09323       ast_dnsmgr_release(peer->dnsmgr);
09324 
09325    ast_string_field_free_memory(peer);
09326 }
09327 
09328 /*! \brief Create peer structure based on configuration */
09329 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09330 {
09331    struct iax2_peer *peer = NULL;
09332    struct ast_ha *oldha = NULL;
09333    int maskfound=0;
09334    int found=0;
09335    int firstpass=1;
09336    struct iax2_peer tmp_peer = {
09337       .name = name,
09338    };
09339 
09340    if (!temponly) {
09341       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09342       if (peer && !ast_test_flag(peer, IAX_DELME))
09343          firstpass = 0;
09344    }
09345 
09346    if (peer) {
09347       found++;
09348       if (firstpass) {
09349          oldha = peer->ha;
09350          peer->ha = NULL;
09351       }
09352       unlink_peer(peer);
09353    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09354       peer->expire = -1;
09355       peer->pokeexpire = -1;
09356       peer->sockfd = defaultsockfd;
09357       if (ast_string_field_init(peer, 32))
09358          peer = peer_unref(peer);
09359    }
09360 
09361    if (peer) {
09362       if (firstpass) {
09363          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09364          peer->encmethods = iax2_encryption;
09365          peer->adsi = adsi;
09366          ast_string_field_set(peer,secret,"");
09367          if (!found) {
09368             ast_string_field_set(peer, name, name);
09369             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09370             peer->expiry = min_reg_expire;
09371          }
09372          peer->prefs = prefs;
09373          peer->capability = iax2_capability;
09374          peer->smoothing = 0;
09375          peer->pokefreqok = DEFAULT_FREQ_OK;
09376          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09377          ast_string_field_set(peer,context,"");
09378          ast_string_field_set(peer,peercontext,"");
09379          ast_clear_flag(peer, IAX_HASCALLERID);
09380          ast_string_field_set(peer, cid_name, "");
09381          ast_string_field_set(peer, cid_num, "");
09382       }
09383 
09384       if (!v) {
09385          v = alt;
09386          alt = NULL;
09387       }
09388       while(v) {
09389          if (!strcasecmp(v->name, "secret")) {
09390             ast_string_field_set(peer, secret, v->value);
09391          } else if (!strcasecmp(v->name, "mailbox")) {
09392             ast_string_field_set(peer, mailbox, v->value);
09393          } else if (!strcasecmp(v->name, "mohinterpret")) {
09394             ast_string_field_set(peer, mohinterpret, v->value);
09395          } else if (!strcasecmp(v->name, "mohsuggest")) {
09396             ast_string_field_set(peer, mohsuggest, v->value);
09397          } else if (!strcasecmp(v->name, "dbsecret")) {
09398             ast_string_field_set(peer, dbsecret, v->value);
09399          } else if (!strcasecmp(v->name, "trunk")) {
09400             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09401             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09402                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09403                ast_clear_flag(peer, IAX_TRUNK);
09404             }
09405          } else if (!strcasecmp(v->name, "auth")) {
09406             peer->authmethods = get_auth_methods(v->value);
09407          } else if (!strcasecmp(v->name, "encryption")) {
09408             peer->encmethods = get_encrypt_methods(v->value);
09409          } else if (!strcasecmp(v->name, "notransfer")) {
09410             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09411             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09412             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09413          } else if (!strcasecmp(v->name, "transfer")) {
09414             if (!strcasecmp(v->value, "mediaonly")) {
09415                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09416             } else if (ast_true(v->value)) {
09417                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09418             } else 
09419                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09420          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09421             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09422          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09423             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09424          } else if (!strcasecmp(v->name, "host")) {
09425             if (!strcasecmp(v->value, "dynamic")) {
09426                /* They'll register with us */
09427                ast_set_flag(peer, IAX_DYNAMIC); 
09428                if (!found) {
09429                   /* Initialize stuff iff we're not found, otherwise
09430                      we keep going with what we had */
09431                   memset(&peer->addr.sin_addr, 0, 4);
09432                   if (peer->addr.sin_port) {
09433                      /* If we've already got a port, make it the default rather than absolute */
09434                      peer->defaddr.sin_port = peer->addr.sin_port;
09435                      peer->addr.sin_port = 0;
09436                   }
09437                }
09438             } else {
09439                /* Non-dynamic.  Make sure we become that way if we're not */
09440                AST_SCHED_DEL(sched, peer->expire);
09441                ast_clear_flag(peer, IAX_DYNAMIC);
09442                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09443                   return peer_unref(peer);
09444                if (!peer->addr.sin_port)
09445                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09446             }
09447             if (!maskfound)
09448                inet_aton("255.255.255.255", &peer->mask);
09449          } else if (!strcasecmp(v->name, "defaultip")) {
09450             if (ast_get_ip(&peer->defaddr, v->value))
09451                return peer_unref(peer);
09452          } else if (!strcasecmp(v->name, "sourceaddress")) {
09453             peer_set_srcaddr(peer, v->value);
09454          } else if (!strcasecmp(v->name, "permit") ||
09455                   !strcasecmp(v->name, "deny")) {
09456             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09457          } else if (!strcasecmp(v->name, "mask")) {
09458             maskfound++;
09459             inet_aton(v->value, &peer->mask);
09460          } else if (!strcasecmp(v->name, "context")) {
09461             ast_string_field_set(peer, context, v->value);
09462          } else if (!strcasecmp(v->name, "regexten")) {
09463             ast_string_field_set(peer, regexten, v->value);
09464          } else if (!strcasecmp(v->name, "peercontext")) {
09465             ast_string_field_set(peer, peercontext, v->value);
09466          } else if (!strcasecmp(v->name, "port")) {
09467             if (ast_test_flag(peer, IAX_DYNAMIC))
09468                peer->defaddr.sin_port = htons(atoi(v->value));
09469             else
09470                peer->addr.sin_port = htons(atoi(v->value));
09471          } else if (!strcasecmp(v->name, "username")) {
09472             ast_string_field_set(peer, username, v->value);
09473          } else if (!strcasecmp(v->name, "allow")) {
09474             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09475          } else if (!strcasecmp(v->name, "disallow")) {
09476             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09477          } else if (!strcasecmp(v->name, "callerid")) {
09478             if (!ast_strlen_zero(v->value)) {
09479                char name2[80];
09480                char num2[80];
09481                ast_callerid_split(v->value, name2, 80, num2, 80);
09482                ast_string_field_set(peer, cid_name, name2);
09483                ast_string_field_set(peer, cid_num, num2);
09484                ast_set_flag(peer, IAX_HASCALLERID);
09485             } else {
09486                ast_clear_flag(peer, IAX_HASCALLERID);
09487                ast_string_field_set(peer, cid_name, "");
09488                ast_string_field_set(peer, cid_num, "");
09489             }
09490          } else if (!strcasecmp(v->name, "fullname")) {
09491             if (!ast_strlen_zero(v->value)) {
09492                ast_string_field_set(peer, cid_name, v->value);
09493                ast_set_flag(peer, IAX_HASCALLERID);
09494             } else {
09495                ast_string_field_set(peer, cid_name, "");
09496                if (ast_strlen_zero(peer->cid_num))
09497                   ast_clear_flag(peer, IAX_HASCALLERID);
09498             }
09499          } else if (!strcasecmp(v->name, "cid_number")) {
09500             if (!ast_strlen_zero(v->value)) {
09501                ast_string_field_set(peer, cid_num, v->value);
09502                ast_set_flag(peer, IAX_HASCALLERID);
09503             } else {
09504                ast_string_field_set(peer, cid_num, "");
09505                if (ast_strlen_zero(peer->cid_name))
09506                   ast_clear_flag(peer, IAX_HASCALLERID);
09507             }
09508          } else if (!strcasecmp(v->name, "sendani")) {
09509             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09510          } else if (!strcasecmp(v->name, "inkeys")) {
09511             ast_string_field_set(peer, inkeys, v->value);
09512          } else if (!strcasecmp(v->name, "outkey")) {
09513             ast_string_field_set(peer, outkey, v->value);
09514          } else if (!strcasecmp(v->name, "qualify")) {
09515             if (!strcasecmp(v->value, "no")) {
09516                peer->maxms = 0;
09517             } else if (!strcasecmp(v->value, "yes")) {
09518                peer->maxms = DEFAULT_MAXMS;
09519             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09520                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);
09521                peer->maxms = 0;
09522             }
09523          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09524             peer->smoothing = ast_true(v->value);
09525          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09526             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09527                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);
09528             }
09529          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09530             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09531                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);
09532             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09533          } else if (!strcasecmp(v->name, "timezone")) {
09534             ast_string_field_set(peer, zonetag, v->value);
09535          } else if (!strcasecmp(v->name, "adsi")) {
09536             peer->adsi = ast_true(v->value);
09537          }/* else if (strcasecmp(v->name,"type")) */
09538          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09539          v = v->next;
09540          if (!v) {
09541             v = alt;
09542             alt = NULL;
09543          }
09544       }
09545       if (!peer->authmethods)
09546          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09547       ast_clear_flag(peer, IAX_DELME); 
09548       /* Make sure these are IPv4 addresses */
09549       peer->addr.sin_family = AF_INET;
09550    }
09551    if (oldha)
09552       ast_free_ha(oldha);
09553    return peer;
09554 }
09555 
09556 static void user_destructor(void *obj)
09557 {
09558    struct iax2_user *user = obj;
09559 
09560    ast_free_ha(user->ha);
09561    free_context(user->contexts);
09562    if(user->vars) {
09563       ast_variables_destroy(user->vars);
09564       user->vars = NULL;
09565    }
09566    ast_string_field_free_memory(user);
09567 }
09568 
09569 /*! \brief Create in-memory user structure from configuration */
09570 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09571 {
09572    struct iax2_user *user = NULL;
09573    struct iax2_context *con, *conl = NULL;
09574    struct ast_ha *oldha = NULL;
09575    struct iax2_context *oldcon = NULL;
09576    int format;
09577    int firstpass=1;
09578    int oldcurauthreq = 0;
09579    char *varname = NULL, *varval = NULL;
09580    struct ast_variable *tmpvar = NULL;
09581    struct iax2_user tmp_user = {
09582       .name = name,
09583    };
09584 
09585    if (!temponly) {
09586       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09587       if (user && !ast_test_flag(user, IAX_DELME))
09588          firstpass = 0;
09589    }
09590 
09591    if (user) {
09592       if (firstpass) {
09593          oldcurauthreq = user->curauthreq;
09594          oldha = user->ha;
09595          oldcon = user->contexts;
09596          user->ha = NULL;
09597          user->contexts = NULL;
09598       }
09599       /* Already in the list, remove it and it will be added back (or FREE'd) */
09600       ao2_unlink(users, user);
09601    } else {
09602       user = ao2_alloc(sizeof(*user), user_destructor);
09603    }
09604    
09605    if (user) {
09606       if (firstpass) {
09607          ast_string_field_free_memory(user);
09608          memset(user, 0, sizeof(struct iax2_user));
09609          if (ast_string_field_init(user, 32)) {
09610             user = user_unref(user);
09611             goto cleanup;
09612          }
09613          user->maxauthreq = maxauthreq;
09614          user->curauthreq = oldcurauthreq;
09615          user->prefs = prefs;
09616          user->capability = iax2_capability;
09617          user->encmethods = iax2_encryption;
09618          user->adsi = adsi;
09619          ast_string_field_set(user, name, name);
09620          ast_string_field_set(user, language, language);
09621          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09622          ast_clear_flag(user, IAX_HASCALLERID);
09623          ast_string_field_set(user, cid_name, "");
09624          ast_string_field_set(user, cid_num, "");
09625       }
09626       if (!v) {
09627          v = alt;
09628          alt = NULL;
09629       }
09630       while(v) {
09631          if (!strcasecmp(v->name, "context")) {
09632             con = build_context(v->value);
09633             if (con) {
09634                if (conl)
09635                   conl->next = con;
09636                else
09637                   user->contexts = con;
09638                conl = con;
09639             }
09640          } else if (!strcasecmp(v->name, "permit") ||
09641                   !strcasecmp(v->name, "deny")) {
09642             user->ha = ast_append_ha(v->name, v->value, user->ha);
09643          } else if (!strcasecmp(v->name, "setvar")) {
09644             varname = ast_strdupa(v->value);
09645             if (varname && (varval = strchr(varname,'='))) {
09646                *varval = '\0';
09647                varval++;
09648                if((tmpvar = ast_variable_new(varname, varval))) {
09649                   tmpvar->next = user->vars; 
09650                   user->vars = tmpvar;
09651                }
09652             }
09653          } else if (!strcasecmp(v->name, "allow")) {
09654             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09655          } else if (!strcasecmp(v->name, "disallow")) {
09656             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09657          } else if (!strcasecmp(v->name, "trunk")) {
09658             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09659             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09660                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09661                ast_clear_flag(user, IAX_TRUNK);
09662             }
09663          } else if (!strcasecmp(v->name, "auth")) {
09664             user->authmethods = get_auth_methods(v->value);
09665          } else if (!strcasecmp(v->name, "encryption")) {
09666             user->encmethods = get_encrypt_methods(v->value);
09667          } else if (!strcasecmp(v->name, "notransfer")) {
09668             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09669             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09670             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09671          } else if (!strcasecmp(v->name, "transfer")) {
09672             if (!strcasecmp(v->value, "mediaonly")) {
09673                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09674             } else if (ast_true(v->value)) {
09675                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09676             } else 
09677                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09678          } else if (!strcasecmp(v->name, "codecpriority")) {
09679             if(!strcasecmp(v->value, "caller"))
09680                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09681             else if(!strcasecmp(v->value, "disabled"))
09682                ast_set_flag(user, IAX_CODEC_NOPREFS);
09683             else if(!strcasecmp(v->value, "reqonly")) {
09684                ast_set_flag(user, IAX_CODEC_NOCAP);
09685                ast_set_flag(user, IAX_CODEC_NOPREFS);
09686             }
09687          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09688             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09689          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09690             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09691          } else if (!strcasecmp(v->name, "dbsecret")) {
09692             ast_string_field_set(user, dbsecret, v->value);
09693          } else if (!strcasecmp(v->name, "secret")) {
09694             if (!ast_strlen_zero(user->secret)) {
09695                char *old = ast_strdupa(user->secret);
09696 
09697                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09698             } else
09699                ast_string_field_set(user, secret, v->value);
09700          } else if (!strcasecmp(v->name, "callerid")) {
09701             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09702                char name2[80];
09703                char num2[80];
09704                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09705                ast_string_field_set(user, cid_name, name2);
09706                ast_string_field_set(user, cid_num, num2);
09707                ast_set_flag(user, IAX_HASCALLERID);
09708             } else {
09709                ast_clear_flag(user, IAX_HASCALLERID);
09710                ast_string_field_set(user, cid_name, "");
09711                ast_string_field_set(user, cid_num, "");
09712             }
09713          } else if (!strcasecmp(v->name, "fullname")) {
09714             if (!ast_strlen_zero(v->value)) {
09715                ast_string_field_set(user, cid_name, v->value);
09716                ast_set_flag(user, IAX_HASCALLERID);
09717             } else {
09718                ast_string_field_set(user, cid_name, "");
09719                if (ast_strlen_zero(user->cid_num))
09720                   ast_clear_flag(user, IAX_HASCALLERID);
09721             }
09722          } else if (!strcasecmp(v->name, "cid_number")) {
09723             if (!ast_strlen_zero(v->value)) {
09724                ast_string_field_set(user, cid_num, v->value);
09725                ast_set_flag(user, IAX_HASCALLERID);
09726             } else {
09727                ast_string_field_set(user, cid_num, "");
09728                if (ast_strlen_zero(user->cid_name))
09729                   ast_clear_flag(user, IAX_HASCALLERID);
09730             }
09731          } else if (!strcasecmp(v->name, "accountcode")) {
09732             ast_string_field_set(user, accountcode, v->value);
09733          } else if (!strcasecmp(v->name, "mohinterpret")) {
09734             ast_string_field_set(user, mohinterpret, v->value);
09735          } else if (!strcasecmp(v->name, "mohsuggest")) {
09736             ast_string_field_set(user, mohsuggest, v->value);
09737          } else if (!strcasecmp(v->name, "language")) {
09738             ast_string_field_set(user, language, v->value);
09739          } else if (!strcasecmp(v->name, "amaflags")) {
09740             format = ast_cdr_amaflags2int(v->value);
09741             if (format < 0) {
09742                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09743             } else {
09744                user->amaflags = format;
09745             }
09746          } else if (!strcasecmp(v->name, "inkeys")) {
09747             ast_string_field_set(user, inkeys, v->value);
09748          } else if (!strcasecmp(v->name, "maxauthreq")) {
09749             user->maxauthreq = atoi(v->value);
09750             if (user->maxauthreq < 0)
09751                user->maxauthreq = 0;
09752          } else if (!strcasecmp(v->name, "adsi")) {
09753             user->adsi = ast_true(v->value);
09754          }/* else if (strcasecmp(v->name,"type")) */
09755          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09756          v = v->next;
09757          if (!v) {
09758             v = alt;
09759             alt = NULL;
09760          }
09761       }
09762       if (!user->authmethods) {
09763          if (!ast_strlen_zero(user->secret)) {
09764             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09765             if (!ast_strlen_zero(user->inkeys))
09766                user->authmethods |= IAX_AUTH_RSA;
09767          } else if (!ast_strlen_zero(user->inkeys)) {
09768             user->authmethods = IAX_AUTH_RSA;
09769          } else {
09770             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09771          }
09772       }
09773       ast_clear_flag(user, IAX_DELME);
09774    }
09775 cleanup:
09776    if (oldha)
09777       ast_free_ha(oldha);
09778    if (oldcon)
09779       free_context(oldcon);
09780    return user;
09781 }
09782 
09783 static int peer_delme_cb(void *obj, void *arg, int flags)
09784 {
09785    struct iax2_peer *peer = obj;
09786 
09787    ast_set_flag(peer, IAX_DELME);
09788 
09789    return 0;
09790 }
09791 
09792 static int user_delme_cb(void *obj, void *arg, int flags)
09793 {
09794    struct iax2_user *user = obj;
09795 
09796    ast_set_flag(user, IAX_DELME);
09797 
09798    return 0;
09799 }
09800 
09801 static void delete_users(void)
09802 {
09803    struct iax2_registry *reg;
09804 
09805    ao2_callback(users, 0, user_delme_cb, NULL);
09806 
09807    AST_LIST_LOCK(&registrations);
09808    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09809       ast_sched_del(sched, reg->expire);
09810       if (reg->callno) {
09811          ast_mutex_lock(&iaxsl[reg->callno]);
09812          if (iaxs[reg->callno]) {
09813             iaxs[reg->callno]->reg = NULL;
09814             iax2_destroy(reg->callno);
09815          }
09816          ast_mutex_unlock(&iaxsl[reg->callno]);
09817       }
09818       if (reg->dnsmgr)
09819          ast_dnsmgr_release(reg->dnsmgr);
09820       free(reg);
09821    }
09822    AST_LIST_UNLOCK(&registrations);
09823 
09824    ao2_callback(peers, 0, peer_delme_cb, NULL);
09825 }
09826 
09827 static void prune_users(void)
09828 {
09829    struct iax2_user *user;
09830    struct ao2_iterator i;
09831 
09832    i = ao2_iterator_init(users, 0);
09833    while ((user = ao2_iterator_next(&i))) {
09834       if (ast_test_flag(user, IAX_DELME))
09835          ao2_unlink(users, user);
09836       user_unref(user);
09837    }
09838 }
09839 
09840 /* Prune peers who still are supposed to be deleted */
09841 static void prune_peers(void)
09842 {
09843    struct iax2_peer *peer;
09844    struct ao2_iterator i;
09845 
09846    i = ao2_iterator_init(peers, 0);
09847    while ((peer = ao2_iterator_next(&i))) {
09848       if (ast_test_flag(peer, IAX_DELME))
09849          unlink_peer(peer);
09850       peer_unref(peer);
09851    }
09852 }
09853 
09854 static void set_timing(void)
09855 {
09856 #ifdef HAVE_ZAPTEL
09857    int bs = trunkfreq * 8;
09858    if (timingfd > -1) {
09859       if (
09860 #ifdef ZT_TIMERACK
09861          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09862 #endif         
09863          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09864          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09865    }
09866 #endif
09867 }
09868 
09869 static void set_config_destroy(void)
09870 {
09871    strcpy(accountcode, "");
09872    strcpy(language, "");
09873    strcpy(mohinterpret, "default");
09874    strcpy(mohsuggest, "");
09875    amaflags = 0;
09876    delayreject = 0;
09877    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09878    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09879    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09880    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09881    delete_users();
09882 }
09883 
09884 /*! \brief Load configuration */
09885 static int set_config(char *config_file, int reload)
09886 {
09887    struct ast_config *cfg, *ucfg;
09888    int capability=iax2_capability;
09889    struct ast_variable *v;
09890    char *cat;
09891    const char *utype;
09892    const char *tosval;
09893    int format;
09894    int portno = IAX_DEFAULT_PORTNO;
09895    int  x;
09896    struct iax2_user *user;
09897    struct iax2_peer *peer;
09898    struct ast_netsock *ns;
09899 #if 0
09900    static unsigned short int last_port=0;
09901 #endif
09902 
09903    cfg = ast_config_load(config_file);
09904    
09905    if (!cfg) {
09906       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09907       return -1;
09908    }
09909 
09910    if (reload) {
09911       set_config_destroy();
09912    }
09913 
09914    /* Reset global codec prefs */   
09915    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09916    
09917    /* Reset Global Flags */
09918    memset(&globalflags, 0, sizeof(globalflags));
09919    ast_set_flag(&globalflags, IAX_RTUPDATE);
09920 
09921 #ifdef SO_NO_CHECK
09922    nochecksums = 0;
09923 #endif
09924 
09925    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09926    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09927 
09928    maxauthreq = 3;
09929 
09930    v = ast_variable_browse(cfg, "general");
09931 
09932    /* Seed initial tos value */
09933    tosval = ast_variable_retrieve(cfg, "general", "tos");
09934    if (tosval) {
09935       if (ast_str2tos(tosval, &tos))
09936          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09937    }
09938    while(v) {
09939       if (!strcasecmp(v->name, "bindport")){ 
09940          if (reload)
09941             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09942          else
09943             portno = atoi(v->value);
09944       } else if (!strcasecmp(v->name, "pingtime")) 
09945          ping_time = atoi(v->value);
09946       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09947          if (reload) {
09948             if (atoi(v->value) != iaxthreadcount)
09949                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09950          } else {
09951             iaxthreadcount = atoi(v->value);
09952             if (iaxthreadcount < 1) {
09953                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09954                iaxthreadcount = 1;
09955             } else if (iaxthreadcount > 256) {
09956                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09957                iaxthreadcount = 256;
09958             }
09959          }
09960       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09961          if (reload) {
09962             AST_LIST_LOCK(&dynamic_list);
09963             iaxmaxthreadcount = atoi(v->value);
09964             AST_LIST_UNLOCK(&dynamic_list);
09965          } else {
09966             iaxmaxthreadcount = atoi(v->value);
09967             if (iaxmaxthreadcount < 0) {
09968                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09969                iaxmaxthreadcount = 0;
09970             } else if (iaxmaxthreadcount > 256) {
09971                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09972                iaxmaxthreadcount = 256;
09973             }
09974          }
09975       } else if (!strcasecmp(v->name, "nochecksums")) {
09976 #ifdef SO_NO_CHECK
09977          if (ast_true(v->value))
09978             nochecksums = 1;
09979          else
09980             nochecksums = 0;
09981 #else
09982          if (ast_true(v->value))
09983             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09984 #endif
09985       }
09986       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09987          maxjitterbuffer = atoi(v->value);
09988       else if (!strcasecmp(v->name, "resyncthreshold")) 
09989          resyncthreshold = atoi(v->value);
09990       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09991          maxjitterinterps = atoi(v->value);
09992       else if (!strcasecmp(v->name, "lagrqtime")) 
09993          lagrq_time = atoi(v->value);
09994       else if (!strcasecmp(v->name, "maxregexpire")) 
09995          max_reg_expire = atoi(v->value);
09996       else if (!strcasecmp(v->name, "minregexpire")) 
09997          min_reg_expire = atoi(v->value);
09998       else if (!strcasecmp(v->name, "bindaddr")) {
09999          if (reload) {
10000             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10001          } else {
10002             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10003                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10004             } else {
10005                if (option_verbose > 1) {
10006                   if (strchr(v->value, ':'))
10007                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10008                   else
10009                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10010                }
10011                if (defaultsockfd < 0) 
10012                   defaultsockfd = ast_netsock_sockfd(ns);
10013                ast_netsock_unref(ns);
10014             }
10015          }
10016       } else if (!strcasecmp(v->name, "authdebug"))
10017          authdebug = ast_true(v->value);
10018       else if (!strcasecmp(v->name, "encryption"))
10019          iax2_encryption = get_encrypt_methods(v->value);
10020       else if (!strcasecmp(v->name, "notransfer")) {
10021          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10022          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10023          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10024       } else if (!strcasecmp(v->name, "transfer")) {
10025          if (!strcasecmp(v->value, "mediaonly")) {
10026             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10027          } else if (ast_true(v->value)) {
10028             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10029          } else 
10030             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10031       } else if (!strcasecmp(v->name, "codecpriority")) {
10032          if(!strcasecmp(v->value, "caller"))
10033             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10034          else if(!strcasecmp(v->value, "disabled"))
10035             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10036          else if(!strcasecmp(v->value, "reqonly")) {
10037             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10038             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10039          }
10040       } else if (!strcasecmp(v->name, "jitterbuffer"))
10041          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10042       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10043          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10044       else if (!strcasecmp(v->name, "delayreject"))
10045          delayreject = ast_true(v->value);
10046       else if (!strcasecmp(v->name, "allowfwdownload"))
10047          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10048       else if (!strcasecmp(v->name, "rtcachefriends"))
10049          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10050       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10051          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10052       else if (!strcasecmp(v->name, "rtupdate"))
10053          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10054       else if (!strcasecmp(v->name, "trunktimestamps"))
10055          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10056       else if (!strcasecmp(v->name, "rtautoclear")) {
10057          int i = atoi(v->value);
10058          if(i > 0)
10059             global_rtautoclear = i;
10060          else
10061             i = 0;
10062          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10063       } else if (!strcasecmp(v->name, "trunkfreq")) {
10064          trunkfreq = atoi(v->value);
10065          if (trunkfreq < 10)
10066             trunkfreq = 10;
10067       } else if (!strcasecmp(v->name, "autokill")) {
10068          if (sscanf(v->value, "%d", &x) == 1) {
10069             if (x >= 0)
10070                autokill = x;
10071             else
10072                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10073          } else if (ast_true(v->value)) {
10074             autokill = DEFAULT_MAXMS;
10075          } else {
10076             autokill = 0;
10077          }
10078       } else if (!strcasecmp(v->name, "bandwidth")) {
10079          if (!strcasecmp(v->value, "low")) {
10080             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10081          } else if (!strcasecmp(v->value, "medium")) {
10082             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10083          } else if (!strcasecmp(v->value, "high")) {
10084             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10085          } else
10086             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10087       } else if (!strcasecmp(v->name, "allow")) {
10088          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10089       } else if (!strcasecmp(v->name, "disallow")) {
10090          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10091       } else if (!strcasecmp(v->name, "register")) {
10092          iax2_register(v->value, v->lineno);
10093       } else if (!strcasecmp(v->name, "iaxcompat")) {
10094          iaxcompat = ast_true(v->value);
10095       } else if (!strcasecmp(v->name, "regcontext")) {
10096          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10097          /* Create context if it doesn't exist already */
10098          if (!ast_context_find(regcontext))
10099             ast_context_create(NULL, regcontext, "IAX2");
10100       } else if (!strcasecmp(v->name, "tos")) {
10101          if (ast_str2tos(v->value, &tos))
10102             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10103       } else if (!strcasecmp(v->name, "accountcode")) {
10104          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10105       } else if (!strcasecmp(v->name, "mohinterpret")) {
10106          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10107       } else if (!strcasecmp(v->name, "mohsuggest")) {
10108          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10109       } else if (!strcasecmp(v->name, "amaflags")) {
10110          format = ast_cdr_amaflags2int(v->value);
10111          if (format < 0) {
10112             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10113          } else {
10114             amaflags = format;
10115          }
10116       } else if (!strcasecmp(v->name, "language")) {
10117          ast_copy_string(language, v->value, sizeof(language));
10118       } else if (!strcasecmp(v->name, "maxauthreq")) {
10119          maxauthreq = atoi(v->value);
10120          if (maxauthreq < 0)
10121             maxauthreq = 0;
10122       } else if (!strcasecmp(v->name, "adsi")) {
10123          adsi = ast_true(v->value);
10124       } /*else if (strcasecmp(v->name,"type")) */
10125       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10126       v = v->next;
10127    }
10128    
10129    if (defaultsockfd < 0) {
10130       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10131          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10132       } else {
10133          if (option_verbose > 1)
10134             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10135          defaultsockfd = ast_netsock_sockfd(ns);
10136          ast_netsock_unref(ns);
10137       }
10138    }
10139    if (reload) {
10140       ast_netsock_release(outsock);
10141       outsock = ast_netsock_list_alloc();
10142       if (!outsock) {
10143          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10144          return -1;
10145       }
10146       ast_netsock_init(outsock);
10147    }
10148 
10149    if (min_reg_expire > max_reg_expire) {
10150       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10151          min_reg_expire, max_reg_expire, max_reg_expire);
10152       min_reg_expire = max_reg_expire;
10153    }
10154    iax2_capability = capability;
10155    
10156    ucfg = ast_config_load("users.conf");
10157    if (ucfg) {
10158       struct ast_variable *gen;
10159       int genhasiax;
10160       int genregisteriax;
10161       const char *hasiax, *registeriax;
10162       
10163       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10164       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10165       gen = ast_variable_browse(ucfg, "general");
10166       cat = ast_category_browse(ucfg, NULL);
10167       while (cat) {
10168          if (strcasecmp(cat, "general")) {
10169             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10170             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10171             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10172                /* Start with general parameters, then specific parameters, user and peer */
10173                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10174                if (user) {
10175                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10176                   user = user_unref(user);
10177                }
10178                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10179                if (peer) {
10180                   if (ast_test_flag(peer, IAX_DYNAMIC))
10181                      reg_source_db(peer);
10182                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10183                   peer = peer_unref(peer);
10184                }
10185             }
10186             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10187                char tmp[256];
10188                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10189                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10190                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10191                if (!host)
10192                   host = ast_variable_retrieve(ucfg, "general", "host");
10193                if (!username)
10194                   username = ast_variable_retrieve(ucfg, "general", "username");
10195                if (!secret)
10196                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10197                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10198                   if (!ast_strlen_zero(secret))
10199                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10200                   else
10201                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10202                   iax2_register(tmp, 0);
10203                }
10204             }
10205          }
10206          cat = ast_category_browse(ucfg, cat);
10207       }
10208       ast_config_destroy(ucfg);
10209    }
10210    
10211    cat = ast_category_browse(cfg, NULL);
10212    while(cat) {
10213       if (strcasecmp(cat, "general")) {
10214          utype = ast_variable_retrieve(cfg, cat, "type");
10215          if (utype) {
10216             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10217                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10218                if (user) {
10219                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10220                   user = user_unref(user);
10221                }
10222             }
10223             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10224                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10225                if (peer) {
10226                   if (ast_test_flag(peer, IAX_DYNAMIC))
10227                      reg_source_db(peer);
10228                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10229                   peer = peer_unref(peer);
10230                }
10231             } else if (strcasecmp(utype, "user")) {
10232                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10233             }
10234          } else
10235             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10236       }
10237       cat = ast_category_browse(cfg, cat);
10238    }
10239    ast_config_destroy(cfg);
10240    set_timing();
10241    return 1;
10242 }
10243 
10244 static void poke_all_peers(void)
10245 {
10246    struct ao2_iterator i;
10247    struct iax2_peer *peer;
10248 
10249    i = ao2_iterator_init(peers, 0);
10250    while ((peer = ao2_iterator_next(&i))) {
10251       iax2_poke_peer(peer, 0);
10252       peer_unref(peer);
10253    }
10254 }
10255 static int reload_config(void)
10256 {
10257    char *config = "iax.conf";
10258    struct iax2_registry *reg;
10259 
10260    if (set_config(config, 1) > 0) {
10261       prune_peers();
10262       prune_users();
10263       AST_LIST_LOCK(&registrations);
10264       AST_LIST_TRAVERSE(&registrations, reg, entry)
10265          iax2_do_register(reg);
10266       AST_LIST_UNLOCK(&registrations);
10267       /* Qualify hosts, too */
10268       poke_all_peers();
10269    }
10270    reload_firmware(0);
10271    iax_provision_reload();
10272 
10273    return 0;
10274 }
10275 
10276 static int iax2_reload(int fd, int argc, char *argv[])
10277 {
10278    return reload_config();
10279 }
10280 
10281 static int reload(void)
10282 {
10283    return reload_config();
10284 }
10285 
10286 static int cache_get_callno_locked(const char *data)
10287 {
10288    struct sockaddr_in sin;
10289    int x;
10290    int callno;
10291    struct iax_ie_data ied;
10292    struct create_addr_info cai;
10293    struct parsed_dial_string pds;
10294    char *tmpstr;
10295 
10296    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10297       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10298          look up entries for a single context */
10299       if (!ast_mutex_trylock(&iaxsl[x])) {
10300          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10301             return x;
10302          ast_mutex_unlock(&iaxsl[x]);
10303       }
10304    }
10305 
10306    /* No match found, we need to create a new one */
10307 
10308    memset(&cai, 0, sizeof(cai));
10309    memset(&ied, 0, sizeof(ied));
10310    memset(&pds, 0, sizeof(pds));
10311 
10312    tmpstr = ast_strdupa(data);
10313    parse_dial_string(tmpstr, &pds);
10314 
10315    if (ast_strlen_zero(pds.peer)) {
10316       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10317       return -1;
10318    }
10319 
10320    /* Populate our address from the given */
10321    if (create_addr(pds.peer, NULL, &sin, &cai))
10322       return -1;
10323 
10324    if (option_debug)
10325       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10326          pds.peer, pds.username, pds.password, pds.context);
10327 
10328    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10329    if (callno < 1) {
10330       ast_log(LOG_WARNING, "Unable to create call\n");
10331       return -1;
10332    }
10333 
10334    ast_string_field_set(iaxs[callno], dproot, data);
10335    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10336 
10337    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10338    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10339    /* the string format is slightly different from a standard dial string,
10340       because the context appears in the 'exten' position
10341    */
10342    if (pds.exten)
10343       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10344    if (pds.username)
10345       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10346    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10347    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10348    /* Keep password handy */
10349    if (pds.password)
10350       ast_string_field_set(iaxs[callno], secret, pds.password);
10351    if (pds.key)
10352       ast_string_field_set(iaxs[callno], outkey, pds.key);
10353    /* Start the call going */
10354    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10355 
10356    return callno;
10357 }
10358 
10359 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10360 {
10361    struct iax2_dpcache *dp, *prev = NULL, *next;
10362    struct timeval tv;
10363    int x;
10364    int com[2];
10365    int timeout;
10366    int old=0;
10367    int outfd;
10368    int abort;
10369    int callno;
10370    struct ast_channel *c;
10371    struct ast_frame *f;
10372    gettimeofday(&tv, NULL);
10373    dp = dpcache;
10374    while(dp) {
10375       next = dp->next;
10376       /* Expire old caches */
10377       if (ast_tvcmp(tv, dp->expiry) > 0) {
10378             /* It's expired, let it disappear */
10379             if (prev)
10380                prev->next = dp->next;
10381             else
10382                dpcache = dp->next;
10383             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10384                /* Free memory and go again */
10385                free(dp);
10386             } else {
10387                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);
10388             }
10389             dp = next;
10390             continue;
10391       }
10392       /* We found an entry that matches us! */
10393       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10394          break;
10395       prev = dp;
10396       dp = next;
10397    }
10398    if (!dp) {
10399       /* No matching entry.  Create a new one. */
10400       /* First, can we make a callno? */
10401       callno = cache_get_callno_locked(data);
10402       if (callno < 0) {
10403          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10404          return NULL;
10405       }
10406       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10407          ast_mutex_unlock(&iaxsl[callno]);
10408          return NULL;
10409       }
10410       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10411       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10412       gettimeofday(&dp->expiry, NULL);
10413       dp->orig = dp->expiry;
10414       /* Expires in 30 mins by default */
10415       dp->expiry.tv_sec += iaxdefaultdpcache;
10416       dp->next = dpcache;
10417       dp->flags = CACHE_FLAG_PENDING;
10418       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10419          dp->waiters[x] = -1;
10420       dpcache = dp;
10421       dp->peer = iaxs[callno]->dpentries;
10422       iaxs[callno]->dpentries = dp;
10423       /* Send the request if we're already up */
10424       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10425          iax2_dprequest(dp, callno);
10426       ast_mutex_unlock(&iaxsl[callno]);
10427    }
10428    /* By here we must have a dp */
10429    if (dp->flags & CACHE_FLAG_PENDING) {
10430       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10431          for a reply to come back so long as it's pending */
10432       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10433          /* Find an empty slot */
10434          if (dp->waiters[x] < 0)
10435             break;
10436       }
10437       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10438          ast_log(LOG_WARNING, "No more waiter positions available\n");
10439          return NULL;
10440       }
10441       if (pipe(com)) {
10442          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10443          return NULL;
10444       }
10445       dp->waiters[x] = com[1];
10446       /* Okay, now we wait */
10447       timeout = iaxdefaulttimeout * 1000;
10448       /* Temporarily unlock */
10449       ast_mutex_unlock(&dpcache_lock);
10450       /* Defer any dtmf */
10451       if (chan)
10452          old = ast_channel_defer_dtmf(chan);
10453       abort = 0;
10454       while(timeout) {
10455          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10456          if (outfd > -1) {
10457             break;
10458          }
10459          if (c) {
10460             f = ast_read(c);
10461             if (f)
10462                ast_frfree(f);
10463             else {
10464                /* Got hung up on, abort! */
10465                break;
10466                abort = 1;
10467             }
10468          }
10469       }
10470       if (!timeout) {
10471          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10472       }
10473       ast_mutex_lock(&dpcache_lock);
10474       dp->waiters[x] = -1;
10475       close(com[1]);
10476       close(com[0]);
10477       if (abort) {
10478          /* Don't interpret anything, just abort.  Not sure what th epoint
10479            of undeferring dtmf on a hung up channel is but hey whatever */
10480          if (!old && chan)
10481             ast_channel_undefer_dtmf(chan);
10482          return NULL;
10483       }
10484       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10485          /* Now to do non-independent analysis the results of our wait */
10486          if (dp->flags & CACHE_FLAG_PENDING) {
10487             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10488                pending.  Don't let it take as long to timeout. */
10489             dp->flags &= ~CACHE_FLAG_PENDING;
10490             dp->flags |= CACHE_FLAG_TIMEOUT;
10491             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10492                systems without leaving it unavailable once the server comes back online */
10493             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10494             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10495                if (dp->waiters[x] > -1)
10496                   write(dp->waiters[x], "asdf", 4);
10497          }
10498       }
10499       /* Our caller will obtain the rest */
10500       if (!old && chan)
10501          ast_channel_undefer_dtmf(chan);
10502    }
10503    return dp;  
10504 }
10505 
10506 /*! \brief Part of the IAX2 switch interface */
10507 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10508 {
10509    struct iax2_dpcache *dp;
10510    int res = 0;
10511 #if 0
10512    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10513 #endif
10514    if ((priority != 1) && (priority != 2))
10515       return 0;
10516    ast_mutex_lock(&dpcache_lock);
10517    dp = find_cache(chan, data, context, exten, priority);
10518    if (dp) {
10519       if (dp->flags & CACHE_FLAG_EXISTS)
10520          res= 1;
10521    }
10522    ast_mutex_unlock(&dpcache_lock);
10523    if (!dp) {
10524       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10525    }
10526    return res;
10527 }
10528 
10529 /*! \brief part of the IAX2 dial plan switch interface */
10530 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10531 {
10532    int res = 0;
10533    struct iax2_dpcache *dp;
10534 #if 0
10535    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10536 #endif
10537    if ((priority != 1) && (priority != 2))
10538       return 0;
10539    ast_mutex_lock(&dpcache_lock);
10540    dp = find_cache(chan, data, context, exten, priority);
10541    if (dp) {
10542       if (dp->flags & CACHE_FLAG_CANEXIST)
10543          res= 1;
10544    }
10545    ast_mutex_unlock(&dpcache_lock);
10546    if (!dp) {
10547       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10548    }
10549    return res;
10550 }
10551 
10552 /*! \brief Part of the IAX2 Switch interface */
10553 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10554 {
10555    int res = 0;
10556    struct iax2_dpcache *dp;
10557 #if 0
10558    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10559 #endif
10560    if ((priority != 1) && (priority != 2))
10561       return 0;
10562    ast_mutex_lock(&dpcache_lock);
10563    dp = find_cache(chan, data, context, exten, priority);
10564    if (dp) {
10565       if (dp->flags & CACHE_FLAG_MATCHMORE)
10566          res= 1;
10567    }
10568    ast_mutex_unlock(&dpcache_lock);
10569    if (!dp) {
10570       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10571    }
10572    return res;
10573 }
10574 
10575 /*! \brief Execute IAX2 dialplan switch */
10576 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10577 {
10578    char odata[256];
10579    char req[256];
10580    char *ncontext;
10581    struct iax2_dpcache *dp;
10582    struct ast_app *dial;
10583 #if 0
10584    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);
10585 #endif
10586    if (priority == 2) {
10587       /* Indicate status, can be overridden in dialplan */
10588       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10589       if (dialstatus) {
10590          dial = pbx_findapp(dialstatus);
10591          if (dial) 
10592             pbx_exec(chan, dial, "");
10593       }
10594       return -1;
10595    } else if (priority != 1)
10596       return -1;
10597    ast_mutex_lock(&dpcache_lock);
10598    dp = find_cache(chan, data, context, exten, priority);
10599    if (dp) {
10600       if (dp->flags & CACHE_FLAG_EXISTS) {
10601          ast_copy_string(odata, data, sizeof(odata));
10602          ncontext = strchr(odata, '/');
10603          if (ncontext) {
10604             *ncontext = '\0';
10605             ncontext++;
10606             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10607          } else {
10608             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10609          }
10610          if (option_verbose > 2)
10611             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10612       } else {
10613          ast_mutex_unlock(&dpcache_lock);
10614          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10615          return -1;
10616       }
10617    }
10618    ast_mutex_unlock(&dpcache_lock);
10619    dial = pbx_findapp("Dial");
10620    if (dial) {
10621       return pbx_exec(chan, dial, req);
10622    } else {
10623       ast_log(LOG_WARNING, "No dial application registered\n");
10624    }
10625    return -1;
10626 }
10627 
10628 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10629 {
10630    struct iax2_peer *peer;
10631    char *peername, *colname;
10632 
10633    peername = ast_strdupa(data);
10634 
10635    /* if our channel, return the IP address of the endpoint of current channel */
10636    if (!strcmp(peername,"CURRENTCHANNEL")) {
10637            unsigned short callno;
10638       if (chan->tech != &iax2_tech)
10639          return -1;
10640       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10641       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10642       return 0;
10643    }
10644 
10645    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10646       *colname++ = '\0';
10647    else if ((colname = strchr(peername, '|')))
10648       *colname++ = '\0';
10649    else
10650       colname = "ip";
10651 
10652    if (!(peer = find_peer(peername, 1)))
10653       return -1;
10654 
10655    if (!strcasecmp(colname, "ip")) {
10656       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10657    } else  if (!strcasecmp(colname, "status")) {
10658       peer_status(peer, buf, len); 
10659    } else  if (!strcasecmp(colname, "mailbox")) {
10660       ast_copy_string(buf, peer->mailbox, len);
10661    } else  if (!strcasecmp(colname, "context")) {
10662       ast_copy_string(buf, peer->context, len);
10663    } else  if (!strcasecmp(colname, "expire")) {
10664       snprintf(buf, len, "%d", peer->expire);
10665    } else  if (!strcasecmp(colname, "dynamic")) {
10666       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10667    } else  if (!strcasecmp(colname, "callerid_name")) {
10668       ast_copy_string(buf, peer->cid_name, len);
10669    } else  if (!strcasecmp(colname, "callerid_num")) {
10670       ast_copy_string(buf, peer->cid_num, len);
10671    } else  if (!strcasecmp(colname, "codecs")) {
10672       ast_getformatname_multiple(buf, len -1, peer->capability);
10673    } else  if (!strncasecmp(colname, "codec[", 6)) {
10674       char *codecnum, *ptr;
10675       int index = 0, codec = 0;
10676       
10677       codecnum = strchr(colname, '[');
10678       *codecnum = '\0';
10679       codecnum++;
10680       if ((ptr = strchr(codecnum, ']'))) {
10681          *ptr = '\0';
10682       }
10683       index = atoi(codecnum);
10684       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10685          ast_copy_string(buf, ast_getformatname(codec), len);
10686       }
10687    }
10688 
10689    peer_unref(peer);
10690 
10691    return 0;
10692 }
10693 
10694 struct ast_custom_function iaxpeer_function = {
10695    .name = "IAXPEER",
10696    .synopsis = "Gets IAX peer information",
10697    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10698    .read = function_iaxpeer,
10699    .desc = "If peername specified, valid items are:\n"
10700    "- ip (default)          The IP address.\n"
10701    "- status                The peer's status (if qualify=yes)\n"
10702    "- mailbox               The configured mailbox.\n"
10703    "- context               The configured context.\n"
10704    "- expire                The epoch time of the next expire.\n"
10705    "- dynamic               Is it dynamic? (yes/no).\n"
10706    "- callerid_name         The configured Caller ID name.\n"
10707    "- callerid_num          The configured Caller ID number.\n"
10708    "- codecs                The configured codecs.\n"
10709    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10710    "\n"
10711    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10712    "\n"
10713 };
10714 
10715 
10716 /*! \brief Part of the device state notification system ---*/
10717 static int iax2_devicestate(void *data) 
10718 {
10719    struct parsed_dial_string pds;
10720    char *tmp = ast_strdupa(data);
10721    struct iax2_peer *p;
10722    int res = AST_DEVICE_INVALID;
10723 
10724    memset(&pds, 0, sizeof(pds));
10725    parse_dial_string(tmp, &pds);
10726 
10727    if (ast_strlen_zero(pds.peer)) {
10728       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10729       return res;
10730    }
10731    
10732    if (option_debug > 2)
10733       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10734 
10735    /* SLD: FIXME: second call to find_peer during registration */
10736    if (!(p = find_peer(pds.peer, 1)))
10737       return res;
10738 
10739    res = AST_DEVICE_UNAVAILABLE;
10740    if (option_debug > 2) 
10741       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10742          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10743    
10744    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10745        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10746       /* Peer is registered, or have default IP address
10747          and a valid registration */
10748       if (p->historicms == 0 || p->historicms <= p->maxms)
10749          /* let the core figure out whether it is in use or not */
10750          res = AST_DEVICE_UNKNOWN;  
10751    }
10752 
10753    peer_unref(p);
10754 
10755    return res;
10756 }
10757 
10758 static struct ast_switch iax2_switch = 
10759 {
10760    name:          "IAX2",
10761    description:      "IAX Remote Dialplan Switch",
10762    exists:        iax2_exists,
10763    canmatch:      iax2_canmatch,
10764    exec:       iax2_exec,
10765    matchmore:     iax2_matchmore,
10766 };
10767 
10768 static char show_stats_usage[] =
10769 "Usage: iax2 show stats\n"
10770 "       Display statistics on IAX channel driver.\n";
10771 
10772 static char show_cache_usage[] =
10773 "Usage: iax2 show cache\n"
10774 "       Display currently cached IAX Dialplan results.\n";
10775 
10776 static char show_peer_usage[] =
10777 "Usage: iax2 show peer <name>\n"
10778 "       Display details on specific IAX peer\n";
10779 
10780 static char prune_realtime_usage[] =
10781 "Usage: iax2 prune realtime [<peername>|all]\n"
10782 "       Prunes object(s) from the cache\n";
10783 
10784 static char iax2_reload_usage[] =
10785 "Usage: iax2 reload\n"
10786 "       Reloads IAX configuration from iax.conf\n";
10787 
10788 static char show_prov_usage[] =
10789 "Usage: iax2 provision <host> <template> [forced]\n"
10790 "       Provisions the given peer or IP address using a template\n"
10791 "       matching either 'template' or '*' if the template is not\n"
10792 "       found.  If 'forced' is specified, even empty provisioning\n"
10793 "       fields will be provisioned as empty fields.\n";
10794 
10795 static char show_users_usage[] = 
10796 "Usage: iax2 show users [like <pattern>]\n"
10797 "       Lists all known IAX2 users.\n"
10798 "       Optional regular expression pattern is used to filter the user list.\n";
10799 
10800 static char show_channels_usage[] = 
10801 "Usage: iax2 show channels\n"
10802 "       Lists all currently active IAX channels.\n";
10803 
10804 static char show_netstats_usage[] = 
10805 "Usage: iax2 show netstats\n"
10806 "       Lists network status for all currently active IAX channels.\n";
10807 
10808 static char show_threads_usage[] = 
10809 "Usage: iax2 show threads\n"
10810 "       Lists status of IAX helper threads\n";
10811 
10812 static char show_peers_usage[] = 
10813 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10814 "       Lists all known IAX2 peers.\n"
10815 "       Optional 'registered' argument lists only peers with known addresses.\n"
10816 "       Optional regular expression pattern is used to filter the peer list.\n";
10817 
10818 static char show_firmware_usage[] = 
10819 "Usage: iax2 show firmware\n"
10820 "       Lists all known IAX firmware images.\n";
10821 
10822 static char show_reg_usage[] =
10823 "Usage: iax2 show registry\n"
10824 "       Lists all registration requests and status.\n";
10825 
10826 static char debug_usage[] = 
10827 "Usage: iax2 set debug\n"
10828 "       Enables dumping of IAX packets for debugging purposes\n";
10829 
10830 static char no_debug_usage[] = 
10831 "Usage: iax2 set debug off\n"
10832 "       Disables dumping of IAX packets for debugging purposes\n";
10833 
10834 static char debug_trunk_usage[] =
10835 "Usage: iax2 set debug trunk\n"
10836 "       Requests current status of IAX trunking\n";
10837 
10838 static char no_debug_trunk_usage[] =
10839 "Usage: iax2 set debug trunk off\n"
10840 "       Requests current status of IAX trunking\n";
10841 
10842 static char debug_jb_usage[] =
10843 "Usage: iax2 set debug jb\n"
10844 "       Enables jitterbuffer debugging information\n";
10845 
10846 static char no_debug_jb_usage[] =
10847 "Usage: iax2 set debug jb off\n"
10848 "       Disables jitterbuffer debugging information\n";
10849 
10850 static char iax2_test_losspct_usage[] =
10851 "Usage: iax2 test losspct <percentage>\n"
10852 "       For testing, throws away <percentage> percent of incoming packets\n";
10853 
10854 #ifdef IAXTESTS
10855 static char iax2_test_late_usage[] =
10856 "Usage: iax2 test late <ms>\n"
10857 "       For testing, count the next frame as <ms> ms late\n";
10858 
10859 static char iax2_test_resync_usage[] =
10860 "Usage: iax2 test resync <ms>\n"
10861 "       For testing, adjust all future frames by <ms> ms\n";
10862 
10863 static char iax2_test_jitter_usage[] =
10864 "Usage: iax2 test jitter <ms> <pct>\n"
10865 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10866 #endif /* IAXTESTS */
10867 
10868 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10869    { "iax2", "trunk", "debug", NULL },
10870    iax2_do_trunk_debug, NULL,
10871    NULL };
10872 
10873 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10874    { "iax2", "jb", "debug", NULL },
10875    iax2_do_jb_debug, NULL,
10876    NULL };
10877 
10878 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10879    { "iax2", "no", "debug", NULL },
10880    iax2_no_debug, NULL,
10881    NULL };
10882 
10883 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10884    { "iax2", "no", "trunk", "debug", NULL },
10885    iax2_no_trunk_debug, NULL,
10886    NULL };
10887 
10888 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10889    { "iax2", "no", "jb", "debug", NULL },
10890    iax2_no_jb_debug, NULL,
10891    NULL };
10892 
10893 static struct ast_cli_entry cli_iax2[] = {
10894    { { "iax2", "show", "cache", NULL },
10895    iax2_show_cache, "Display IAX cached dialplan",
10896    show_cache_usage, NULL, },
10897 
10898    { { "iax2", "show", "channels", NULL },
10899    iax2_show_channels, "List active IAX channels",
10900    show_channels_usage, NULL, },
10901 
10902    { { "iax2", "show", "firmware", NULL },
10903    iax2_show_firmware, "List available IAX firmwares",
10904    show_firmware_usage, NULL, },
10905 
10906    { { "iax2", "show", "netstats", NULL },
10907    iax2_show_netstats, "List active IAX channel netstats",
10908    show_netstats_usage, NULL, },
10909 
10910    { { "iax2", "show", "peers", NULL },
10911    iax2_show_peers, "List defined IAX peers",
10912    show_peers_usage, NULL, },
10913 
10914    { { "iax2", "show", "registry", NULL },
10915    iax2_show_registry, "Display IAX registration status",
10916    show_reg_usage, NULL, },
10917 
10918    { { "iax2", "show", "stats", NULL },
10919    iax2_show_stats, "Display IAX statistics",
10920    show_stats_usage, NULL, },
10921 
10922    { { "iax2", "show", "threads", NULL },
10923    iax2_show_threads, "Display IAX helper thread info",
10924    show_threads_usage, NULL, },
10925 
10926    { { "iax2", "show", "users", NULL },
10927    iax2_show_users, "List defined IAX users",
10928    show_users_usage, NULL, },
10929 
10930    { { "iax2", "prune", "realtime", NULL },
10931    iax2_prune_realtime, "Prune a cached realtime lookup",
10932    prune_realtime_usage, complete_iax2_show_peer },
10933 
10934    { { "iax2", "reload", NULL },
10935    iax2_reload, "Reload IAX configuration",
10936    iax2_reload_usage },
10937 
10938    { { "iax2", "show", "peer", NULL },
10939    iax2_show_peer, "Show details on specific IAX peer",
10940    show_peer_usage, complete_iax2_show_peer },
10941 
10942    { { "iax2", "set", "debug", NULL },
10943    iax2_do_debug, "Enable IAX debugging",
10944    debug_usage },
10945 
10946    { { "iax2", "set", "debug", "trunk", NULL },
10947    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10948    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10949 
10950    { { "iax2", "set", "debug", "jb", NULL },
10951    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10952    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10953 
10954    { { "iax2", "set", "debug", "off", NULL },
10955    iax2_no_debug, "Disable IAX debugging",
10956    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10957 
10958    { { "iax2", "set", "debug", "trunk", "off", NULL },
10959    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10960    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10961 
10962    { { "iax2", "set", "debug", "jb", "off", NULL },
10963    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10964    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10965 
10966    { { "iax2", "test", "losspct", NULL },
10967    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10968    iax2_test_losspct_usage },
10969 
10970    { { "iax2", "provision", NULL },
10971    iax2_prov_cmd, "Provision an IAX device",
10972    show_prov_usage, iax2_prov_complete_template_3rd },
10973 
10974 #ifdef IAXTESTS
10975    { { "iax2", "test", "late", NULL },
10976    iax2_test_late, "Test the receipt of a late frame",
10977    iax2_test_late_usage },
10978 
10979    { { "iax2", "test", "resync", NULL },
10980    iax2_test_resync, "Test a resync in received timestamps",
10981    iax2_test_resync_usage },
10982 
10983    { { "iax2", "test", "jitter", NULL },
10984    iax2_test_jitter, "Simulates jitter for testing",
10985    iax2_test_jitter_usage },
10986 #endif /* IAXTESTS */
10987 };
10988 
10989 static int __unload_module(void)
10990 {
10991    struct iax2_thread *thread = NULL;
10992    int x;
10993 
10994    /* Make sure threads do not hold shared resources when they are canceled */
10995    
10996    /* Grab the sched lock resource to keep it away from threads about to die */
10997    /* Cancel the network thread, close the net socket */
10998    if (netthreadid != AST_PTHREADT_NULL) {
10999       AST_LIST_LOCK(&iaxq.queue);
11000       ast_mutex_lock(&sched_lock);
11001       pthread_cancel(netthreadid);
11002       ast_cond_signal(&sched_cond);
11003       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11004       AST_LIST_UNLOCK(&iaxq.queue);
11005       pthread_join(netthreadid, NULL);
11006    }
11007    if (schedthreadid != AST_PTHREADT_NULL) {
11008       ast_mutex_lock(&sched_lock);  
11009       pthread_cancel(schedthreadid);
11010       ast_cond_signal(&sched_cond);
11011       ast_mutex_unlock(&sched_lock);   
11012       pthread_join(schedthreadid, NULL);
11013    }
11014    
11015    /* Call for all threads to halt */
11016    AST_LIST_LOCK(&idle_list);
11017    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11018       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11019       pthread_cancel(thread->threadid);
11020    }
11021    AST_LIST_TRAVERSE_SAFE_END
11022    AST_LIST_UNLOCK(&idle_list);
11023 
11024    AST_LIST_LOCK(&active_list);
11025    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11026       AST_LIST_REMOVE_CURRENT(&active_list, list);
11027       pthread_cancel(thread->threadid);
11028    }
11029    AST_LIST_TRAVERSE_SAFE_END
11030    AST_LIST_UNLOCK(&active_list);
11031 
11032    AST_LIST_LOCK(&dynamic_list);
11033         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11034       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11035       pthread_cancel(thread->threadid);
11036         }
11037    AST_LIST_TRAVERSE_SAFE_END
11038         AST_LIST_UNLOCK(&dynamic_list);
11039 
11040    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11041 
11042    /* Wait for threads to exit */
11043    while(0 < iaxactivethreadcount)
11044       usleep(10000);
11045    
11046    ast_netsock_release(netsock);
11047    ast_netsock_release(outsock);
11048    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11049       if (iaxs[x]) {
11050          iax2_destroy(x);
11051       }
11052    }
11053    ast_manager_unregister( "IAXpeers" );
11054    ast_manager_unregister( "IAXnetstats" );
11055    ast_unregister_application(papp);
11056    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11057    ast_unregister_switch(&iax2_switch);
11058    ast_channel_unregister(&iax2_tech);
11059    delete_users();
11060    iax_provision_unload();
11061    sched_context_destroy(sched);
11062    reload_firmware(1);
11063 
11064    ast_mutex_destroy(&waresl.lock);
11065 
11066    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11067       ast_mutex_destroy(&iaxsl[x]);
11068    }
11069 
11070    ao2_ref(peers, -1);
11071    ao2_ref(users, -1);
11072    ao2_ref(iax_peercallno_pvts, -1);
11073 
11074    return 0;
11075 }
11076 
11077 static int unload_module(void)
11078 {
11079    ast_custom_function_unregister(&iaxpeer_function);
11080    return __unload_module();
11081 }
11082 
11083 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11084 {
11085    struct iax2_peer *peer = obj;
11086 
11087    if (peer->sockfd < 0)
11088       peer->sockfd = defaultsockfd;
11089 
11090    return 0;
11091 }
11092 
11093 static int pvt_hash_cb(const void *obj, const int flags)
11094 {
11095    const struct chan_iax2_pvt *pvt = obj;
11096 
11097    return pvt->peercallno;
11098 }
11099 
11100 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11101 {
11102    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11103 
11104    /* The frames_received field is used to hold whether we're matching
11105     * against a full frame or not ... */
11106 
11107    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11108       pvt2->frames_received) ? CMP_MATCH : 0;
11109 }
11110 
11111 /*! \brief Load IAX2 module, load configuraiton ---*/
11112 static int load_module(void)
11113 {
11114    char *config = "iax.conf";
11115    int res = 0;
11116    int x;
11117    struct iax2_registry *reg = NULL;
11118 
11119    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11120    if (!peers)
11121       return AST_MODULE_LOAD_FAILURE;
11122    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11123    if (!users) {
11124       ao2_ref(peers, -1);
11125       return AST_MODULE_LOAD_FAILURE;
11126    }
11127    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11128    if (!iax_peercallno_pvts) {
11129       ao2_ref(peers, -1);
11130       ao2_ref(users, -1);
11131       return AST_MODULE_LOAD_FAILURE;
11132    }
11133 
11134    ast_custom_function_register(&iaxpeer_function);
11135 
11136    iax_set_output(iax_debug_output);
11137    iax_set_error(iax_error_output);
11138    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11139    
11140 #ifdef HAVE_ZAPTEL
11141 #ifdef ZT_TIMERACK
11142    timingfd = open("/dev/zap/timer", O_RDWR);
11143    if (timingfd < 0)
11144 #endif
11145       timingfd = open("/dev/zap/pseudo", O_RDWR);
11146    if (timingfd < 0) 
11147       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11148 #endif      
11149 
11150    memset(iaxs, 0, sizeof(iaxs));
11151 
11152    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11153       ast_mutex_init(&iaxsl[x]);
11154    }
11155    
11156    ast_cond_init(&sched_cond, NULL);
11157 
11158    io = io_context_create();
11159    sched = sched_context_create();
11160    
11161    if (!io || !sched) {
11162       ast_log(LOG_ERROR, "Out of memory\n");
11163       return -1;
11164    }
11165 
11166    netsock = ast_netsock_list_alloc();
11167    if (!netsock) {
11168       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11169       return -1;
11170    }
11171    ast_netsock_init(netsock);
11172 
11173    outsock = ast_netsock_list_alloc();
11174    if (!outsock) {
11175       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11176       return -1;
11177    }
11178    ast_netsock_init(outsock);
11179 
11180    ast_mutex_init(&waresl.lock);
11181 
11182    AST_LIST_HEAD_INIT(&iaxq.queue);
11183    
11184    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11185 
11186    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11187    
11188    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11189    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11190 
11191    if(set_config(config, 0) == -1)
11192       return AST_MODULE_LOAD_DECLINE;
11193 
11194    if (ast_channel_register(&iax2_tech)) {
11195       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11196       __unload_module();
11197       return -1;
11198    }
11199 
11200    if (ast_register_switch(&iax2_switch)) 
11201       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11202 
11203    res = start_network_thread();
11204    if (!res) {
11205       if (option_verbose > 1) 
11206          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11207    } else {
11208       ast_log(LOG_ERROR, "Unable to start network thread\n");
11209       ast_netsock_release(netsock);
11210       ast_netsock_release(outsock);
11211    }
11212 
11213    AST_LIST_LOCK(&registrations);
11214    AST_LIST_TRAVERSE(&registrations, reg, entry)
11215       iax2_do_register(reg);
11216    AST_LIST_UNLOCK(&registrations); 
11217 
11218    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11219    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11220 
11221    reload_firmware(0);
11222    iax_provision_reload();
11223    return res;
11224 }
11225 
11226 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11227       .load = load_module,
11228       .unload = unload_module,
11229       .reload = reload,
11230           );

Generated on Sat Apr 18 23:45:00 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.8