Wed Feb 11 11:59:48 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  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>dahdi</use>
00033         <depend>res_features</depend>
00034  ***/
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 170642 $")
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061 
00062 #if defined(HAVE_ZAPTEL) || defined (HAVE_DAHDI)
00063 #include <sys/ioctl.h>
00064 #include "asterisk/dahdi_compat.h"
00065 #endif
00066 
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h" 
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099 
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104 
00105 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00106    multithreaded mode. */
00107 #define SCHED_MULTITHREADED
00108 
00109 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00110    thread is actually doing. */
00111 #define DEBUG_SCHED_MULTITHREAD
00112 
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116 
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120 
00121 
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124 
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130 
00131 #define DEBUG_SUPPORT
00132 
00133 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00134 
00135 /* Sample over last 100 units to determine historic jitter */
00136 #define GAMMA (0.01)
00137 
00138 static struct ast_codec_pref prefs;
00139 
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00141 
00142 static char context[80] = "default";
00143 
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146 
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158 static int last_authmethod = 0;
00159 
00160 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00161 
00162 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00163 
00164 static unsigned int tos = 0;
00165 
00166 static int min_reg_expire;
00167 static int max_reg_expire;
00168 
00169 static int timingfd = -1;           /* Timing file descriptor */
00170 
00171 static struct ast_netsock_list *netsock;
00172 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00173 static int defaultsockfd = -1;
00174 
00175 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00176 
00177 /* Ethernet, etc */
00178 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00179 /* T1, maybe ISDN */
00180 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00181                 ~AST_FORMAT_SLINEAR &        \
00182                 ~AST_FORMAT_ULAW &        \
00183                 ~AST_FORMAT_ALAW &        \
00184                 ~AST_FORMAT_G722) 
00185 /* A modem */
00186 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00187                 ~AST_FORMAT_G726 &        \
00188                 ~AST_FORMAT_G726_AAL2 &      \
00189                 ~AST_FORMAT_ADPCM)
00190 
00191 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00192                 ~AST_FORMAT_G723_1)
00193 
00194 
00195 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00196 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00197 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00198 
00199 static   struct io_context *io;
00200 static   struct sched_context *sched;
00201 
00202 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00203 
00204 static int iaxdebug = 0;
00205 
00206 static int iaxtrunkdebug = 0;
00207 
00208 static int test_losspct = 0;
00209 #ifdef IAXTESTS
00210 static int test_late = 0;
00211 static int test_resync = 0;
00212 static int test_jit = 0;
00213 static int test_jitpct = 0;
00214 #endif /* IAXTESTS */
00215 
00216 static char accountcode[AST_MAX_ACCOUNT_CODE];
00217 static char mohinterpret[MAX_MUSICCLASS];
00218 static char mohsuggest[MAX_MUSICCLASS];
00219 static int amaflags = 0;
00220 static int adsi = 0;
00221 static int delayreject = 0;
00222 static int iax2_encryption = 0;
00223 
00224 static struct ast_flags globalflags = { 0 };
00225 
00226 static pthread_t netthreadid = AST_PTHREADT_NULL;
00227 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00228 AST_MUTEX_DEFINE_STATIC(sched_lock);
00229 static ast_cond_t sched_cond;
00230 
00231 enum {
00232    IAX_STATE_STARTED =     (1 << 0),
00233    IAX_STATE_AUTHENTICATED =  (1 << 1),
00234    IAX_STATE_TBD =      (1 << 2),
00235    IAX_STATE_UNCHANGED =      (1 << 3),
00236 } iax2_state;
00237 
00238 struct iax2_context {
00239    char context[AST_MAX_CONTEXT];
00240    struct iax2_context *next;
00241 };
00242 
00243 enum {
00244    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00245    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00246    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00247    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00248    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00249    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00250    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00251    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00252         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00253    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00254    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00255    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00256    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00257    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00258    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00259    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00260    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00261    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00262    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00263    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00264    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00265    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00266    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00267    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00268    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00269    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00270                        response, so that we've achieved a three-way handshake with
00271                        them before sending voice or anything else*/
00272    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00273 } iax2_flags;
00274 
00275 static int global_rtautoclear = 120;
00276 
00277 static int reload_config(void);
00278 static int iax2_reload(int fd, int argc, char *argv[]);
00279 
00280 
00281 struct iax2_user {
00282    AST_DECLARE_STRING_FIELDS(
00283       AST_STRING_FIELD(name);
00284       AST_STRING_FIELD(secret);
00285       AST_STRING_FIELD(dbsecret);
00286       AST_STRING_FIELD(accountcode);
00287       AST_STRING_FIELD(mohinterpret);
00288       AST_STRING_FIELD(mohsuggest);
00289       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00290       AST_STRING_FIELD(language);
00291       AST_STRING_FIELD(cid_num);
00292       AST_STRING_FIELD(cid_name);
00293    );
00294    
00295    int authmethods;
00296    int encmethods;
00297    int amaflags;
00298    int adsi;
00299    unsigned int flags;
00300    int capability;
00301    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00302    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00303    struct ast_codec_pref prefs;
00304    struct ast_ha *ha;
00305    struct iax2_context *contexts;
00306    struct ast_variable *vars;
00307 };
00308 
00309 struct iax2_peer {
00310    AST_DECLARE_STRING_FIELDS(
00311       AST_STRING_FIELD(name);
00312       AST_STRING_FIELD(username);
00313       AST_STRING_FIELD(secret);
00314       AST_STRING_FIELD(dbsecret);
00315       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00316 
00317       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00318       AST_STRING_FIELD(context);      /*!< For transfers only */
00319       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00320       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00321       AST_STRING_FIELD(mohinterpret);
00322       AST_STRING_FIELD(mohsuggest);
00323       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00324       /* Suggested caller id if registering */
00325       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00326       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00327       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00328    );
00329    struct ast_codec_pref prefs;
00330    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00331    struct sockaddr_in addr;
00332    int formats;
00333    int sockfd;             /*!< Socket to use for transmission */
00334    struct in_addr mask;
00335    int adsi;
00336    unsigned int flags;
00337 
00338    /* Dynamic Registration fields */
00339    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00340    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00341    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00342 
00343    int expire;             /*!< Schedule entry for expiry */
00344    int expiry;             /*!< How soon to expire */
00345    int capability;               /*!< Capability */
00346 
00347    /* Qualification */
00348    int callno;             /*!< Call number of POKE request */
00349    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00350    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00351    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00352 
00353    int pokefreqok;               /*!< How often to check if the host is up */
00354    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00355    int historicms;               /*!< How long recent average responses took */
00356    int smoothing;             /*!< Sample over how many units to determine historic ms */
00357    
00358    struct ast_ha *ha;
00359 };
00360 
00361 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00362 
00363 static struct iax2_trunk_peer {
00364    ast_mutex_t lock;
00365    int sockfd;
00366    struct sockaddr_in addr;
00367    struct timeval txtrunktime;      /*!< Transmit trunktime */
00368    struct timeval rxtrunktime;      /*!< Receive trunktime */
00369    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00370    struct timeval trunkact;      /*!< Last trunk activity */
00371    unsigned int lastsent;        /*!< Last sent time */
00372    /* Trunk data and length */
00373    unsigned char *trunkdata;
00374    unsigned int trunkdatalen;
00375    unsigned int trunkdataalloc;
00376    struct iax2_trunk_peer *next;
00377    int trunkerror;
00378    int calls;
00379 } *tpeers = NULL;
00380 
00381 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00382 
00383 struct iax_firmware {
00384    struct iax_firmware *next;
00385    int fd;
00386    int mmaplen;
00387    int dead;
00388    struct ast_iax2_firmware_header *fwh;
00389    unsigned char *buf;
00390 };
00391 
00392 enum iax_reg_state {
00393    REG_STATE_UNREGISTERED = 0,
00394    REG_STATE_REGSENT,
00395    REG_STATE_AUTHSENT,
00396    REG_STATE_REGISTERED,
00397    REG_STATE_REJECTED,
00398    REG_STATE_TIMEOUT,
00399    REG_STATE_NOAUTH
00400 };
00401 
00402 enum iax_transfer_state {
00403    TRANSFER_NONE = 0,
00404    TRANSFER_BEGIN,
00405    TRANSFER_READY,
00406    TRANSFER_RELEASED,
00407    TRANSFER_PASSTHROUGH,
00408    TRANSFER_MBEGIN,
00409    TRANSFER_MREADY,
00410    TRANSFER_MRELEASED,
00411    TRANSFER_MPASSTHROUGH,
00412    TRANSFER_MEDIA,
00413    TRANSFER_MEDIAPASS
00414 };
00415 
00416 struct iax2_registry {
00417    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00418    char username[80];
00419    char secret[80];        /*!< Password or key name in []'s */
00420    char random[80];
00421    int expire;          /*!< Sched ID of expiration */
00422    int refresh;            /*!< How often to refresh */
00423    enum iax_reg_state regstate;
00424    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00425    int callno;          /*!< Associated call number if applicable */
00426    struct sockaddr_in us;        /*!< Who the server thinks we are */
00427    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00428    AST_LIST_ENTRY(iax2_registry) entry;
00429 };
00430 
00431 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00432 
00433 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00434 #define MIN_RETRY_TIME     100
00435 #define MAX_RETRY_TIME     10000
00436 
00437 #define MAX_JITTER_BUFFER  50
00438 #define MIN_JITTER_BUFFER  10
00439 
00440 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00441 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00442 
00443 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00444 
00445 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00446 #define TS_GAP_FOR_JB_RESYNC  5000
00447 
00448 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00449 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00450 static int iaxdynamicthreadcount = 0;
00451 static int iaxdynamicthreadnum = 0;
00452 static int iaxactivethreadcount = 0;
00453 
00454 struct iax_rr {
00455    int jitter;
00456    int losspct;
00457    int losscnt;
00458    int packets;
00459    int delay;
00460    int dropped;
00461    int ooo;
00462 };
00463 
00464 struct chan_iax2_pvt {
00465    /*! Socket to send/receive on for this call */
00466    int sockfd;
00467    /*! Last received voice format */
00468    int voiceformat;
00469    /*! Last received video format */
00470    int videoformat;
00471    /*! Last sent voice format */
00472    int svoiceformat;
00473    /*! Last sent video format */
00474    int svideoformat;
00475    /*! What we are capable of sending */
00476    int capability;
00477    /*! Last received timestamp */
00478    unsigned int last;
00479    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00480    unsigned int lastsent;
00481    /*! Timestamp of the last video frame sent */
00482    unsigned int lastvsent;
00483    /*! Next outgoing timestamp if everything is good */
00484    unsigned int nextpred;
00485    /*! True if the last voice we transmitted was not silence/CNG */
00486    int notsilenttx;
00487    /*! Ping time */
00488    unsigned int pingtime;
00489    /*! Max time for initial response */
00490    int maxtime;
00491    /*! Peer Address */
00492    struct sockaddr_in addr;
00493    /*! Actual used codec preferences */
00494    struct ast_codec_pref prefs;
00495    /*! Requested codec preferences */
00496    struct ast_codec_pref rprefs;
00497    /*! Our call number */
00498    unsigned short callno;
00499    /*! Peer callno */
00500    unsigned short peercallno;
00501    /*! Negotiated format, this is only used to remember what format was
00502        chosen for an unauthenticated call so that the channel can get
00503        created later using the right format */
00504    int chosenformat;
00505    /*! Peer selected format */
00506    int peerformat;
00507    /*! Peer capability */
00508    int peercapability;
00509    /*! timeval that we base our transmission on */
00510    struct timeval offset;
00511    /*! timeval that we base our delivery on */
00512    struct timeval rxcore;
00513    /*! The jitterbuffer */
00514         jitterbuf *jb;
00515    /*! active jb read scheduler id */
00516         int jbid;                       
00517    /*! LAG */
00518    int lag;
00519    /*! Error, as discovered by the manager */
00520    int error;
00521    /*! Owner if we have one */
00522    struct ast_channel *owner;
00523    /*! What's our state? */
00524    struct ast_flags state;
00525    /*! Expiry (optional) */
00526    int expiry;
00527    /*! Next outgoing sequence number */
00528    unsigned char oseqno;
00529    /*! Next sequence number they have not yet acknowledged */
00530    unsigned char rseqno;
00531    /*! Next incoming sequence number */
00532    unsigned char iseqno;
00533    /*! Last incoming sequence number we have acknowledged */
00534    unsigned char aseqno;
00535 
00536    AST_DECLARE_STRING_FIELDS(
00537       /*! Peer name */
00538       AST_STRING_FIELD(peer);
00539       /*! Default Context */
00540       AST_STRING_FIELD(context);
00541       /*! Caller ID if available */
00542       AST_STRING_FIELD(cid_num);
00543       AST_STRING_FIELD(cid_name);
00544       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00545       AST_STRING_FIELD(ani);
00546       /*! DNID */
00547       AST_STRING_FIELD(dnid);
00548       /*! RDNIS */
00549       AST_STRING_FIELD(rdnis);
00550       /*! Requested Extension */
00551       AST_STRING_FIELD(exten);
00552       /*! Expected Username */
00553       AST_STRING_FIELD(username);
00554       /*! Expected Secret */
00555       AST_STRING_FIELD(secret);
00556       /*! MD5 challenge */
00557       AST_STRING_FIELD(challenge);
00558       /*! Public keys permitted keys for incoming authentication */
00559       AST_STRING_FIELD(inkeys);
00560       /*! Private key for outgoing authentication */
00561       AST_STRING_FIELD(outkey);
00562       /*! Preferred language */
00563       AST_STRING_FIELD(language);
00564       /*! Hostname/peername for naming purposes */
00565       AST_STRING_FIELD(host);
00566 
00567       AST_STRING_FIELD(dproot);
00568       AST_STRING_FIELD(accountcode);
00569       AST_STRING_FIELD(mohinterpret);
00570       AST_STRING_FIELD(mohsuggest);
00571    );
00572    
00573    /*! permitted authentication methods */
00574    int authmethods;
00575    /*! permitted encryption methods */
00576    int encmethods;
00577    /*! Encryption AES-128 Key */
00578    aes_encrypt_ctx ecx;
00579    /*! Decryption AES-128 Key */
00580    aes_decrypt_ctx dcx;
00581    /*! 32 bytes of semi-random data */
00582    unsigned char semirand[32];
00583    /*! Associated registry */
00584    struct iax2_registry *reg;
00585    /*! Associated peer for poking */
00586    struct iax2_peer *peerpoke;
00587    /*! IAX_ flags */
00588    unsigned int flags;
00589    int adsi;
00590 
00591    /*! Transferring status */
00592    enum iax_transfer_state transferring;
00593    /*! Transfer identifier */
00594    int transferid;
00595    /*! Who we are IAX transfering to */
00596    struct sockaddr_in transfer;
00597    /*! What's the new call number for the transfer */
00598    unsigned short transfercallno;
00599    /*! Transfer decrypt AES-128 Key */
00600    aes_encrypt_ctx tdcx;
00601 
00602    /*! Status of knowledge of peer ADSI capability */
00603    int peeradsicpe;
00604 
00605    /*! Who we are bridged to */
00606    unsigned short bridgecallno;
00607    
00608    int pingid;       /*!< Transmit PING request */
00609    int lagid;        /*!< Retransmit lag request */
00610    int autoid;       /*!< Auto hangup for Dialplan requestor */
00611    int authid;       /*!< Authentication rejection ID */
00612    int authfail;        /*!< Reason to report failure */
00613    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00614    int calling_ton;
00615    int calling_tns;
00616    int calling_pres;
00617    int amaflags;
00618    struct iax2_dpcache *dpentries;
00619    struct ast_variable *vars;
00620    /*! last received remote rr */
00621    struct iax_rr remote_rr;
00622    /*! Current base time: (just for stats) */
00623    int min;
00624    /*! Dropped frame count: (just for stats) */
00625    int frames_dropped;
00626    /*! received frame count: (just for stats) */
00627    int frames_received;
00628 };
00629 
00630 static struct ast_iax2_queue {
00631    AST_LIST_HEAD(, iax_frame) queue;
00632    int count;
00633 } iaxq;
00634 
00635 /*!
00636  * This module will get much higher performance when doing a lot of
00637  * user and peer lookups if the number of buckets is increased from 1.
00638  * However, to maintain old behavior for Asterisk 1.4, these are set to
00639  * 1 by default.  When using multiple buckets, search order through these
00640  * containers is considered random, so you will not be able to depend on
00641  * the order the entires are specified in iax.conf for matching order. */
00642 #ifdef LOW_MEMORY
00643 #define MAX_PEER_BUCKETS 1
00644 /* #define MAX_PEER_BUCKETS 17 */
00645 #else
00646 #define MAX_PEER_BUCKETS 1
00647 /* #define MAX_PEER_BUCKETS 563 */
00648 #endif
00649 static struct ao2_container *peers;
00650 
00651 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00652 static struct ao2_container *users;
00653 
00654 static struct ast_firmware_list {
00655    struct iax_firmware *wares;
00656    ast_mutex_t lock;
00657 } waresl;
00658 
00659 /*! Extension exists */
00660 #define CACHE_FLAG_EXISTS     (1 << 0)
00661 /*! Extension is nonexistent */
00662 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00663 /*! Extension can exist */
00664 #define CACHE_FLAG_CANEXIST      (1 << 2)
00665 /*! Waiting to hear back response */
00666 #define CACHE_FLAG_PENDING    (1 << 3)
00667 /*! Timed out */
00668 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00669 /*! Request transmitted */
00670 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00671 /*! Timeout */
00672 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00673 /*! Matchmore */
00674 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00675 
00676 static struct iax2_dpcache {
00677    char peercontext[AST_MAX_CONTEXT];
00678    char exten[AST_MAX_EXTENSION];
00679    struct timeval orig;
00680    struct timeval expiry;
00681    int flags;
00682    unsigned short callno;
00683    int waiters[256];
00684    struct iax2_dpcache *next;
00685    struct iax2_dpcache *peer; /*!< For linking in peers */
00686 } *dpcache;
00687 
00688 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00689 
00690 static void reg_source_db(struct iax2_peer *p);
00691 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00692 
00693 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00694 
00695 #define IAX_IOSTATE_IDLE      0
00696 #define IAX_IOSTATE_READY     1
00697 #define IAX_IOSTATE_PROCESSING   2
00698 #define IAX_IOSTATE_SCHEDREADY   3
00699 
00700 #define IAX_TYPE_POOL    1
00701 #define IAX_TYPE_DYNAMIC 2
00702 
00703 struct iax2_pkt_buf {
00704    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00705    size_t len;
00706    unsigned char buf[1];
00707 };
00708 
00709 struct iax2_thread {
00710    AST_LIST_ENTRY(iax2_thread) list;
00711    int type;
00712    int iostate;
00713 #ifdef SCHED_MULTITHREADED
00714    void (*schedfunc)(const void *);
00715    const void *scheddata;
00716 #endif
00717 #ifdef DEBUG_SCHED_MULTITHREAD
00718    char curfunc[80];
00719 #endif   
00720    int actions;
00721    pthread_t threadid;
00722    int threadnum;
00723    struct sockaddr_in iosin;
00724    unsigned char readbuf[4096]; 
00725    unsigned char *buf;
00726    ssize_t buf_len;
00727    size_t buf_size;
00728    int iofd;
00729    time_t checktime;
00730    ast_mutex_t lock;
00731    ast_cond_t cond;
00732    unsigned int ready_for_signal:1;
00733    /*! if this thread is processing a full frame,
00734      some information about that frame will be stored
00735      here, so we can avoid dispatching any more full
00736      frames for that callno to other threads */
00737    struct {
00738       unsigned short callno;
00739       struct sockaddr_in sin;
00740       unsigned char type;
00741       unsigned char csub;
00742    } ffinfo;
00743    /*! Queued up full frames for processing.  If more full frames arrive for
00744     *  a call which this thread is already processing a full frame for, they
00745     *  are queued up here. */
00746    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00747 };
00748 
00749 /* Thread lists */
00750 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00751 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00752 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00753 
00754 static void *iax2_process_thread(void *data);
00755 
00756 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00757 {
00758    ast_mutex_lock(lock);
00759    ast_cond_signal(cond);
00760    ast_mutex_unlock(lock);
00761 }
00762 
00763 static void iax_debug_output(const char *data)
00764 {
00765    if (iaxdebug)
00766       ast_verbose("%s", data);
00767 }
00768 
00769 static void iax_error_output(const char *data)
00770 {
00771    ast_log(LOG_WARNING, "%s", data);
00772 }
00773 
00774 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00775 {
00776    va_list args;
00777    char buf[1024];
00778 
00779    va_start(args, fmt);
00780    vsnprintf(buf, 1024, fmt, args);
00781    va_end(args);
00782 
00783    ast_log(LOG_ERROR, "%s", buf);
00784 }
00785 
00786 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00787 {
00788    va_list args;
00789    char buf[1024];
00790 
00791    va_start(args, fmt);
00792    vsnprintf(buf, 1024, fmt, args);
00793    va_end(args);
00794 
00795    ast_log(LOG_WARNING, "%s", buf);
00796 }
00797 
00798 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00799 {
00800    va_list args;
00801    char buf[1024];
00802 
00803    va_start(args, fmt);
00804    vsnprintf(buf, 1024, fmt, args);
00805    va_end(args);
00806 
00807    ast_verbose("%s", buf);
00808 }
00809 
00810 /* XXX We probably should use a mutex when working with this XXX */
00811 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00812 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00813 static struct timeval lastused[ARRAY_LEN(iaxs)];
00814 
00815 /*!
00816  * \brief Another container of iax2_pvt structures
00817  *
00818  * Active IAX2 pvt structs are also stored in this container, if they are a part
00819  * of an active call where we know the remote side's call number.  The reason
00820  * for this is that incoming media frames do not contain our call number.  So,
00821  * instead of having to iterate the entire iaxs array, we use this container to
00822  * look up calls where the remote side is using a given call number.
00823  */
00824 static struct ao2_container *iax_peercallno_pvts;
00825 
00826 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00827    but keeps the division between trunked and non-trunked better. */
00828 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00829 
00830 static int maxtrunkcall = TRUNK_CALL_START;
00831 static int maxnontrunkcall = 1;
00832 
00833 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);
00834 static int expire_registry(const void *data);
00835 static int iax2_answer(struct ast_channel *c);
00836 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00837 static int iax2_devicestate(void *data);
00838 static int iax2_digit_begin(struct ast_channel *c, char digit);
00839 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00840 static int iax2_do_register(struct iax2_registry *reg);
00841 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00842 static int iax2_hangup(struct ast_channel *c);
00843 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00844 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00845 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00846 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00847 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00848 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00849 static int iax2_sendtext(struct ast_channel *c, const char *text);
00850 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00851 static int iax2_transfer(struct ast_channel *c, const char *dest);
00852 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00853 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00854 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00855 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00856 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00857 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00858 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00859 static struct ast_frame *iax2_read(struct ast_channel *c);
00860 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00861 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00862 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00863 static void prune_peers(void);
00864 
00865 static const struct ast_channel_tech iax2_tech = {
00866    .type = "IAX2",
00867    .description = tdesc,
00868    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00869    .properties = AST_CHAN_TP_WANTSJITTER,
00870    .requester = iax2_request,
00871    .devicestate = iax2_devicestate,
00872    .send_digit_begin = iax2_digit_begin,
00873    .send_digit_end = iax2_digit_end,
00874    .send_text = iax2_sendtext,
00875    .send_image = iax2_sendimage,
00876    .send_html = iax2_sendhtml,
00877    .call = iax2_call,
00878    .hangup = iax2_hangup,
00879    .answer = iax2_answer,
00880    .read = iax2_read,
00881    .write = iax2_write,
00882    .write_video = iax2_write,
00883    .indicate = iax2_indicate,
00884    .setoption = iax2_setoption,
00885    .bridge = iax2_bridge,
00886    .transfer = iax2_transfer,
00887    .fixup = iax2_fixup,
00888 };
00889 
00890 /* WARNING: insert_idle_thread should only ever be called within the
00891  * context of an iax2_process_thread() thread.
00892  */
00893 static void insert_idle_thread(struct iax2_thread *thread)
00894 {
00895    if (thread->type == IAX_TYPE_DYNAMIC) {
00896       AST_LIST_LOCK(&dynamic_list);
00897       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00898       AST_LIST_UNLOCK(&dynamic_list);
00899    } else {
00900       AST_LIST_LOCK(&idle_list);
00901       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00902       AST_LIST_UNLOCK(&idle_list);
00903    }
00904 
00905    return;
00906 }
00907 
00908 static struct iax2_thread *find_idle_thread(void)
00909 {
00910    pthread_attr_t attr;
00911    struct iax2_thread *thread = NULL;
00912 
00913    /* Pop the head of the list off */
00914    AST_LIST_LOCK(&idle_list);
00915    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00916    AST_LIST_UNLOCK(&idle_list);
00917 
00918    /* If no idle thread is available from the regular list, try dynamic */
00919    if (thread == NULL) {
00920       AST_LIST_LOCK(&dynamic_list);
00921       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00922       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00923       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00924          /* We need to MAKE a thread! */
00925          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00926             thread->threadnum = iaxdynamicthreadnum++;
00927             thread->type = IAX_TYPE_DYNAMIC;
00928             ast_mutex_init(&thread->lock);
00929             ast_cond_init(&thread->cond, NULL);
00930             pthread_attr_init(&attr);
00931             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00932             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00933                free(thread);
00934                thread = NULL;
00935             } else {
00936                /* All went well and the thread is up, so increment our count */
00937                iaxdynamicthreadcount++;
00938                
00939                /* Wait for the thread to be ready before returning it to the caller */
00940                while (!thread->ready_for_signal)
00941                   usleep(1);
00942             }
00943          }
00944       }
00945       AST_LIST_UNLOCK(&dynamic_list);
00946    }
00947 
00948    /* this thread is not processing a full frame (since it is idle),
00949       so ensure that the field for the full frame call number is empty */
00950    if (thread)
00951       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00952 
00953    return thread;
00954 }
00955 
00956 #ifdef SCHED_MULTITHREADED
00957 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00958 {
00959    struct iax2_thread *thread = NULL;
00960    static time_t lasterror;
00961    static time_t t;
00962 
00963    thread = find_idle_thread();
00964 
00965    if (thread != NULL) {
00966       thread->schedfunc = func;
00967       thread->scheddata = data;
00968       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00969 #ifdef DEBUG_SCHED_MULTITHREAD
00970       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00971 #endif
00972       signal_condition(&thread->lock, &thread->cond);
00973       return 0;
00974    }
00975    time(&t);
00976    if (t != lasterror && option_debug) 
00977       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00978    lasterror = t;
00979 
00980    return -1;
00981 }
00982 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00983 #endif
00984 
00985 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00986 {
00987    int res;
00988 
00989    res = ast_sched_add(con, when, callback, data);
00990    signal_condition(&sched_lock, &sched_cond);
00991 
00992    return res;
00993 }
00994 
00995 static int send_ping(const void *data);
00996 
00997 static void __send_ping(const void *data)
00998 {
00999    int callno = (long) data;
01000 
01001    ast_mutex_lock(&iaxsl[callno]);
01002 
01003    if (iaxs[callno]) {
01004       if (iaxs[callno]->peercallno) {
01005          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01006          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01007       } else {
01008          /* I am the schedule, so I'm allowed to do this */
01009          iaxs[callno]->pingid = -1;
01010       }
01011    } else if (option_debug > 0) {
01012       ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01013    }
01014 
01015    ast_mutex_unlock(&iaxsl[callno]);
01016 }
01017 
01018 static int send_ping(const void *data)
01019 {
01020 #ifdef SCHED_MULTITHREADED
01021    if (schedule_action(__send_ping, data))
01022 #endif      
01023       __send_ping(data);
01024 
01025    return 0;
01026 }
01027 
01028 static int get_encrypt_methods(const char *s)
01029 {
01030    int e;
01031    if (!strcasecmp(s, "aes128"))
01032       e = IAX_ENCRYPT_AES128;
01033    else if (ast_true(s))
01034       e = IAX_ENCRYPT_AES128;
01035    else
01036       e = 0;
01037    return e;
01038 }
01039 
01040 static int send_lagrq(const void *data);
01041 
01042 static void __send_lagrq(const void *data)
01043 {
01044    int callno = (long) data;
01045 
01046    ast_mutex_lock(&iaxsl[callno]);
01047 
01048    if (iaxs[callno]) {
01049       if (iaxs[callno]->peercallno) {
01050          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01051          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01052       } else {
01053          /* I am the schedule, so I'm allowed to do this */
01054          iaxs[callno]->lagid = -1;
01055       }
01056    } else {
01057       ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01058    }
01059 
01060    ast_mutex_unlock(&iaxsl[callno]);
01061 }
01062 
01063 static int send_lagrq(const void *data)
01064 {
01065 #ifdef SCHED_MULTITHREADED
01066    if (schedule_action(__send_lagrq, data))
01067 #endif      
01068       __send_lagrq(data);
01069    
01070    return 0;
01071 }
01072 
01073 static unsigned char compress_subclass(int subclass)
01074 {
01075    int x;
01076    int power=-1;
01077    /* If it's 128 or smaller, just return it */
01078    if (subclass < IAX_FLAG_SC_LOG)
01079       return subclass;
01080    /* Otherwise find its power */
01081    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01082       if (subclass & (1 << x)) {
01083          if (power > -1) {
01084             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01085             return 0;
01086          } else
01087             power = x;
01088       }
01089    }
01090    return power | IAX_FLAG_SC_LOG;
01091 }
01092 
01093 static int uncompress_subclass(unsigned char csub)
01094 {
01095    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01096    if (csub & IAX_FLAG_SC_LOG) {
01097       /* special case for 'compressed' -1 */
01098       if (csub == 0xff)
01099          return -1;
01100       else
01101          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01102    }
01103    else
01104       return csub;
01105 }
01106 
01107 /*!
01108  * \note The only member of the peer passed here guaranteed to be set is the name field
01109  */
01110 static int peer_hash_cb(const void *obj, const int flags)
01111 {
01112    const struct iax2_peer *peer = obj;
01113 
01114    return ast_str_hash(peer->name);
01115 }
01116 
01117 /*!
01118  * \note The only member of the peer passed here guaranteed to be set is the name field
01119  */
01120 static int peer_cmp_cb(void *obj, void *arg, int flags)
01121 {
01122    struct iax2_peer *peer = obj, *peer2 = arg;
01123 
01124    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01125 }
01126 
01127 /*!
01128  * \note The only member of the user passed here guaranteed to be set is the name field
01129  */
01130 static int user_hash_cb(const void *obj, const int flags)
01131 {
01132    const struct iax2_user *user = obj;
01133 
01134    return ast_str_hash(user->name);
01135 }
01136 
01137 /*!
01138  * \note The only member of the user passed here guaranteed to be set is the name field
01139  */
01140 static int user_cmp_cb(void *obj, void *arg, int flags)
01141 {
01142    struct iax2_user *user = obj, *user2 = arg;
01143 
01144    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01145 }
01146 
01147 /*!
01148  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01149  *       so do not call it with a pvt lock held.
01150  */
01151 static struct iax2_peer *find_peer(const char *name, int realtime) 
01152 {
01153    struct iax2_peer *peer = NULL;
01154    struct iax2_peer tmp_peer = {
01155       .name = name,
01156    };
01157 
01158    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01159 
01160    /* Now go for realtime if applicable */
01161    if(!peer && realtime)
01162       peer = realtime_peer(name, NULL);
01163 
01164    return peer;
01165 }
01166 
01167 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01168 {
01169    ao2_ref(peer, +1);
01170    return peer;
01171 }
01172 
01173 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01174 {
01175    ao2_ref(peer, -1);
01176    return NULL;
01177 }
01178 
01179 static inline struct iax2_user *user_ref(struct iax2_user *user)
01180 {
01181    ao2_ref(user, +1);
01182    return user;
01183 }
01184 
01185 static inline struct iax2_user *user_unref(struct iax2_user *user)
01186 {
01187    ao2_ref(user, -1);
01188    return NULL;
01189 }
01190 
01191 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01192 {
01193    struct iax2_peer *peer = NULL;
01194    int res = 0;
01195    struct ao2_iterator i;
01196 
01197    i = ao2_iterator_init(peers, 0);
01198    while ((peer = ao2_iterator_next(&i))) {
01199       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01200           (peer->addr.sin_port == sin.sin_port)) {
01201          ast_copy_string(host, peer->name, len);
01202          peer_unref(peer);
01203          res = 1;
01204          break;
01205       }
01206       peer_unref(peer);
01207    }
01208 
01209    if (!peer) {
01210       peer = realtime_peer(NULL, &sin);
01211       if (peer) {
01212          ast_copy_string(host, peer->name, len);
01213          peer_unref(peer);
01214          res = 1;
01215       }
01216    }
01217 
01218    return res;
01219 }
01220 
01221 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01222 {
01223    /* Decrement AUTHREQ count if needed */
01224    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01225       struct iax2_user *user;
01226       struct iax2_user tmp_user = {
01227          .name = pvt->username,
01228       };
01229 
01230       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01231       if (user) {
01232          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01233          user = user_unref(user);       
01234       }
01235 
01236       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01237    }
01238 
01239    /* No more pings or lagrq's */
01240    AST_SCHED_DEL(sched, pvt->pingid);
01241    AST_SCHED_DEL(sched, pvt->lagid);
01242    AST_SCHED_DEL(sched, pvt->autoid);
01243    AST_SCHED_DEL(sched, pvt->authid);
01244    AST_SCHED_DEL(sched, pvt->initid);
01245    AST_SCHED_DEL(sched, pvt->jbid);
01246 }
01247 
01248 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01249 {
01250    if (!pvt->peercallno) {
01251       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01252       return;
01253    }
01254 
01255    ao2_link(iax_peercallno_pvts, pvt);
01256 }
01257 
01258 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01259 {
01260    if (!pvt->peercallno) {
01261       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01262       return;
01263    }
01264 
01265    ao2_unlink(iax_peercallno_pvts, pvt);
01266 }
01267 
01268 static void update_max_trunk(void)
01269 {
01270    int max = TRUNK_CALL_START;
01271    int x;
01272 
01273    /* XXX Prolly don't need locks here XXX */
01274    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01275       if (iaxs[x]) {
01276          max = x + 1;
01277       }
01278    }
01279 
01280    maxtrunkcall = max;
01281    if (option_debug && iaxdebug)
01282       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01283 }
01284 
01285 static void iax2_frame_free(struct iax_frame *fr)
01286 {
01287    AST_SCHED_DEL(sched, fr->retrans);
01288    iax_frame_free(fr);
01289 }
01290 
01291 static void iax2_destroy(int callno)
01292 {
01293    struct chan_iax2_pvt *pvt;
01294    struct ast_channel *owner;
01295 
01296 retry:
01297    pvt = iaxs[callno];
01298    gettimeofday(&lastused[callno], NULL);
01299    
01300    owner = pvt ? pvt->owner : NULL;
01301 
01302    if (owner) {
01303       if (ast_mutex_trylock(&owner->lock)) {
01304          if (option_debug > 2)
01305             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01306          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01307          goto retry;
01308       }
01309    }
01310    if (!owner && iaxs[callno]) {
01311       AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]);
01312       AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]);
01313       iaxs[callno] = NULL;
01314    }
01315 
01316    if (pvt) {
01317       if (!owner) {
01318          pvt->owner = NULL;
01319       } else {
01320          /* If there's an owner, prod it to give up */
01321          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01322           * because we already hold the owner channel lock. */
01323          ast_queue_hangup(owner);
01324       }
01325 
01326       if (pvt->peercallno) {
01327          remove_by_peercallno(pvt);
01328       }
01329 
01330       if (!owner) {
01331          ao2_ref(pvt, -1);
01332          pvt = NULL;
01333       }
01334    }
01335 
01336    if (owner) {
01337       ast_mutex_unlock(&owner->lock);
01338    }
01339 
01340    if (callno & 0x4000) {
01341       update_max_trunk();
01342    }
01343 }
01344 
01345 static int scheduled_destroy(const void *vid)
01346 {
01347    short callno = PTR_TO_CALLNO(vid);
01348    ast_mutex_lock(&iaxsl[callno]);
01349    if (iaxs[callno]) {
01350       if (option_debug) {
01351          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01352       }
01353       iax2_destroy(callno);
01354    }
01355    ast_mutex_unlock(&iaxsl[callno]);
01356    return 0;
01357 }
01358 
01359 static void pvt_destructor(void *obj)
01360 {
01361    struct chan_iax2_pvt *pvt = obj;
01362    struct iax_frame *cur = NULL;
01363 
01364    iax2_destroy_helper(pvt);
01365 
01366    /* Already gone */
01367    ast_set_flag(pvt, IAX_ALREADYGONE); 
01368 
01369    AST_LIST_LOCK(&iaxq.queue);
01370    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01371       /* Cancel any pending transmissions */
01372       if (cur->callno == pvt->callno) { 
01373          cur->retries = -1;
01374       }
01375    }
01376    AST_LIST_UNLOCK(&iaxq.queue);
01377 
01378    if (pvt->reg) {
01379       pvt->reg->callno = 0;
01380    }
01381 
01382    if (!pvt->owner) {
01383       jb_frame frame;
01384       if (pvt->vars) {
01385           ast_variables_destroy(pvt->vars);
01386           pvt->vars = NULL;
01387       }
01388 
01389       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01390          iax2_frame_free(frame.data);
01391       }
01392 
01393       jb_destroy(pvt->jb);
01394       ast_string_field_free_memory(pvt);
01395    }
01396 }
01397 
01398 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01399 {
01400    struct chan_iax2_pvt *tmp;
01401    jb_conf jbconf;
01402 
01403    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01404       return NULL;
01405    }
01406 
01407    if (ast_string_field_init(tmp, 32)) {
01408       ao2_ref(tmp, -1);
01409       tmp = NULL;
01410       return NULL;
01411    }
01412       
01413    tmp->prefs = prefs;
01414    tmp->callno = 0;
01415    tmp->peercallno = 0;
01416    tmp->transfercallno = 0;
01417    tmp->bridgecallno = 0;
01418    tmp->pingid = -1;
01419    tmp->lagid = -1;
01420    tmp->autoid = -1;
01421    tmp->authid = -1;
01422    tmp->initid = -1;
01423 
01424    ast_string_field_set(tmp,exten, "s");
01425    ast_string_field_set(tmp,host, host);
01426 
01427    tmp->jb = jb_new();
01428    tmp->jbid = -1;
01429    jbconf.max_jitterbuf = maxjitterbuffer;
01430    jbconf.resync_threshold = resyncthreshold;
01431    jbconf.max_contig_interp = maxjitterinterps;
01432    jb_setconf(tmp->jb,&jbconf);
01433 
01434    return tmp;
01435 }
01436 
01437 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01438 {
01439    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01440    if (new) {
01441       size_t afdatalen = new->afdatalen;
01442       memcpy(new, fr, sizeof(*new));
01443       iax_frame_wrap(new, &fr->af);
01444       new->afdatalen = afdatalen;
01445       new->data = NULL;
01446       new->datalen = 0;
01447       new->direction = DIRECTION_INGRESS;
01448       new->retrans = -1;
01449    }
01450    return new;
01451 }
01452 
01453 #define NEW_PREVENT  0
01454 #define NEW_ALLOW    1
01455 #define NEW_FORCE    2
01456 
01457 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01458 {
01459    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01460       (cur->addr.sin_port == sin->sin_port)) {
01461       /* This is the main host */
01462       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01463           (check_dcallno ? dcallno == cur->callno : 1) ) {
01464          /* That's us.  Be sure we keep track of the peer call number */
01465          return 1;
01466       }
01467    }
01468    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01469        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01470       /* We're transferring */
01471       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01472          return 1;
01473    }
01474    return 0;
01475 }
01476 
01477 static void update_max_nontrunk(void)
01478 {
01479    int max = 1;
01480    int x;
01481    /* XXX Prolly don't need locks here XXX */
01482    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01483       if (iaxs[x])
01484          max = x + 1;
01485    }
01486    maxnontrunkcall = max;
01487    if (option_debug && iaxdebug)
01488       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01489 }
01490 
01491 static int make_trunk(unsigned short callno, int locked)
01492 {
01493    int x;
01494    int res= 0;
01495    struct timeval now;
01496    if (iaxs[callno]->oseqno) {
01497       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01498       return -1;
01499    }
01500    if (callno & TRUNK_CALL_START) {
01501       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01502       return -1;
01503    }
01504    gettimeofday(&now, NULL);
01505    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01506       ast_mutex_lock(&iaxsl[x]);
01507       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01508          /* Update the two timers that should have been started */
01509          /*!
01510           * \note We delete these before switching the slot, because if
01511           * they fire in the meantime, they will generate a warning.
01512           */
01513          AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01514          AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01515          iaxs[x] = iaxs[callno];
01516          iaxs[x]->callno = x;
01517          iaxs[callno] = NULL;
01518          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01519          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01520          if (locked)
01521             ast_mutex_unlock(&iaxsl[callno]);
01522          res = x;
01523          if (!locked)
01524             ast_mutex_unlock(&iaxsl[x]);
01525          break;
01526       }
01527       ast_mutex_unlock(&iaxsl[x]);
01528    }
01529    if (x >= ARRAY_LEN(iaxs) - 1) {
01530       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01531       return -1;
01532    }
01533    if (option_debug)
01534       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01535    /* We move this call from a non-trunked to a trunked call */
01536    update_max_trunk();
01537    update_max_nontrunk();
01538    return res;
01539 }
01540 
01541 /*!
01542  * \note Calling this function while holding another pvt lock can cause a deadlock.
01543  */
01544 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01545 {
01546    int res = 0;
01547    int x;
01548    struct timeval now;
01549    char host[80];
01550 
01551    if (new <= NEW_ALLOW) {
01552       if (callno) {
01553          struct chan_iax2_pvt *pvt;
01554          struct chan_iax2_pvt tmp_pvt = {
01555             .callno = dcallno,
01556             .peercallno = callno,
01557             /* hack!! */
01558             .frames_received = check_dcallno,
01559          };
01560  
01561          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01562  
01563          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01564             if (return_locked) {
01565                ast_mutex_lock(&iaxsl[pvt->callno]);
01566             }
01567             res = pvt->callno;
01568             ao2_ref(pvt, -1);
01569             pvt = NULL;
01570             return res;
01571          }
01572       }
01573 
01574       /* This will occur on the first response to a message that we initiated,
01575        * such as a PING. */
01576       if (dcallno) {
01577          ast_mutex_lock(&iaxsl[dcallno]);
01578       }
01579       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01580          iaxs[dcallno]->peercallno = callno;
01581          res = dcallno;
01582          store_by_peercallno(iaxs[dcallno]);
01583          if (!res || !return_locked) {
01584             ast_mutex_unlock(&iaxsl[dcallno]);
01585          }
01586          return res;
01587       }
01588       if (dcallno) {
01589          ast_mutex_unlock(&iaxsl[dcallno]);
01590       }
01591 
01592 #ifdef IAX_OLD_FIND
01593       /* If we get here, we SHOULD NOT find a call structure for this
01594          callno; if we do, it means that there is a call structure that
01595          has a peer callno but did NOT get entered into the hash table,
01596          which is bad.
01597 
01598          If we find a call structure using this old, slow method, output a log
01599          message so we'll know about it. After a few months of leaving this in
01600          place, if we don't hear about people seeing these messages, we can
01601          remove this code for good.
01602       */
01603 
01604       for (x = 1; !res && x < maxnontrunkcall; x++) {
01605          ast_mutex_lock(&iaxsl[x]);
01606          if (iaxs[x]) {
01607             /* Look for an exact match */
01608             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01609                res = x;
01610             }
01611          }
01612          if (!res || !return_locked)
01613             ast_mutex_unlock(&iaxsl[x]);
01614       }
01615 
01616       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01617          ast_mutex_lock(&iaxsl[x]);
01618          if (iaxs[x]) {
01619             /* Look for an exact match */
01620             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01621                res = x;
01622             }
01623          }
01624          if (!res || !return_locked)
01625             ast_mutex_unlock(&iaxsl[x]);
01626       }
01627 
01628       if (res) {
01629          ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
01630       }
01631 #endif
01632    }
01633    if (!res && (new >= NEW_ALLOW)) {
01634       int start, found = 0;
01635 
01636       /* It may seem odd that we look through the peer list for a name for
01637        * this *incoming* call.  Well, it is weird.  However, users don't
01638        * have an IP address/port number that we can match against.  So,
01639        * this is just checking for a peer that has that IP/port and
01640        * assuming that we have a user of the same name.  This isn't always
01641        * correct, but it will be changed if needed after authentication. */
01642       if (!iax2_getpeername(*sin, host, sizeof(host)))
01643          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01644 
01645       now = ast_tvnow();
01646       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01647       for (x = start; 1; x++) {
01648          if (x == TRUNK_CALL_START) {
01649             x = 1;
01650             continue;
01651          }
01652 
01653          /* Find first unused call number that hasn't been used in a while */
01654          ast_mutex_lock(&iaxsl[x]);
01655          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01656             found = 1;
01657             break;
01658          }
01659          ast_mutex_unlock(&iaxsl[x]);
01660          
01661          if (x == start - 1) {
01662             break;
01663          }
01664       }
01665       /* We've still got lock held if we found a spot */
01666       if (x == start - 1 && !found) {
01667          ast_log(LOG_WARNING, "No more space\n");
01668          return 0;
01669       }
01670       iaxs[x] = new_iax(sin, host);
01671       update_max_nontrunk();
01672       if (iaxs[x]) {
01673          if (option_debug && iaxdebug)
01674             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01675          iaxs[x]->sockfd = sockfd;
01676          iaxs[x]->addr.sin_port = sin->sin_port;
01677          iaxs[x]->addr.sin_family = sin->sin_family;
01678          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01679          iaxs[x]->peercallno = callno;
01680          iaxs[x]->callno = x;
01681          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01682          iaxs[x]->expiry = min_reg_expire;
01683          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01684          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01685          iaxs[x]->amaflags = amaflags;
01686          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01687          
01688          ast_string_field_set(iaxs[x], accountcode, accountcode);
01689          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01690          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01691 
01692          if (iaxs[x]->peercallno) {
01693             store_by_peercallno(iaxs[x]);
01694          }
01695       } else {
01696          ast_log(LOG_WARNING, "Out of resources\n");
01697          ast_mutex_unlock(&iaxsl[x]);
01698          return 0;
01699       }
01700       if (!return_locked)
01701          ast_mutex_unlock(&iaxsl[x]);
01702       res = x;
01703    }
01704    return res;
01705 }
01706 
01707 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01708 
01709    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01710 }
01711 
01712 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01713 
01714    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01715 }
01716 
01717 /*!
01718  * \brief Queue a frame to a call's owning asterisk channel
01719  *
01720  * \pre This function assumes that iaxsl[callno] is locked when called.
01721  *
01722  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01723  * was valid before calling it, it may no longer be valid after calling it.
01724  * This function may unlock and lock the mutex associated with this callno,
01725  * meaning that another thread may grab it and destroy the call.
01726  */
01727 static int iax2_queue_frame(int callno, struct ast_frame *f)
01728 {
01729    for (;;) {
01730       if (iaxs[callno] && iaxs[callno]->owner) {
01731          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01732             /* Avoid deadlock by pausing and trying again */
01733             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01734          } else {
01735             ast_queue_frame(iaxs[callno]->owner, f);
01736             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01737             break;
01738          }
01739       } else
01740          break;
01741    }
01742    return 0;
01743 }
01744 
01745 /*!
01746  * \brief Queue a hangup frame on the ast_channel owner
01747  *
01748  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01749  * is active for the given call number.
01750  *
01751  * \pre Assumes lock for callno is already held.
01752  *
01753  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01754  * was valid before calling it, it may no longer be valid after calling it.
01755  * This function may unlock and lock the mutex associated with this callno,
01756  * meaning that another thread may grab it and destroy the call.
01757  */
01758 static int iax2_queue_hangup(int callno)
01759 {
01760    for (;;) {
01761       if (iaxs[callno] && iaxs[callno]->owner) {
01762          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01763             /* Avoid deadlock by pausing and trying again */
01764             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01765          } else {
01766             ast_queue_hangup(iaxs[callno]->owner);
01767             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01768             break;
01769          }
01770       } else
01771          break;
01772    }
01773    return 0;
01774 }
01775 
01776 /*!
01777  * \brief Queue a control frame on the ast_channel owner
01778  *
01779  * This function queues a control frame on the owner of the IAX2 pvt struct that
01780  * is active for the given call number.
01781  *
01782  * \pre Assumes lock for callno is already held.
01783  *
01784  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01785  * was valid before calling it, it may no longer be valid after calling it.
01786  * This function may unlock and lock the mutex associated with this callno,
01787  * meaning that another thread may grab it and destroy the call.
01788  */
01789 static int iax2_queue_control_data(int callno, 
01790    enum ast_control_frame_type control, const void *data, size_t datalen)
01791 {
01792    for (;;) {
01793       if (iaxs[callno] && iaxs[callno]->owner) {
01794          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01795             /* Avoid deadlock by pausing and trying again */
01796             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01797          } else {
01798             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01799             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01800             break;
01801          }
01802       } else
01803          break;
01804    }
01805    return 0;
01806 }
01807 static void destroy_firmware(struct iax_firmware *cur)
01808 {
01809    /* Close firmware */
01810    if (cur->fwh) {
01811       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01812    }
01813    close(cur->fd);
01814    free(cur);
01815 }
01816 
01817 static int try_firmware(char *s)
01818 {
01819    struct stat stbuf;
01820    struct iax_firmware *cur;
01821    int ifd;
01822    int fd;
01823    int res;
01824    
01825    struct ast_iax2_firmware_header *fwh, fwh2;
01826    struct MD5Context md5;
01827    unsigned char sum[16];
01828    unsigned char buf[1024];
01829    int len, chunk;
01830    char *s2;
01831    char *last;
01832    s2 = alloca(strlen(s) + 100);
01833    if (!s2) {
01834       ast_log(LOG_WARNING, "Alloca failed!\n");
01835       return -1;
01836    }
01837    last = strrchr(s, '/');
01838    if (last)
01839       last++;
01840    else
01841       last = s;
01842    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01843    res = stat(s, &stbuf);
01844    if (res < 0) {
01845       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01846       return -1;
01847    }
01848    /* Make sure it's not a directory */
01849    if (S_ISDIR(stbuf.st_mode))
01850       return -1;
01851    ifd = open(s, O_RDONLY);
01852    if (ifd < 0) {
01853       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01854       return -1;
01855    }
01856    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01857    if (fd < 0) {
01858       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01859       close(ifd);
01860       return -1;
01861    }
01862    /* Unlink our newly created file */
01863    unlink(s2);
01864    
01865    /* Now copy the firmware into it */
01866    len = stbuf.st_size;
01867    while(len) {
01868       chunk = len;
01869       if (chunk > sizeof(buf))
01870          chunk = sizeof(buf);
01871       res = read(ifd, buf, chunk);
01872       if (res != chunk) {
01873          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01874          close(ifd);
01875          close(fd);
01876          return -1;
01877       }
01878       res = write(fd, buf, chunk);
01879       if (res != chunk) {
01880          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01881          close(ifd);
01882          close(fd);
01883          return -1;
01884       }
01885       len -= chunk;
01886    }
01887    close(ifd);
01888    /* Return to the beginning */
01889    lseek(fd, 0, SEEK_SET);
01890    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01891       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01892       close(fd);
01893       return -1;
01894    }
01895    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01896       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01897       close(fd);
01898       return -1;
01899    }
01900    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01901       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01902       close(fd);
01903       return -1;
01904    }
01905    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01906       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01907       close(fd);
01908       return -1;
01909    }
01910    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01911    if (fwh == (void *) -1) {
01912       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01913       close(fd);
01914       return -1;
01915    }
01916    MD5Init(&md5);
01917    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01918    MD5Final(sum, &md5);
01919    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01920       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01921       munmap((void*)fwh, stbuf.st_size);
01922       close(fd);
01923       return -1;
01924    }
01925    cur = waresl.wares;
01926    while(cur) {
01927       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01928          /* Found a candidate */
01929          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01930             /* The version we have on loaded is older, load this one instead */
01931             break;
01932          /* This version is no newer than what we have.  Don't worry about it.
01933             We'll consider it a proper load anyhow though */
01934          munmap((void*)fwh, stbuf.st_size);
01935          close(fd);
01936          return 0;
01937       }
01938       cur = cur->next;
01939    }
01940    if (!cur) {
01941       /* Allocate a new one and link it */
01942       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01943          cur->fd = -1;
01944          cur->next = waresl.wares;
01945          waresl.wares = cur;
01946       }
01947    }
01948    if (cur) {
01949       if (cur->fwh) {
01950          munmap((void*)cur->fwh, cur->mmaplen);
01951       }
01952       if (cur->fd > -1)
01953          close(cur->fd);
01954       cur->fwh = fwh;
01955       cur->fd = fd;
01956       cur->mmaplen = stbuf.st_size;
01957       cur->dead = 0;
01958    }
01959    return 0;
01960 }
01961 
01962 static int iax_check_version(char *dev)
01963 {
01964    int res = 0;
01965    struct iax_firmware *cur;
01966    if (!ast_strlen_zero(dev)) {
01967       ast_mutex_lock(&waresl.lock);
01968       cur = waresl.wares;
01969       while(cur) {
01970          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01971             res = ntohs(cur->fwh->version);
01972             break;
01973          }
01974          cur = cur->next;
01975       }
01976       ast_mutex_unlock(&waresl.lock);
01977    }
01978    return res;
01979 }
01980 
01981 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01982 {
01983    int res = -1;
01984    unsigned int bs = desc & 0xff;
01985    unsigned int start = (desc >> 8) & 0xffffff;
01986    unsigned int bytes;
01987    struct iax_firmware *cur;
01988    if (!ast_strlen_zero((char *)dev) && bs) {
01989       start *= bs;
01990       ast_mutex_lock(&waresl.lock);
01991       cur = waresl.wares;
01992       while(cur) {
01993          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01994             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01995             if (start < ntohl(cur->fwh->datalen)) {
01996                bytes = ntohl(cur->fwh->datalen) - start;
01997                if (bytes > bs)
01998                   bytes = bs;
01999                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02000             } else {
02001                bytes = 0;
02002                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02003             }
02004             if (bytes == bs)
02005                res = 0;
02006             else
02007                res = 1;
02008             break;
02009          }
02010          cur = cur->next;
02011       }
02012       ast_mutex_unlock(&waresl.lock);
02013    }
02014    return res;
02015 }
02016 
02017 
02018 static void reload_firmware(int unload)
02019 {
02020    struct iax_firmware *cur, *curl, *curp;
02021    DIR *fwd;
02022    struct dirent *de;
02023    char dir[256];
02024    char fn[256];
02025    /* Mark all as dead */
02026    ast_mutex_lock(&waresl.lock);
02027    cur = waresl.wares;
02028    while(cur) {
02029       cur->dead = 1;
02030       cur = cur->next;
02031    }
02032 
02033    /* Now that we've freed them, load the new ones */
02034    if (!unload) {
02035       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02036       fwd = opendir(dir);
02037       if (fwd) {
02038          while((de = readdir(fwd))) {
02039             if (de->d_name[0] != '.') {
02040                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02041                if (!try_firmware(fn)) {
02042                   if (option_verbose > 1)
02043                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02044                }
02045             }
02046          }
02047          closedir(fwd);
02048       } else 
02049          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02050    }
02051 
02052    /* Clean up leftovers */
02053    cur = waresl.wares;
02054    curp = NULL;
02055    while(cur) {
02056       curl = cur;
02057       cur = cur->next;
02058       if (curl->dead) {
02059          if (curp) {
02060             curp->next = cur;
02061          } else {
02062             waresl.wares = cur;
02063          }
02064          destroy_firmware(curl);
02065       } else {
02066          curp = cur;
02067       }
02068    }
02069    ast_mutex_unlock(&waresl.lock);
02070 }
02071 
02072 /*!
02073  * \note This function assumes that iaxsl[callno] is locked when called.
02074  *
02075  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02076  * was valid before calling it, it may no longer be valid after calling it.
02077  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02078  * associated with this callno, meaning that another thread may grab it and destroy the call.
02079  */
02080 static int __do_deliver(void *data)
02081 {
02082    /* Just deliver the packet by using queueing.  This is called by
02083      the IAX thread with the iaxsl lock held. */
02084    struct iax_frame *fr = data;
02085    fr->retrans = -1;
02086    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02087    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02088       iax2_queue_frame(fr->callno, &fr->af);
02089    /* Free our iax frame */
02090    iax2_frame_free(fr);
02091    /* And don't run again */
02092    return 0;
02093 }
02094 
02095 static int handle_error(void)
02096 {
02097    /* XXX Ideally we should figure out why an error occured and then abort those
02098       rather than continuing to try.  Unfortunately, the published interface does
02099       not seem to work XXX */
02100 #if 0
02101    struct sockaddr_in *sin;
02102    int res;
02103    struct msghdr m;
02104    struct sock_extended_err e;
02105    m.msg_name = NULL;
02106    m.msg_namelen = 0;
02107    m.msg_iov = NULL;
02108    m.msg_control = &e;
02109    m.msg_controllen = sizeof(e);
02110    m.msg_flags = 0;
02111    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02112    if (res < 0)
02113       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02114    else {
02115       if (m.msg_controllen) {
02116          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02117          if (sin) 
02118             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02119          else
02120             ast_log(LOG_WARNING, "No address detected??\n");
02121       } else {
02122          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02123       }
02124    }
02125 #endif
02126    return 0;
02127 }
02128 
02129 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02130 {
02131    int res;
02132    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02133                sizeof(*sin));
02134    if (res < 0) {
02135       if (option_debug)
02136          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02137       handle_error();
02138    } else
02139       res = 0;
02140    return res;
02141 }
02142 
02143 static int send_packet(struct iax_frame *f)
02144 {
02145    int res;
02146    int callno = f->callno;
02147 
02148    /* Don't send if there was an error, but return error instead */
02149    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02150        return -1;
02151    
02152    /* Called with iaxsl held */
02153    if (option_debug > 2 && iaxdebug)
02154       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));
02155    if (f->transfer) {
02156       if (iaxdebug)
02157          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02158       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02159                sizeof(iaxs[callno]->transfer));
02160    } else {
02161       if (iaxdebug)
02162          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02163       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02164                sizeof(iaxs[callno]->addr));
02165    }
02166    if (res < 0) {
02167       if (option_debug && iaxdebug)
02168          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02169       handle_error();
02170    } else
02171       res = 0;
02172    return res;
02173 }
02174 
02175 /*!
02176  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02177  *       for the given call number may disappear during its execution.
02178  */
02179 static int iax2_predestroy(int callno)
02180 {
02181    struct ast_channel *c;
02182    struct chan_iax2_pvt *pvt = iaxs[callno];
02183 
02184    if (!pvt)
02185       return -1;
02186    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02187       iax2_destroy_helper(pvt);
02188       ast_set_flag(pvt, IAX_ALREADYGONE); 
02189    }
02190    c = pvt->owner;
02191    if (c) {
02192       c->tech_pvt = NULL;
02193       iax2_queue_hangup(callno);
02194       pvt->owner = NULL;
02195       ast_module_unref(ast_module_info->self);
02196    }
02197    return 0;
02198 }
02199 
02200 static int update_packet(struct iax_frame *f)
02201 {
02202    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02203    struct ast_iax2_full_hdr *fh = f->data;
02204    /* Mark this as a retransmission */
02205    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02206    /* Update iseqno */
02207    f->iseqno = iaxs[f->callno]->iseqno;
02208    fh->iseqno = f->iseqno;
02209    return 0;
02210 }
02211 
02212 static int attempt_transmit(const void *data);
02213 static void __attempt_transmit(const void *data)
02214 {
02215    /* Attempt to transmit the frame to the remote peer...
02216       Called without iaxsl held. */
02217    struct iax_frame *f = (struct iax_frame *)data;
02218    int freeme=0;
02219    int callno = f->callno;
02220    /* Make sure this call is still active */
02221    if (callno) 
02222       ast_mutex_lock(&iaxsl[callno]);
02223    if (callno && iaxs[callno]) {
02224       if ((f->retries < 0) /* Already ACK'd */ ||
02225           (f->retries >= max_retries) /* Too many attempts */) {
02226             /* Record an error if we've transmitted too many times */
02227             if (f->retries >= max_retries) {
02228                if (f->transfer) {
02229                   /* Transfer timeout */
02230                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02231                } else if (f->final) {
02232                   if (f->final) 
02233                      iax2_destroy(callno);
02234                } else {
02235                   if (iaxs[callno]->owner)
02236                      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);
02237                   iaxs[callno]->error = ETIMEDOUT;
02238                   if (iaxs[callno]->owner) {
02239                      struct ast_frame fr = { 0, };
02240                      /* Hangup the fd */
02241                      fr.frametype = AST_FRAME_CONTROL;
02242                      fr.subclass = AST_CONTROL_HANGUP;
02243                      iax2_queue_frame(callno, &fr); // XXX
02244                      /* Remember, owner could disappear */
02245                      if (iaxs[callno] && iaxs[callno]->owner)
02246                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02247                   } else {
02248                      if (iaxs[callno]->reg) {
02249                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02250                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02251                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02252                      }
02253                      iax2_destroy(callno);
02254                   }
02255                }
02256 
02257             }
02258             freeme++;
02259       } else {
02260          /* Update it if it needs it */
02261          update_packet(f);
02262          /* Attempt transmission */
02263          send_packet(f);
02264          f->retries++;
02265          /* Try again later after 10 times as long */
02266          f->retrytime *= 10;
02267          if (f->retrytime > MAX_RETRY_TIME)
02268             f->retrytime = MAX_RETRY_TIME;
02269          /* Transfer messages max out at one second */
02270          if (f->transfer && (f->retrytime > 1000))
02271             f->retrytime = 1000;
02272          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02273       }
02274    } else {
02275       /* Make sure it gets freed */
02276       f->retries = -1;
02277       freeme++;
02278    }
02279    if (callno)
02280       ast_mutex_unlock(&iaxsl[callno]);
02281    /* Do not try again */
02282    if (freeme) {
02283       /* Don't attempt delivery, just remove it from the queue */
02284       AST_LIST_LOCK(&iaxq.queue);
02285       AST_LIST_REMOVE(&iaxq.queue, f, list);
02286       iaxq.count--;
02287       AST_LIST_UNLOCK(&iaxq.queue);
02288       f->retrans = -1;
02289       /* Free the IAX frame */
02290       iax2_frame_free(f);
02291    }
02292 }
02293 
02294 static int attempt_transmit(const void *data)
02295 {
02296 #ifdef SCHED_MULTITHREADED
02297    if (schedule_action(__attempt_transmit, data))
02298 #endif      
02299       __attempt_transmit(data);
02300    return 0;
02301 }
02302 
02303 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02304 {
02305    struct iax2_peer *peer;
02306 
02307    if (argc != 4)
02308         return RESULT_SHOWUSAGE;
02309    if (!strcmp(argv[3],"all")) {
02310       reload_config();
02311       ast_cli(fd, "OK cache is flushed.\n");
02312    } else if ((peer = find_peer(argv[3], 0))) {
02313       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02314          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02315          expire_registry(peer_ref(peer));
02316          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02317       } else {
02318          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02319       }
02320       peer_unref(peer);
02321    } else {
02322       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02323    }
02324    
02325    return RESULT_SUCCESS;
02326 }
02327 
02328 static int iax2_test_losspct(int fd, int argc, char *argv[])
02329 {
02330        if (argc != 4)
02331                return RESULT_SHOWUSAGE;
02332 
02333        test_losspct = atoi(argv[3]);
02334 
02335        return RESULT_SUCCESS;
02336 }
02337 
02338 #ifdef IAXTESTS
02339 static int iax2_test_late(int fd, int argc, char *argv[])
02340 {
02341    if (argc != 4)
02342       return RESULT_SHOWUSAGE;
02343 
02344    test_late = atoi(argv[3]);
02345 
02346    return RESULT_SUCCESS;
02347 }
02348 
02349 static int iax2_test_resync(int fd, int argc, char *argv[])
02350 {
02351    if (argc != 4)
02352       return RESULT_SHOWUSAGE;
02353 
02354    test_resync = atoi(argv[3]);
02355 
02356    return RESULT_SUCCESS;
02357 }
02358 
02359 static int iax2_test_jitter(int fd, int argc, char *argv[])
02360 {
02361    if (argc < 4 || argc > 5)
02362       return RESULT_SHOWUSAGE;
02363 
02364    test_jit = atoi(argv[3]);
02365    if (argc == 5) 
02366       test_jitpct = atoi(argv[4]);
02367 
02368    return RESULT_SUCCESS;
02369 }
02370 #endif /* IAXTESTS */
02371 
02372 /*! \brief  peer_status: Report Peer status in character string */
02373 /*    returns 1 if peer is online, -1 if unmonitored */
02374 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02375 {
02376    int res = 0;
02377    if (peer->maxms) {
02378       if (peer->lastms < 0) {
02379          ast_copy_string(status, "UNREACHABLE", statuslen);
02380       } else if (peer->lastms > peer->maxms) {
02381          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02382          res = 1;
02383       } else if (peer->lastms) {
02384          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02385          res = 1;
02386       } else {
02387          ast_copy_string(status, "UNKNOWN", statuslen);
02388       }
02389    } else { 
02390       ast_copy_string(status, "Unmonitored", statuslen);
02391       res = -1;
02392    }
02393    return res;
02394 }
02395 
02396 /*! \brief Show one peer in detail */
02397 static int iax2_show_peer(int fd, int argc, char *argv[])
02398 {
02399    char status[30];
02400    char cbuf[256];
02401    struct iax2_peer *peer;
02402    char codec_buf[512];
02403    int x = 0, codec = 0, load_realtime = 0;
02404 
02405    if (argc < 4)
02406       return RESULT_SHOWUSAGE;
02407 
02408    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02409 
02410    peer = find_peer(argv[3], load_realtime);
02411    if (peer) {
02412       ast_cli(fd,"\n\n");
02413       ast_cli(fd, "  * Name       : %s\n", peer->name);
02414       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02415       ast_cli(fd, "  Context      : %s\n", peer->context);
02416       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02417       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02418       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02419       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02420       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02421       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));
02422       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02423       ast_cli(fd, "  Username     : %s\n", peer->username);
02424       ast_cli(fd, "  Codecs       : ");
02425       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02426       ast_cli(fd, "%s\n", codec_buf);
02427 
02428       ast_cli(fd, "  Codec Order  : (");
02429       for(x = 0; x < 32 ; x++) {
02430          codec = ast_codec_pref_index(&peer->prefs,x);
02431          if(!codec)
02432             break;
02433          ast_cli(fd, "%s", ast_getformatname(codec));
02434          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02435             ast_cli(fd, "|");
02436       }
02437 
02438       if (!x)
02439          ast_cli(fd, "none");
02440       ast_cli(fd, ")\n");
02441 
02442       ast_cli(fd, "  Status       : ");
02443       peer_status(peer, status, sizeof(status));   
02444       ast_cli(fd, "%s\n",status);
02445       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02446       ast_cli(fd,"\n");
02447       peer_unref(peer);
02448    } else {
02449       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02450       ast_cli(fd,"\n");
02451    }
02452 
02453    return RESULT_SUCCESS;
02454 }
02455 
02456 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02457 {
02458    int which = 0;
02459    struct iax2_peer *peer;
02460    char *res = NULL;
02461    int wordlen = strlen(word);
02462    struct ao2_iterator i;
02463 
02464    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02465    if (pos != 3)
02466       return NULL;
02467 
02468    i = ao2_iterator_init(peers, 0);
02469    while ((peer = ao2_iterator_next(&i))) {
02470       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02471          res = ast_strdup(peer->name);
02472          peer_unref(peer);
02473          break;
02474       }
02475       peer_unref(peer);
02476    }
02477 
02478    return res;
02479 }
02480 
02481 static int iax2_show_stats(int fd, int argc, char *argv[])
02482 {
02483    struct iax_frame *cur;
02484    int cnt = 0, dead=0, final=0;
02485 
02486    if (argc != 3)
02487       return RESULT_SHOWUSAGE;
02488 
02489    AST_LIST_LOCK(&iaxq.queue);
02490    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02491       if (cur->retries < 0)
02492          dead++;
02493       if (cur->final)
02494          final++;
02495       cnt++;
02496    }
02497    AST_LIST_UNLOCK(&iaxq.queue);
02498 
02499    ast_cli(fd, "    IAX Statistics\n");
02500    ast_cli(fd, "---------------------\n");
02501    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02502    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02503    
02504    return RESULT_SUCCESS;
02505 }
02506 
02507 static int iax2_show_cache(int fd, int argc, char *argv[])
02508 {
02509    struct iax2_dpcache *dp;
02510    char tmp[1024], *pc;
02511    int s;
02512    int x,y;
02513    struct timeval tv;
02514    gettimeofday(&tv, NULL);
02515    ast_mutex_lock(&dpcache_lock);
02516    dp = dpcache;
02517    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02518    while(dp) {
02519       s = dp->expiry.tv_sec - tv.tv_sec;
02520       tmp[0] = '\0';
02521       if (dp->flags & CACHE_FLAG_EXISTS)
02522          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02523       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02524          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02525       if (dp->flags & CACHE_FLAG_CANEXIST)
02526          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02527       if (dp->flags & CACHE_FLAG_PENDING)
02528          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02529       if (dp->flags & CACHE_FLAG_TIMEOUT)
02530          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02531       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02532          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02533       if (dp->flags & CACHE_FLAG_MATCHMORE)
02534          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02535       if (dp->flags & CACHE_FLAG_UNKNOWN)
02536          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02537       /* Trim trailing pipe */
02538       if (!ast_strlen_zero(tmp))
02539          tmp[strlen(tmp) - 1] = '\0';
02540       else
02541          ast_copy_string(tmp, "(none)", sizeof(tmp));
02542       y=0;
02543       pc = strchr(dp->peercontext, '@');
02544       if (!pc)
02545          pc = dp->peercontext;
02546       else
02547          pc++;
02548       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02549          if (dp->waiters[x] > -1)
02550             y++;
02551       if (s > 0)
02552          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02553       else
02554          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02555       dp = dp->next;
02556    }
02557    ast_mutex_unlock(&dpcache_lock);
02558    return RESULT_SUCCESS;
02559 }
02560 
02561 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02562 
02563 static void unwrap_timestamp(struct iax_frame *fr)
02564 {
02565    /* Video mini frames only encode the lower 15 bits of the session
02566     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
02567    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02568    const int lower_mask = (1 << ts_shift) - 1;
02569    const int upper_mask = ~lower_mask;
02570    const int last_upper = iaxs[fr->callno]->last & upper_mask;
02571 
02572    if ( (fr->ts & upper_mask) == last_upper ) {
02573       const int x = fr->ts - iaxs[fr->callno]->last;
02574       const int threshold = (ts_shift == 15) ? 25000 : 50000;
02575 
02576       if (x < -threshold) {
02577          /* Sudden big jump backwards in timestamp:
02578             What likely happened here is that miniframe timestamp has circled but we haven't
02579             gotten the update from the main packet.  We'll just pretend that we did, and
02580             update the timestamp appropriately. */
02581          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02582          if (option_debug && iaxdebug)
02583             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02584       } else if (x > threshold) {
02585          /* Sudden apparent big jump forwards in timestamp:
02586             What's likely happened is this is an old miniframe belonging to the previous
02587             top 15 or 16-bit timestamp that has turned up out of order.
02588             Adjust the timestamp appropriately. */
02589          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02590          if (option_debug && iaxdebug)
02591             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02592       }
02593    }
02594 }
02595 
02596 static int get_from_jb(const void *p);
02597 
02598 static void update_jbsched(struct chan_iax2_pvt *pvt)
02599 {
02600    int when;
02601    
02602    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02603    
02604    when = jb_next(pvt->jb) - when;
02605 
02606    AST_SCHED_DEL(sched, pvt->jbid);
02607 
02608    if(when <= 0) {
02609       /* XXX should really just empty until when > 0.. */
02610       when = 1;
02611    }
02612    
02613    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02614 }
02615 
02616 static void __get_from_jb(const void *p) 
02617 {
02618    int callno = PTR_TO_CALLNO(p);
02619    struct chan_iax2_pvt *pvt = NULL;
02620    struct iax_frame *fr;
02621    jb_frame frame;
02622    int ret;
02623    long now;
02624    long next;
02625    struct timeval tv;
02626    
02627    /* Make sure we have a valid private structure before going on */
02628    ast_mutex_lock(&iaxsl[callno]);
02629    pvt = iaxs[callno];
02630    if (!pvt) {
02631       /* No go! */
02632       ast_mutex_unlock(&iaxsl[callno]);
02633       return;
02634    }
02635 
02636    pvt->jbid = -1;
02637    
02638    gettimeofday(&tv,NULL);
02639    /* round up a millisecond since ast_sched_runq does; */
02640    /* prevents us from spinning while waiting for our now */
02641    /* to catch up with runq's now */
02642    tv.tv_usec += 1000;
02643    
02644    now = ast_tvdiff_ms(tv, pvt->rxcore);
02645    
02646    if(now >= (next = jb_next(pvt->jb))) {
02647       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02648       switch(ret) {
02649       case JB_OK:
02650          fr = frame.data;
02651          __do_deliver(fr);
02652          /* __do_deliver() can cause the call to disappear */
02653          pvt = iaxs[callno];
02654          break;
02655       case JB_INTERP:
02656       {
02657          struct ast_frame af = { 0, };
02658          
02659          /* create an interpolation frame */
02660          af.frametype = AST_FRAME_VOICE;
02661          af.subclass = pvt->voiceformat;
02662          af.samples  = frame.ms * 8;
02663          af.src  = "IAX2 JB interpolation";
02664          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02665          af.offset = AST_FRIENDLY_OFFSET;
02666          
02667          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02668           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02669          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02670             iax2_queue_frame(callno, &af);
02671             /* iax2_queue_frame() could cause the call to disappear */
02672             pvt = iaxs[callno];
02673          }
02674       }
02675          break;
02676       case JB_DROP:
02677          iax2_frame_free(frame.data);
02678          break;
02679       case JB_NOFRAME:
02680       case JB_EMPTY:
02681          /* do nothing */
02682          break;
02683       default:
02684          /* shouldn't happen */
02685          break;
02686       }
02687    }
02688    if (pvt)
02689       update_jbsched(pvt);
02690    ast_mutex_unlock(&iaxsl[callno]);
02691 }
02692 
02693 static int get_from_jb(const void *data)
02694 {
02695 #ifdef SCHED_MULTITHREADED
02696    if (schedule_action(__get_from_jb, data))
02697 #endif      
02698       __get_from_jb(data);
02699    return 0;
02700 }
02701 
02702 /*!
02703  * \note This function assumes fr->callno is locked
02704  *
02705  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02706  * was valid before calling it, it may no longer be valid after calling it.
02707  */
02708 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02709 {
02710    int type, len;
02711    int ret;
02712    int needfree = 0;
02713    struct ast_channel *owner = NULL;
02714    struct ast_channel *bridge = NULL;
02715    
02716    /* Attempt to recover wrapped timestamps */
02717    unwrap_timestamp(fr);
02718 
02719    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02720    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02721       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02722    else {
02723 #if 0
02724       if (option_debug)
02725          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02726 #endif
02727       fr->af.delivery = ast_tv(0,0);
02728    }
02729 
02730    type = JB_TYPE_CONTROL;
02731    len = 0;
02732 
02733    if(fr->af.frametype == AST_FRAME_VOICE) {
02734       type = JB_TYPE_VOICE;
02735       len = ast_codec_get_samples(&fr->af) / 8;
02736    } else if(fr->af.frametype == AST_FRAME_CNG) {
02737       type = JB_TYPE_SILENCE;
02738    }
02739 
02740    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02741       if (tsout)
02742          *tsout = fr->ts;
02743       __do_deliver(fr);
02744       return -1;
02745    }
02746 
02747    if ((owner = iaxs[fr->callno]->owner))
02748       bridge = ast_bridged_channel(owner);
02749 
02750    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02751     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02752    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02753       jb_frame frame;
02754 
02755       /* deliver any frames in the jb */
02756       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02757          __do_deliver(frame.data);
02758          /* __do_deliver() can make the call disappear */
02759          if (!iaxs[fr->callno])
02760             return -1;
02761       }
02762 
02763       jb_reset(iaxs[fr->callno]->jb);
02764 
02765       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02766 
02767       /* deliver this frame now */
02768       if (tsout)
02769          *tsout = fr->ts;
02770       __do_deliver(fr);
02771       return -1;
02772    }
02773 
02774    /* insert into jitterbuffer */
02775    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02776    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02777          calc_rxstamp(iaxs[fr->callno],fr->ts));
02778    if (ret == JB_DROP) {
02779       needfree++;
02780    } else if (ret == JB_SCHED) {
02781       update_jbsched(iaxs[fr->callno]);
02782    }
02783    if (tsout)
02784       *tsout = fr->ts;
02785    if (needfree) {
02786       /* Free our iax frame */
02787       iax2_frame_free(fr);
02788       return -1;
02789    }
02790    return 0;
02791 }
02792 
02793 static int iax2_transmit(struct iax_frame *fr)
02794 {
02795    /* Lock the queue and place this packet at the end */
02796    /* By setting this to 0, the network thread will send it for us, and
02797       queue retransmission if necessary */
02798    fr->sentyet = 0;
02799    AST_LIST_LOCK(&iaxq.queue);
02800    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02801    iaxq.count++;
02802    AST_LIST_UNLOCK(&iaxq.queue);
02803    /* Wake up the network and scheduler thread */
02804    if (netthreadid != AST_PTHREADT_NULL)
02805       pthread_kill(netthreadid, SIGURG);
02806    signal_condition(&sched_lock, &sched_cond);
02807    return 0;
02808 }
02809 
02810 
02811 
02812 static int iax2_digit_begin(struct ast_channel *c, char digit)
02813 {
02814    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02815 }
02816 
02817 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02818 {
02819    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02820 }
02821 
02822 static int iax2_sendtext(struct ast_channel *c, const char *text)
02823 {
02824    
02825    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02826       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02827 }
02828 
02829 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02830 {
02831    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02832 }
02833 
02834 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02835 {
02836    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02837 }
02838 
02839 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02840 {
02841    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02842    ast_mutex_lock(&iaxsl[callno]);
02843    if (iaxs[callno])
02844       iaxs[callno]->owner = newchan;
02845    else
02846       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02847    ast_mutex_unlock(&iaxsl[callno]);
02848    return 0;
02849 }
02850 
02851 /*!
02852  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02853  *       so do not call this with a pvt lock held.
02854  */
02855 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02856 {
02857    struct ast_variable *var = NULL;
02858    struct ast_variable *tmp;
02859    struct iax2_peer *peer=NULL;
02860    time_t regseconds = 0, nowtime;
02861    int dynamic=0;
02862 
02863    if (peername) {
02864       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02865       if (!var && sin)
02866          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02867    } else if (sin) {
02868       char porta[25];
02869       sprintf(porta, "%d", ntohs(sin->sin_port));
02870       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02871       if (var) {
02872          /* We'll need the peer name in order to build the structure! */
02873          for (tmp = var; tmp; tmp = tmp->next) {
02874             if (!strcasecmp(tmp->name, "name"))
02875                peername = tmp->value;
02876          }
02877       }
02878    }
02879    if (!var && peername) { /* Last ditch effort */
02880       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02881       /*!\note
02882        * If this one loaded something, then we need to ensure that the host
02883        * field matched.  The only reason why we can't have this as a criteria
02884        * is because we only have the IP address and the host field might be
02885        * set as a name (and the reverse PTR might not match).
02886        */
02887       if (var && sin) {
02888          for (tmp = var; tmp; tmp = tmp->next) {
02889             if (!strcasecmp(tmp->name, "host")) {
02890                struct ast_hostent ahp;
02891                struct hostent *hp;
02892                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02893                   /* No match */
02894                   ast_variables_destroy(var);
02895                   var = NULL;
02896                }
02897                break;
02898             }
02899          }
02900       }
02901    }
02902    if (!var)
02903       return NULL;
02904 
02905    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02906    
02907    if (!peer) {
02908       ast_variables_destroy(var);
02909       return NULL;
02910    }
02911 
02912    for (tmp = var; tmp; tmp = tmp->next) {
02913       /* Make sure it's not a user only... */
02914       if (!strcasecmp(tmp->name, "type")) {
02915          if (strcasecmp(tmp->value, "friend") &&
02916              strcasecmp(tmp->value, "peer")) {
02917             /* Whoops, we weren't supposed to exist! */
02918             peer = peer_unref(peer);
02919             break;
02920          } 
02921       } else if (!strcasecmp(tmp->name, "regseconds")) {
02922          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02923       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02924          inet_aton(tmp->value, &(peer->addr.sin_addr));
02925       } else if (!strcasecmp(tmp->name, "port")) {
02926          peer->addr.sin_port = htons(atoi(tmp->value));
02927       } else if (!strcasecmp(tmp->name, "host")) {
02928          if (!strcasecmp(tmp->value, "dynamic"))
02929             dynamic = 1;
02930       }
02931    }
02932 
02933    ast_variables_destroy(var);
02934 
02935    if (!peer)
02936       return NULL;
02937 
02938    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02939       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02940       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02941          if (peer->expire > -1) {
02942             if (!ast_sched_del(sched, peer->expire)) {
02943                peer->expire = -1;
02944                peer_unref(peer);
02945             }
02946          }
02947          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02948          if (peer->expire == -1)
02949             peer_unref(peer);
02950       }
02951       ao2_link(peers, peer);
02952       if (ast_test_flag(peer, IAX_DYNAMIC))
02953          reg_source_db(peer);
02954    } else {
02955       ast_set_flag(peer, IAX_TEMPONLY);   
02956    }
02957 
02958    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02959       time(&nowtime);
02960       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02961          memset(&peer->addr, 0, sizeof(peer->addr));
02962          realtime_update_peer(peer->name, &peer->addr, 0);
02963          if (option_debug)
02964             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02965                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02966       }
02967       else {
02968          if (option_debug)
02969             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02970                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02971       }
02972    }
02973 
02974    return peer;
02975 }
02976 
02977 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02978 {
02979    struct ast_variable *var;
02980    struct ast_variable *tmp;
02981    struct iax2_user *user=NULL;
02982 
02983    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02984    if (!var)
02985       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02986    if (!var && sin) {
02987       char porta[6];
02988       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02989       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02990       if (!var)
02991          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02992    }
02993    if (!var) { /* Last ditch effort */
02994       var = ast_load_realtime("iaxusers", "name", username, NULL);
02995       /*!\note
02996        * If this one loaded something, then we need to ensure that the host
02997        * field matched.  The only reason why we can't have this as a criteria
02998        * is because we only have the IP address and the host field might be
02999        * set as a name (and the reverse PTR might not match).
03000        */
03001       if (var) {
03002          for (tmp = var; tmp; tmp = tmp->next) {
03003             if (!strcasecmp(tmp->name, "host")) {
03004                struct ast_hostent ahp;
03005                struct hostent *hp;
03006                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03007                   /* No match */
03008                   ast_variables_destroy(var);
03009                   var = NULL;
03010                }
03011                break;
03012             }
03013          }
03014       }
03015    }
03016    if (!var)
03017       return NULL;
03018 
03019    tmp = var;
03020    while(tmp) {
03021       /* Make sure it's not a peer only... */
03022       if (!strcasecmp(tmp->name, "type")) {
03023          if (strcasecmp(tmp->value, "friend") &&
03024              strcasecmp(tmp->value, "user")) {
03025             return NULL;
03026          } 
03027       }
03028       tmp = tmp->next;
03029    }
03030 
03031    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03032 
03033    ast_variables_destroy(var);
03034 
03035    if (!user)
03036       return NULL;
03037 
03038    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03039       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03040       ao2_link(users, user);
03041    } else {
03042       ast_set_flag(user, IAX_TEMPONLY);   
03043    }
03044 
03045    return user;
03046 }
03047 
03048 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03049 {
03050    char port[10];
03051    char regseconds[20];
03052    
03053    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03054    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03055    ast_update_realtime("iaxpeers", "name", peername, 
03056       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03057       "regseconds", regseconds, NULL);
03058 }
03059 
03060 struct create_addr_info {
03061    int capability;
03062    unsigned int flags;
03063    int maxtime;
03064    int encmethods;
03065    int found;
03066    int sockfd;
03067    int adsi;
03068    char username[80];
03069    char secret[80];
03070    char outkey[80];
03071    char timezone[80];
03072    char prefs[32];
03073    char context[AST_MAX_CONTEXT];
03074    char peercontext[AST_MAX_CONTEXT];
03075    char mohinterpret[MAX_MUSICCLASS];
03076    char mohsuggest[MAX_MUSICCLASS];
03077 };
03078 
03079 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03080 {
03081    struct ast_hostent ahp;
03082    struct hostent *hp;
03083    struct iax2_peer *peer;
03084    int res = -1;
03085    struct ast_codec_pref ourprefs;
03086 
03087    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03088    cai->sockfd = defaultsockfd;
03089    cai->maxtime = 0;
03090    sin->sin_family = AF_INET;
03091 
03092    if (!(peer = find_peer(peername, 1))) {
03093       cai->found = 0;
03094 
03095       hp = ast_gethostbyname(peername, &ahp);
03096       if (hp) {
03097          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03098          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03099          /* use global iax prefs for unknown peer/user */
03100          /* But move the calling channel's native codec to the top of the preference list */
03101          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03102          if (c)
03103             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03104          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03105          return 0;
03106       } else {
03107          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03108          return -1;
03109       }
03110    }
03111 
03112    cai->found = 1;
03113    
03114    /* if the peer has no address (current or default), return failure */
03115    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03116       goto return_unref;
03117 
03118    /* if the peer is being monitored and is currently unreachable, return failure */
03119    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03120       goto return_unref;
03121 
03122    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03123    cai->maxtime = peer->maxms;
03124    cai->capability = peer->capability;
03125    cai->encmethods = peer->encmethods;
03126    cai->sockfd = peer->sockfd;
03127    cai->adsi = peer->adsi;
03128    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03129    /* Move the calling channel's native codec to the top of the preference list */
03130    if (c) {
03131       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03132       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03133    }
03134    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03135    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03136    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03137    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03138    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03139    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03140    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03141    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03142    if (ast_strlen_zero(peer->dbsecret)) {
03143       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03144    } else {
03145       char *family;
03146       char *key = NULL;
03147 
03148       family = ast_strdupa(peer->dbsecret);
03149       key = strchr(family, '/');
03150       if (key)
03151          *key++ = '\0';
03152       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03153          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03154          goto return_unref;
03155       }
03156    }
03157 
03158    if (peer->addr.sin_addr.s_addr) {
03159       sin->sin_addr = peer->addr.sin_addr;
03160       sin->sin_port = peer->addr.sin_port;
03161    } else {
03162       sin->sin_addr = peer->defaddr.sin_addr;
03163       sin->sin_port = peer->defaddr.sin_port;
03164    }
03165 
03166    res = 0;
03167 
03168 return_unref:
03169    peer_unref(peer);
03170 
03171    return res;
03172 }
03173 
03174 static void __auto_congest(const void *nothing)
03175 {
03176    int callno = PTR_TO_CALLNO(nothing);
03177    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03178    ast_mutex_lock(&iaxsl[callno]);
03179    if (iaxs[callno]) {
03180       iaxs[callno]->initid = -1;
03181       iax2_queue_frame(callno, &f);
03182       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03183    }
03184    ast_mutex_unlock(&iaxsl[callno]);
03185 }
03186 
03187 static int auto_congest(const void *data)
03188 {
03189 #ifdef SCHED_MULTITHREADED
03190    if (schedule_action(__auto_congest, data))
03191 #endif      
03192       __auto_congest(data);
03193    return 0;
03194 }
03195 
03196 static unsigned int iax2_datetime(const char *tz)
03197 {
03198    time_t t;
03199    struct tm tm;
03200    unsigned int tmp;
03201    time(&t);
03202    if (!ast_strlen_zero(tz))
03203       ast_localtime(&t, &tm, tz);
03204    else
03205       ast_localtime(&t, &tm, NULL);
03206    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03207    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03208    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03209    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03210    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03211    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03212    return tmp;
03213 }
03214 
03215 struct parsed_dial_string {
03216    char *username;
03217    char *password;
03218    char *key;
03219    char *peer;
03220    char *port;
03221    char *exten;
03222    char *context;
03223    char *options;
03224 };
03225 
03226 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03227 {
03228    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03229       .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03230       .csub = compress_subclass(command) };
03231 
03232    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03233 }
03234 
03235 /*!
03236  * \brief Parses an IAX dial string into its component parts.
03237  * \param data the string to be parsed
03238  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03239  * \return nothing
03240  *
03241  * This function parses the string and fills the structure
03242  * with pointers to its component parts. The input string
03243  * will be modified.
03244  *
03245  * \note This function supports both plaintext passwords and RSA
03246  * key names; if the password string is formatted as '[keyname]',
03247  * then the keyname will be placed into the key field, and the
03248  * password field will be set to NULL.
03249  *
03250  * \note The dial string format is:
03251  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03252  */
03253 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03254 {
03255    if (ast_strlen_zero(data))
03256       return;
03257 
03258    pds->peer = strsep(&data, "/");
03259    pds->exten = strsep(&data, "/");
03260    pds->options = data;
03261 
03262    if (pds->exten) {
03263       data = pds->exten;
03264       pds->exten = strsep(&data, "@");
03265       pds->context = data;
03266    }
03267 
03268    if (strchr(pds->peer, '@')) {
03269       data = pds->peer;
03270       pds->username = strsep(&data, "@");
03271       pds->peer = data;
03272    }
03273 
03274    if (pds->username) {
03275       data = pds->username;
03276       pds->username = strsep(&data, ":");
03277       pds->password = data;
03278    }
03279 
03280    data = pds->peer;
03281    pds->peer = strsep(&data, ":");
03282    pds->port = data;
03283 
03284    /* check for a key name wrapped in [] in the secret position, if found,
03285       move it to the key field instead
03286    */
03287    if (pds->password && (pds->password[0] == '[')) {
03288       pds->key = ast_strip_quoted(pds->password, "[", "]");
03289       pds->password = NULL;
03290    }
03291 }
03292 
03293 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03294 {
03295    struct sockaddr_in sin;
03296    char *l=NULL, *n=NULL, *tmpstr;
03297    struct iax_ie_data ied;
03298    char *defaultrdest = "s";
03299    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03300    struct parsed_dial_string pds;
03301    struct create_addr_info cai;
03302 
03303    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03304       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03305       return -1;
03306    }
03307 
03308    memset(&cai, 0, sizeof(cai));
03309    cai.encmethods = iax2_encryption;
03310 
03311    memset(&pds, 0, sizeof(pds));
03312    tmpstr = ast_strdupa(dest);
03313    parse_dial_string(tmpstr, &pds);
03314 
03315    if (ast_strlen_zero(pds.peer)) {
03316       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03317       return -1;
03318    }
03319 
03320    if (!pds.exten) {
03321       pds.exten = defaultrdest;
03322    }
03323 
03324    if (create_addr(pds.peer, c, &sin, &cai)) {
03325       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03326       return -1;
03327    }
03328 
03329    if (!pds.username && !ast_strlen_zero(cai.username))
03330       pds.username = cai.username;
03331    if (!pds.password && !ast_strlen_zero(cai.secret))
03332       pds.password = cai.secret;
03333    if (!pds.key && !ast_strlen_zero(cai.outkey))
03334       pds.key = cai.outkey;
03335    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03336       pds.context = cai.peercontext;
03337 
03338    /* Keep track of the context for outgoing calls too */
03339    ast_copy_string(c->context, cai.context, sizeof(c->context));
03340 
03341    if (pds.port)
03342       sin.sin_port = htons(atoi(pds.port));
03343 
03344    l = c->cid.cid_num;
03345    n = c->cid.cid_name;
03346 
03347    /* Now build request */ 
03348    memset(&ied, 0, sizeof(ied));
03349 
03350    /* On new call, first IE MUST be IAX version of caller */
03351    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03352    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03353    if (pds.options && strchr(pds.options, 'a')) {
03354       /* Request auto answer */
03355       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03356    }
03357 
03358    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03359 
03360    if (l) {
03361       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03362       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03363    } else {
03364       if (n)
03365          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03366       else
03367          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03368    }
03369 
03370    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03371    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03372 
03373    if (n)
03374       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03375    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03376       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03377 
03378    if (!ast_strlen_zero(c->language))
03379       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03380    if (!ast_strlen_zero(c->cid.cid_dnid))
03381       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03382    if (!ast_strlen_zero(c->cid.cid_rdnis))
03383       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03384 
03385    if (pds.context)
03386       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03387 
03388    if (pds.username)
03389       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03390 
03391    if (cai.encmethods)
03392       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03393 
03394    ast_mutex_lock(&iaxsl[callno]);
03395 
03396    if (!ast_strlen_zero(c->context))
03397       ast_string_field_set(iaxs[callno], context, c->context);
03398 
03399    if (pds.username)
03400       ast_string_field_set(iaxs[callno], username, pds.username);
03401 
03402    iaxs[callno]->encmethods = cai.encmethods;
03403 
03404    iaxs[callno]->adsi = cai.adsi;
03405    
03406    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03407    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03408 
03409    if (pds.key)
03410       ast_string_field_set(iaxs[callno], outkey, pds.key);
03411    if (pds.password)
03412       ast_string_field_set(iaxs[callno], secret, pds.password);
03413 
03414    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03415    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03416    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03417    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03418 
03419    if (iaxs[callno]->maxtime) {
03420       /* Initialize pingtime and auto-congest time */
03421       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03422       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03423    } else if (autokill) {
03424       iaxs[callno]->pingtime = autokill / 2;
03425       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03426    }
03427 
03428    /* send the command using the appropriate socket for this peer */
03429    iaxs[callno]->sockfd = cai.sockfd;
03430 
03431    /* Transmit the string in a "NEW" request */
03432    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03433 
03434    ast_mutex_unlock(&iaxsl[callno]);
03435    ast_setstate(c, AST_STATE_RINGING);
03436    
03437    return 0;
03438 }
03439 
03440 static int iax2_hangup(struct ast_channel *c) 
03441 {
03442    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03443    struct iax_ie_data ied;
03444    int alreadygone;
03445    memset(&ied, 0, sizeof(ied));
03446    ast_mutex_lock(&iaxsl[callno]);
03447    if (callno && iaxs[callno]) {
03448       if (option_debug)
03449          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03450       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03451       /* Send the hangup unless we have had a transmission error or are already gone */
03452       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03453       if (!iaxs[callno]->error && !alreadygone) {
03454          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03455             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03456          }
03457          if (!iaxs[callno]) {
03458             ast_mutex_unlock(&iaxsl[callno]);
03459             return 0;
03460          }
03461       }
03462       /* Explicitly predestroy it */
03463       iax2_predestroy(callno);
03464       /* If we were already gone to begin with, destroy us now */
03465       if (iaxs[callno] && alreadygone) {
03466          if (option_debug)
03467             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03468          iax2_destroy(callno);
03469       } else if (iaxs[callno]) {
03470          ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
03471       }
03472    } else if (c->tech_pvt) {
03473       /* If this call no longer exists, but the channel still
03474        * references it we need to set the channel's tech_pvt to null
03475        * to avoid ast_channel_free() trying to free it.
03476        */
03477       c->tech_pvt = NULL;
03478    }
03479    ast_mutex_unlock(&iaxsl[callno]);
03480    if (option_verbose > 2) 
03481       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03482    return 0;
03483 }
03484 
03485 /*!
03486  * \note expects the pvt to be locked
03487  */
03488 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03489 {
03490    unsigned short callno = pvt->callno;
03491 
03492    if (!pvt->peercallno) {
03493       /* We don't know the remote side's call number, yet.  :( */
03494       int count = 10;
03495       while (count-- && pvt && !pvt->peercallno) {
03496          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03497          pvt = iaxs[callno];
03498       }
03499       if (!pvt->peercallno) {
03500          return -1;
03501       }
03502    }
03503 
03504    return 0;
03505 }
03506 
03507 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03508 {
03509    struct ast_option_header *h;
03510    int res;
03511 
03512    switch (option) {
03513    case AST_OPTION_TXGAIN:
03514    case AST_OPTION_RXGAIN:
03515       /* these two cannot be sent, because they require a result */
03516       errno = ENOSYS;
03517       return -1;
03518    default:
03519    {
03520       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03521       struct chan_iax2_pvt *pvt;
03522 
03523       ast_mutex_lock(&iaxsl[callno]);
03524       pvt = iaxs[callno];
03525 
03526       if (wait_for_peercallno(pvt)) {
03527          ast_mutex_unlock(&iaxsl[callno]);
03528          return -1;
03529       }
03530 
03531       ast_mutex_unlock(&iaxsl[callno]);
03532 
03533       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03534          return -1;
03535       }
03536 
03537       h->flag = AST_OPTION_FLAG_REQUEST;
03538       h->option = htons(option);
03539       memcpy(h->data, data, datalen);
03540       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03541                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03542                  datalen + sizeof(*h), -1);
03543       free(h);
03544       return res;
03545    }
03546    }
03547 }
03548 
03549 static struct ast_frame *iax2_read(struct ast_channel *c) 
03550 {
03551    ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
03552    return NULL;
03553 }
03554 
03555 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03556 {
03557    int res;
03558    struct iax_ie_data ied0;
03559    struct iax_ie_data ied1;
03560    unsigned int transferid = (unsigned int)ast_random();
03561    memset(&ied0, 0, sizeof(ied0));
03562    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03563    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03564    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03565 
03566    memset(&ied1, 0, sizeof(ied1));
03567    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03568    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03569    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03570    
03571    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03572    if (res)
03573       return -1;
03574    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03575    if (res)
03576       return -1;
03577    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03578    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03579    return 0;
03580 }
03581 
03582 static void lock_both(unsigned short callno0, unsigned short callno1)
03583 {
03584    ast_mutex_lock(&iaxsl[callno0]);
03585    while (ast_mutex_trylock(&iaxsl[callno1])) {
03586       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03587    }
03588 }
03589 
03590 static void unlock_both(unsigned short callno0, unsigned short callno1)
03591 {
03592    ast_mutex_unlock(&iaxsl[callno1]);
03593    ast_mutex_unlock(&iaxsl[callno0]);
03594 }
03595 
03596 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)
03597 {
03598    struct ast_channel *cs[3];
03599    struct ast_channel *who, *other;
03600    int to = -1;
03601    int res = -1;
03602    int transferstarted=0;
03603    struct ast_frame *f;
03604    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03605    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03606    struct timeval waittimer = {0, 0}, tv;
03607 
03608    lock_both(callno0, callno1);
03609    if (!iaxs[callno0] || !iaxs[callno1]) {
03610       unlock_both(callno0, callno1);
03611       return AST_BRIDGE_FAILED;
03612    }
03613    /* Put them in native bridge mode */
03614    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03615       iaxs[callno0]->bridgecallno = callno1;
03616       iaxs[callno1]->bridgecallno = callno0;
03617    }
03618    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
03619    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
03620       transferstarted = 1;
03621    }
03622    unlock_both(callno0, callno1);
03623 
03624    /* If not, try to bridge until we can execute a transfer, if we can */
03625    cs[0] = c0;
03626    cs[1] = c1;
03627    for (/* ever */;;) {
03628       /* Check in case we got masqueraded into */
03629       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03630          if (option_verbose > 2)
03631             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03632          /* Remove from native mode */
03633          if (c0->tech == &iax2_tech) {
03634             ast_mutex_lock(&iaxsl[callno0]);
03635             iaxs[callno0]->bridgecallno = 0;
03636             ast_mutex_unlock(&iaxsl[callno0]);
03637          }
03638          if (c1->tech == &iax2_tech) {
03639             ast_mutex_lock(&iaxsl[callno1]);
03640             iaxs[callno1]->bridgecallno = 0;
03641             ast_mutex_unlock(&iaxsl[callno1]);
03642          }
03643          return AST_BRIDGE_FAILED_NOWARN;
03644       }
03645       if (c0->nativeformats != c1->nativeformats) {
03646          if (option_verbose > 2) {
03647             char buf0[255];
03648             char buf1[255];
03649             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03650             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03651             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03652          }
03653          /* Remove from native mode */
03654          lock_both(callno0, callno1);
03655          if (iaxs[callno0])
03656             iaxs[callno0]->bridgecallno = 0;
03657          if (iaxs[callno1])
03658             iaxs[callno1]->bridgecallno = 0;
03659          unlock_both(callno0, callno1);
03660          return AST_BRIDGE_FAILED_NOWARN;
03661       }
03662       /* check if transfered and if we really want native bridging */
03663       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03664          /* Try the transfer */
03665          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03666                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03667             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03668          transferstarted = 1;
03669       }
03670       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03671          /* Call has been transferred.  We're no longer involved */
03672          gettimeofday(&tv, NULL);
03673          if (ast_tvzero(waittimer)) {
03674             waittimer = tv;
03675          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03676             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03677             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03678             *fo = NULL;
03679             *rc = c0;
03680             res = AST_BRIDGE_COMPLETE;
03681             break;
03682          }
03683       }
03684       to = 1000;
03685       who = ast_waitfor_n(cs, 2, &to);
03686       if (timeoutms > -1) {
03687          timeoutms -= (1000 - to);
03688          if (timeoutms < 0)
03689             timeoutms = 0;
03690       }
03691       if (!who) {
03692          if (!timeoutms) {
03693             res = AST_BRIDGE_RETRY;
03694             break;
03695          }
03696          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03697             res = AST_BRIDGE_FAILED;
03698             break;
03699          }
03700          continue;
03701       }
03702       f = ast_read(who);
03703       if (!f) {
03704          *fo = NULL;
03705          *rc = who;
03706          res = AST_BRIDGE_COMPLETE;
03707          break;
03708       }
03709       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03710          *fo = f;
03711          *rc = who;
03712          res =  AST_BRIDGE_COMPLETE;
03713          break;
03714       }
03715       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03716       if ((f->frametype == AST_FRAME_VOICE) ||
03717           (f->frametype == AST_FRAME_TEXT) ||
03718           (f->frametype == AST_FRAME_VIDEO) || 
03719           (f->frametype == AST_FRAME_IMAGE) ||
03720           (f->frametype == AST_FRAME_DTMF)) {
03721          /* monitored dtmf take out of the bridge.
03722           * check if we monitor the specific source.
03723           */
03724          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03725          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03726             *rc = who;
03727             *fo = f;
03728             res = AST_BRIDGE_COMPLETE;
03729             /* Remove from native mode */
03730             break;
03731          }
03732          /* everything else goes to the other side */
03733          ast_write(other, f);
03734       }
03735       ast_frfree(f);
03736       /* Swap who gets priority */
03737       cs[2] = cs[0];
03738       cs[0] = cs[1];
03739       cs[1] = cs[2];
03740    }
03741    lock_both(callno0, callno1);
03742    if(iaxs[callno0])
03743       iaxs[callno0]->bridgecallno = 0;
03744    if(iaxs[callno1])
03745       iaxs[callno1]->bridgecallno = 0;
03746    unlock_both(callno0, callno1);
03747    return res;
03748 }
03749 
03750 static int iax2_answer(struct ast_channel *c)
03751 {
03752    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03753    if (option_debug)
03754       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03755    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03756 }
03757 
03758 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03759 {
03760    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03761    struct chan_iax2_pvt *pvt;
03762    int res = 0;
03763 
03764    if (option_debug && iaxdebug)
03765       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03766 
03767    ast_mutex_lock(&iaxsl[callno]);
03768    pvt = iaxs[callno];
03769 
03770    if (wait_for_peercallno(pvt)) {
03771       res = -1;
03772       goto done;
03773    }
03774 
03775    switch (condition) {
03776    case AST_CONTROL_HOLD:
03777       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03778          ast_moh_start(c, data, pvt->mohinterpret);
03779          goto done;
03780       }
03781       break;
03782    case AST_CONTROL_UNHOLD:
03783       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03784          ast_moh_stop(c);
03785          goto done;
03786       }
03787    }
03788 
03789    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03790 
03791 done:
03792    ast_mutex_unlock(&iaxsl[callno]);
03793 
03794    return res;
03795 }
03796    
03797 static int iax2_transfer(struct ast_channel *c, const char *dest)
03798 {
03799    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03800    struct iax_ie_data ied;
03801    char tmp[256], *context;
03802    ast_copy_string(tmp, dest, sizeof(tmp));
03803    context = strchr(tmp, '@');
03804    if (context) {
03805       *context = '\0';
03806       context++;
03807    }
03808    memset(&ied, 0, sizeof(ied));
03809    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03810    if (context)
03811       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03812    if (option_debug)
03813       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03814    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03815 }
03816    
03817 static int iax2_getpeertrunk(struct sockaddr_in sin)
03818 {
03819    struct iax2_peer *peer;
03820    int res = 0;
03821    struct ao2_iterator i;
03822 
03823    i = ao2_iterator_init(peers, 0);
03824    while ((peer = ao2_iterator_next(&i))) {
03825       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03826           (peer->addr.sin_port == sin.sin_port)) {
03827          res = ast_test_flag(peer, IAX_TRUNK);
03828          peer_unref(peer);
03829          break;
03830       }
03831       peer_unref(peer);
03832    }
03833 
03834    return res;
03835 }
03836 
03837 /*! \brief  Create new call, interface with the PBX core */
03838 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03839 {
03840    struct ast_channel *tmp;
03841    struct chan_iax2_pvt *i;
03842    struct ast_variable *v = NULL;
03843 
03844    if (!(i = iaxs[callno])) {
03845       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03846       return NULL;
03847    }
03848 
03849    /* Don't hold call lock */
03850    ast_mutex_unlock(&iaxsl[callno]);
03851    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);
03852    ast_mutex_lock(&iaxsl[callno]);
03853    if (i != iaxs[callno]) {
03854       if (tmp) {
03855          /* unlock and relock iaxsl[callno] to preserve locking order */
03856          ast_mutex_unlock(&iaxsl[callno]);
03857          ast_channel_free(tmp);
03858          ast_mutex_lock(&iaxsl[callno]);
03859       }
03860       return NULL;
03861    }
03862 
03863    if (!tmp)
03864       return NULL;
03865    tmp->tech = &iax2_tech;
03866    /* We can support any format by default, until we get restricted */
03867    tmp->nativeformats = capability;
03868    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
03869    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
03870    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03871 
03872    /* Don't use ast_set_callerid() here because it will
03873     * generate a NewCallerID event before the NewChannel event */
03874    if (!ast_strlen_zero(i->ani))
03875       tmp->cid.cid_ani = ast_strdup(i->ani);
03876    else
03877       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03878    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03879    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03880    tmp->cid.cid_pres = i->calling_pres;
03881    tmp->cid.cid_ton = i->calling_ton;
03882    tmp->cid.cid_tns = i->calling_tns;
03883    if (!ast_strlen_zero(i->language))
03884       ast_string_field_set(tmp, language, i->language);
03885    if (!ast_strlen_zero(i->accountcode))
03886       ast_string_field_set(tmp, accountcode, i->accountcode);
03887    if (i->amaflags)
03888       tmp->amaflags = i->amaflags;
03889    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03890    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03891    if (i->adsi)
03892       tmp->adsicpe = i->peeradsicpe;
03893    else
03894       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03895    i->owner = tmp;
03896    i->capability = capability;
03897 
03898    for (v = i->vars ; v ; v = v->next)
03899       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03900 
03901    if (state != AST_STATE_DOWN) {
03902       if (ast_pbx_start(tmp)) {
03903          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03904          ast_hangup(tmp);
03905          i->owner = NULL;
03906          return NULL;
03907       }
03908    }
03909 
03910    ast_module_ref(ast_module_info->self);
03911    
03912    return tmp;
03913 }
03914 
03915 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03916 {
03917    unsigned long int mssincetx; /* unsigned to handle overflows */
03918    long int ms, pred;
03919 
03920    tpeer->trunkact = *tv;
03921    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03922    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03923       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03924       tpeer->txtrunktime = *tv;
03925       tpeer->lastsent = 999999;
03926    }
03927    /* Update last transmit time now */
03928    tpeer->lasttxtime = *tv;
03929    
03930    /* Calculate ms offset */
03931    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03932    /* Predict from last value */
03933    pred = tpeer->lastsent + sampms;
03934    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03935       ms = pred;
03936    
03937    /* We never send the same timestamp twice, so fudge a little if we must */
03938    if (ms == tpeer->lastsent)
03939       ms = tpeer->lastsent + 1;
03940    tpeer->lastsent = ms;
03941    return ms;
03942 }
03943 
03944 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03945 {
03946    long ms; /* NOT unsigned */
03947    if (ast_tvzero(iaxs[callno]->rxcore)) {
03948       /* Initialize rxcore time if appropriate */
03949       gettimeofday(&iaxs[callno]->rxcore, NULL);
03950       /* Round to nearest 20ms so traces look pretty */
03951       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03952    }
03953    /* Calculate difference between trunk and channel */
03954    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03955    /* Return as the sum of trunk time and the difference between trunk and real time */
03956    return ms + ts;
03957 }
03958 
03959 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03960 {
03961    int ms;
03962    int voice = 0;
03963    int genuine = 0;
03964    int adjust;
03965    struct timeval *delivery = NULL;
03966 
03967 
03968    /* What sort of frame do we have?: voice is self-explanatory
03969       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03970       non-genuine frames are CONTROL frames [ringing etc], DTMF
03971       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03972       the others need a timestamp slaved to the voice frames so that they go in sequence
03973    */
03974    if (f) {
03975       if (f->frametype == AST_FRAME_VOICE) {
03976          voice = 1;
03977          delivery = &f->delivery;
03978       } else if (f->frametype == AST_FRAME_IAX) {
03979          genuine = 1;
03980       } else if (f->frametype == AST_FRAME_CNG) {
03981          p->notsilenttx = 0;  
03982       }
03983    }
03984    if (ast_tvzero(p->offset)) {
03985       gettimeofday(&p->offset, NULL);
03986       /* Round to nearest 20ms for nice looking traces */
03987       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03988    }
03989    /* If the timestamp is specified, just send it as is */
03990    if (ts)
03991       return ts;
03992    /* If we have a time that the frame arrived, always use it to make our timestamp */
03993    if (delivery && !ast_tvzero(*delivery)) {
03994       ms = ast_tvdiff_ms(*delivery, p->offset);
03995       if (option_debug > 2 && iaxdebug)
03996          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03997    } else {
03998       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03999       if (ms < 0)
04000          ms = 0;
04001       if (voice) {
04002          /* On a voice frame, use predicted values if appropriate */
04003          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04004             /* Adjust our txcore, keeping voice and non-voice synchronized */
04005             /* AN EXPLANATION:
04006                When we send voice, we usually send "calculated" timestamps worked out
04007                on the basis of the number of samples sent. When we send other frames,
04008                we usually send timestamps worked out from the real clock.
04009                The problem is that they can tend to drift out of step because the 
04010                   source channel's clock and our clock may not be exactly at the same rate.
04011                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
04012                for this call.  Moving it adjusts timestamps for non-voice frames.
04013                We make the adjustment in the style of a moving average.  Each time we
04014                adjust p->offset by 10% of the difference between our clock-derived
04015                timestamp and the predicted timestamp.  That's why you see "10000"
04016                below even though IAX2 timestamps are in milliseconds.
04017                The use of a moving average avoids offset moving too radically.
04018                Generally, "adjust" roams back and forth around 0, with offset hardly
04019                changing at all.  But if a consistent different starts to develop it
04020                will be eliminated over the course of 10 frames (200-300msecs) 
04021             */
04022             adjust = (ms - p->nextpred);
04023             if (adjust < 0)
04024                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04025             else if (adjust > 0)
04026                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04027 
04028             if (!p->nextpred) {
04029                p->nextpred = ms; /*f->samples / 8;*/
04030                if (p->nextpred <= p->lastsent)
04031                   p->nextpred = p->lastsent + 3;
04032             }
04033             ms = p->nextpred;
04034          } else {
04035                 /* in this case, just use the actual
04036             * time, since we're either way off
04037             * (shouldn't happen), or we're  ending a
04038             * silent period -- and seed the next
04039             * predicted time.  Also, round ms to the
04040             * next multiple of frame size (so our
04041             * silent periods are multiples of
04042             * frame size too) */
04043 
04044             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04045                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04046                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04047 
04048             if (f->samples >= 8) /* check to make sure we dont core dump */
04049             {
04050                int diff = ms % (f->samples / 8);
04051                if (diff)
04052                    ms += f->samples/8 - diff;
04053             }
04054 
04055             p->nextpred = ms;
04056             p->notsilenttx = 1;
04057          }
04058       } else if ( f->frametype == AST_FRAME_VIDEO ) {
04059          /*
04060          * IAX2 draft 03 says that timestamps MUST be in order.
04061          * It does not say anything about several frames having the same timestamp
04062          * When transporting video, we can have a frame that spans multiple iax packets
04063          * (so called slices), so it would make sense to use the same timestamp for all of
04064          * them
04065          * We do want to make sure that frames don't go backwards though
04066          */
04067          if ( (unsigned int)ms < p->lastsent )
04068             ms = p->lastsent;
04069       } else {
04070          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
04071             it's a genuine frame */
04072          if (genuine) {
04073             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
04074             if (ms <= p->lastsent)
04075                ms = p->lastsent + 3;
04076          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04077             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
04078             ms = p->lastsent + 3;
04079          }
04080       }
04081    }
04082    p->lastsent = ms;
04083    if (voice)
04084       p->nextpred = p->nextpred + f->samples / 8;
04085    return ms;
04086 }
04087 
04088 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04089 {
04090    /* Returns where in "receive time" we are.  That is, how many ms
04091       since we received (or would have received) the frame with timestamp 0 */
04092    int ms;
04093 #ifdef IAXTESTS
04094    int jit;
04095 #endif /* IAXTESTS */
04096    /* Setup rxcore if necessary */
04097    if (ast_tvzero(p->rxcore)) {
04098       p->rxcore = ast_tvnow();
04099       if (option_debug && iaxdebug)
04100          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04101                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04102       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04103 #if 1
04104       if (option_debug && iaxdebug)
04105          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04106                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04107 #endif
04108    }
04109 
04110    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04111 #ifdef IAXTESTS
04112    if (test_jit) {
04113       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04114          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04115          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04116             jit = -jit;
04117          ms += jit;
04118       }
04119    }
04120    if (test_late) {
04121       ms += test_late;
04122       test_late = 0;
04123    }
04124 #endif /* IAXTESTS */
04125    return ms;
04126 }
04127 
04128 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04129 {
04130    struct iax2_trunk_peer *tpeer;
04131    
04132    /* Finds and locks trunk peer */
04133    ast_mutex_lock(&tpeerlock);
04134    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04135       /* We don't lock here because tpeer->addr *never* changes */
04136       if (!inaddrcmp(&tpeer->addr, sin)) {
04137          ast_mutex_lock(&tpeer->lock);
04138          break;
04139       }
04140    }
04141    if (!tpeer) {
04142       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04143          ast_mutex_init(&tpeer->lock);
04144          tpeer->lastsent = 9999;
04145          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04146          tpeer->trunkact = ast_tvnow();
04147          ast_mutex_lock(&tpeer->lock);
04148          tpeer->next = tpeers;
04149          tpeer->sockfd = fd;
04150          tpeers = tpeer;
04151 #ifdef SO_NO_CHECK
04152          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04153 #endif
04154          if (option_debug)
04155             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04156       }
04157    }
04158    ast_mutex_unlock(&tpeerlock);
04159    return tpeer;
04160 }
04161 
04162 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04163 {
04164    struct ast_frame *f;
04165    struct iax2_trunk_peer *tpeer;
04166    void *tmp, *ptr;
04167    struct ast_iax2_meta_trunk_entry *met;
04168    struct ast_iax2_meta_trunk_mini *mtm;
04169 
04170    f = &fr->af;
04171    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04172    if (tpeer) {
04173       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04174          /* Need to reallocate space */
04175          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04176             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04177                ast_mutex_unlock(&tpeer->lock);
04178                return -1;
04179             }
04180             
04181             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04182             tpeer->trunkdata = tmp;
04183             if (option_debug)
04184                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);
04185          } else {
04186             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));
04187             ast_mutex_unlock(&tpeer->lock);
04188             return -1;
04189          }
04190       }
04191 
04192       /* Append to meta frame */
04193       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04194       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04195          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04196          mtm->len = htons(f->datalen);
04197          mtm->mini.callno = htons(pvt->callno);
04198          mtm->mini.ts = htons(0xffff & fr->ts);
04199          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04200          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04201       } else {
04202          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04203          /* Store call number and length in meta header */
04204          met->callno = htons(pvt->callno);
04205          met->len = htons(f->datalen);
04206          /* Advance pointers/decrease length past trunk entry header */
04207          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04208          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04209       }
04210       /* Copy actual trunk data */
04211       memcpy(ptr, f->data, f->datalen);
04212       tpeer->trunkdatalen += f->datalen;
04213 
04214       tpeer->calls++;
04215       ast_mutex_unlock(&tpeer->lock);
04216    }
04217    return 0;
04218 }
04219 
04220 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04221 {
04222    aes_encrypt_key128(digest, ecx);
04223    aes_decrypt_key128(digest, dcx);
04224 }
04225 
04226 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04227 {
04228 #if 0
04229    /* Debug with "fake encryption" */
04230    int x;
04231    if (len % 16)
04232       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04233    for (x=0;x<len;x++)
04234       dst[x] = src[x] ^ 0xff;
04235 #else 
04236    unsigned char lastblock[16] = { 0 };
04237    int x;
04238    while(len > 0) {
04239       aes_decrypt(src, dst, dcx);
04240       for (x=0;x<16;x++)
04241          dst[x] ^= lastblock[x];
04242       memcpy(lastblock, src, sizeof(lastblock));
04243       dst += 16;
04244       src += 16;
04245       len -= 16;
04246    }
04247 #endif
04248 }
04249 
04250 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04251 {
04252 #if 0
04253    /* Debug with "fake encryption" */
04254    int x;
04255    if (len % 16)
04256       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04257    for (x=0;x<len;x++)
04258       dst[x] = src[x] ^ 0xff;
04259 #else
04260    unsigned char curblock[16] = { 0 };
04261    int x;
04262    while(len > 0) {
04263       for (x=0;x<16;x++)
04264          curblock[x] ^= src[x];
04265       aes_encrypt(curblock, dst, ecx);
04266       memcpy(curblock, dst, sizeof(curblock)); 
04267       dst += 16;
04268       src += 16;
04269       len -= 16;
04270    }
04271 #endif
04272 }
04273 
04274 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04275 {
04276    int padding;
04277    unsigned char *workspace;
04278 
04279    workspace = alloca(*datalen);
04280    memset(f, 0, sizeof(*f));
04281    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04282       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04283       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04284          return -1;
04285       /* Decrypt */
04286       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04287 
04288       padding = 16 + (workspace[15] & 0xf);
04289       if (option_debug && iaxdebug)
04290          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04291       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04292          return -1;
04293 
04294       *datalen -= padding;
04295       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04296       f->frametype = fh->type;
04297       if (f->frametype == AST_FRAME_VIDEO) {
04298          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04299       } else {
04300          f->subclass = uncompress_subclass(fh->csub);
04301       }
04302    } else {
04303       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04304       if (option_debug && iaxdebug)
04305          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04306       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04307          return -1;
04308       /* Decrypt */
04309       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04310       padding = 16 + (workspace[15] & 0x0f);
04311       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04312          return -1;
04313       *datalen -= padding;
04314       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04315    }
04316    return 0;
04317 }
04318 
04319 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04320 {
04321    int padding;
04322    unsigned char *workspace;
04323    workspace = alloca(*datalen + 32);
04324    if (!workspace)
04325       return -1;
04326    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04327       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04328       if (option_debug && iaxdebug)
04329          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04330       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04331       padding = 16 + (padding & 0xf);
04332       memcpy(workspace, poo, padding);
04333       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04334       workspace[15] &= 0xf0;
04335       workspace[15] |= (padding & 0xf);
04336       if (option_debug && iaxdebug)
04337          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]);
04338       *datalen += padding;
04339       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04340       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04341          memcpy(poo, workspace + *datalen - 32, 32);
04342    } else {
04343       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04344       if (option_debug && iaxdebug)
04345          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04346       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04347       padding = 16 + (padding & 0xf);
04348       memcpy(workspace, poo, padding);
04349       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04350       workspace[15] &= 0xf0;
04351       workspace[15] |= (padding & 0x0f);
04352       *datalen += padding;
04353       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04354       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04355          memcpy(poo, workspace + *datalen - 32, 32);
04356    }
04357    return 0;
04358 }
04359 
04360 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04361 {
04362    int res=-1;
04363    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04364       /* Search for possible keys, given secrets */
04365       struct MD5Context md5;
04366       unsigned char digest[16];
04367       char *tmppw, *stringp;
04368       
04369       tmppw = ast_strdupa(iaxs[callno]->secret);
04370       stringp = tmppw;
04371       while ((tmppw = strsep(&stringp, ";"))) {
04372          MD5Init(&md5);
04373          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04374          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04375          MD5Final(digest, &md5);
04376          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04377          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04378          if (!res) {
04379             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04380             break;
04381          }
04382       }
04383    } else 
04384       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04385    return res;
04386 }
04387 
04388 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04389 {
04390    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04391       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04392       or delayed, with retransmission */
04393    struct ast_iax2_full_hdr *fh;
04394    struct ast_iax2_mini_hdr *mh;
04395    struct ast_iax2_video_hdr *vh;
04396    struct {
04397       struct iax_frame fr2;
04398       unsigned char buffer[4096];
04399    } frb;
04400    struct iax_frame *fr;
04401    int res;
04402    int sendmini=0;
04403    unsigned int lastsent;
04404    unsigned int fts;
04405 
04406    frb.fr2.afdatalen = sizeof(frb.buffer);
04407 
04408    if (!pvt) {
04409       ast_log(LOG_WARNING, "No private structure for packet?\n");
04410       return -1;
04411    }
04412    
04413    lastsent = pvt->lastsent;
04414 
04415    /* Calculate actual timestamp */
04416    fts = calc_timestamp(pvt, ts, f);
04417 
04418    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04419     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04420     * increment the "predicted timestamps" for voice, if we're predecting */
04421    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04422        return 0;
04423 
04424 
04425    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04426          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04427          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04428       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04429        (f->frametype == AST_FRAME_VOICE) 
04430       /* is a voice frame */ &&
04431       (f->subclass == pvt->svoiceformat) 
04432       /* is the same type */ ) {
04433          /* Force immediate rather than delayed transmission */
04434          now = 1;
04435          /* Mark that mini-style frame is appropriate */
04436          sendmini = 1;
04437    }
04438    if ( f->frametype == AST_FRAME_VIDEO ) {
04439       /*
04440        * If the lower 15 bits of the timestamp roll over, or if
04441        * the video format changed then send a full frame.
04442        * Otherwise send a mini video frame
04443        */
04444       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04445           ((f->subclass & ~0x1) == pvt->svideoformat)
04446          ) {
04447          now = 1;
04448          sendmini = 1;
04449       } else {
04450          now = 0;
04451          sendmini = 0;
04452       }
04453       pvt->lastvsent = fts;
04454    }
04455    /* Allocate an iax_frame */
04456    if (now) {
04457       fr = &frb.fr2;
04458    } else
04459       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));
04460    if (!fr) {
04461       ast_log(LOG_WARNING, "Out of memory\n");
04462       return -1;
04463    }
04464    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04465    iax_frame_wrap(fr, f);
04466 
04467    fr->ts = fts;
04468    fr->callno = pvt->callno;
04469    fr->transfer = transfer;
04470    fr->final = final;
04471    if (!sendmini) {
04472       /* We need a full frame */
04473       if (seqno > -1)
04474          fr->oseqno = seqno;
04475       else
04476          fr->oseqno = pvt->oseqno++;
04477       fr->iseqno = pvt->iseqno;
04478       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04479       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04480       fh->ts = htonl(fr->ts);
04481       fh->oseqno = fr->oseqno;
04482       if (transfer) {
04483          fh->iseqno = 0;
04484       } else
04485          fh->iseqno = fr->iseqno;
04486       /* Keep track of the last thing we've acknowledged */
04487       if (!transfer)
04488          pvt->aseqno = fr->iseqno;
04489       fh->type = fr->af.frametype & 0xFF;
04490       if (fr->af.frametype == AST_FRAME_VIDEO)
04491          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04492       else
04493          fh->csub = compress_subclass(fr->af.subclass);
04494       if (transfer) {
04495          fr->dcallno = pvt->transfercallno;
04496       } else
04497          fr->dcallno = pvt->peercallno;
04498       fh->dcallno = htons(fr->dcallno);
04499       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04500       fr->data = fh;
04501       fr->retries = 0;
04502       /* Retry after 2x the ping time has passed */
04503       fr->retrytime = pvt->pingtime * 2;
04504       if (fr->retrytime < MIN_RETRY_TIME)
04505          fr->retrytime = MIN_RETRY_TIME;
04506       if (fr->retrytime > MAX_RETRY_TIME)
04507          fr->retrytime = MAX_RETRY_TIME;
04508       /* Acks' don't get retried */
04509       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04510          fr->retries = -1;
04511       else if (f->frametype == AST_FRAME_VOICE)
04512          pvt->svoiceformat = f->subclass;
04513       else if (f->frametype == AST_FRAME_VIDEO)
04514          pvt->svideoformat = f->subclass & ~0x1;
04515       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04516          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04517             if (iaxdebug) {
04518                if (fr->transfer)
04519                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04520                else
04521                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04522             }
04523             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04524          } else
04525             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04526       }
04527    
04528       if (now) {
04529          res = send_packet(fr);
04530       } else
04531          res = iax2_transmit(fr);
04532    } else {
04533       if (ast_test_flag(pvt, IAX_TRUNK)) {
04534          iax2_trunk_queue(pvt, fr);
04535          res = 0;
04536       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04537          /* Video frame have no sequence number */
04538          fr->oseqno = -1;
04539          fr->iseqno = -1;
04540          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04541          vh->zeros = 0;
04542          vh->callno = htons(0x8000 | fr->callno);
04543          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04544          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04545          fr->data = vh;
04546          fr->retries = -1;
04547          res = send_packet(fr);        
04548       } else {
04549          /* Mini-frames have no sequence number */
04550          fr->oseqno = -1;
04551          fr->iseqno = -1;
04552          /* Mini frame will do */
04553          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04554          mh->callno = htons(fr->callno);
04555          mh->ts = htons(fr->ts & 0xFFFF);
04556          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04557          fr->data = mh;
04558          fr->retries = -1;
04559          if (pvt->transferring == TRANSFER_MEDIAPASS)
04560             fr->transfer = 1;
04561          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04562             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04563                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04564             } else
04565                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04566          }
04567          res = send_packet(fr);
04568       }
04569    }
04570    return res;
04571 }
04572 
04573 static int iax2_show_users(int fd, int argc, char *argv[])
04574 {
04575    regex_t regexbuf;
04576    int havepattern = 0;
04577 
04578 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04579 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04580 
04581    struct iax2_user *user = NULL;
04582    char auth[90];
04583    char *pstr = "";
04584    struct ao2_iterator i;
04585 
04586    switch (argc) {
04587    case 5:
04588       if (!strcasecmp(argv[3], "like")) {
04589          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04590             return RESULT_SHOWUSAGE;
04591          havepattern = 1;
04592       } else
04593          return RESULT_SHOWUSAGE;
04594    case 3:
04595       break;
04596    default:
04597       return RESULT_SHOWUSAGE;
04598    }
04599 
04600    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04601    i = ao2_iterator_init(users, 0);
04602    for (user = ao2_iterator_next(&i); user; 
04603       user_unref(user), user = ao2_iterator_next(&i)) {
04604       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04605          continue;
04606       
04607       if (!ast_strlen_zero(user->secret)) {
04608          ast_copy_string(auth,user->secret,sizeof(auth));
04609       } else if (!ast_strlen_zero(user->inkeys)) {
04610          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04611       } else
04612          ast_copy_string(auth, "-no secret-", sizeof(auth));
04613       
04614       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04615          pstr = "REQ Only";
04616       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04617          pstr = "Disabled";
04618       else
04619          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04620       
04621       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04622          user->contexts ? user->contexts->context : context,
04623          user->ha ? "Yes" : "No", pstr);
04624    }
04625 
04626    if (havepattern)
04627       regfree(&regexbuf);
04628 
04629    return RESULT_SUCCESS;
04630 #undef FORMAT
04631 #undef FORMAT2
04632 }
04633 
04634 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04635 {
04636    regex_t regexbuf;
04637    int havepattern = 0;
04638    int total_peers = 0;
04639    int online_peers = 0;
04640    int offline_peers = 0;
04641    int unmonitored_peers = 0;
04642    struct ao2_iterator i;
04643 
04644 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04645 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04646 
04647    struct iax2_peer *peer = NULL;
04648    char name[256];
04649    int registeredonly=0;
04650    char *term = manager ? "\r\n" : "\n";
04651 
04652    switch (argc) {
04653    case 6:
04654       if (!strcasecmp(argv[3], "registered"))
04655          registeredonly = 1;
04656       else
04657          return RESULT_SHOWUSAGE;
04658       if (!strcasecmp(argv[4], "like")) {
04659          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04660             return RESULT_SHOWUSAGE;
04661          havepattern = 1;
04662       } else
04663          return RESULT_SHOWUSAGE;
04664       break;
04665    case 5:
04666       if (!strcasecmp(argv[3], "like")) {
04667          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04668             return RESULT_SHOWUSAGE;
04669          havepattern = 1;
04670       } else
04671          return RESULT_SHOWUSAGE;
04672       break;
04673    case 4:
04674       if (!strcasecmp(argv[3], "registered"))
04675          registeredonly = 1;
04676       else
04677          return RESULT_SHOWUSAGE;
04678       break;
04679    case 3:
04680       break;
04681    default:
04682       return RESULT_SHOWUSAGE;
04683    }
04684 
04685 
04686    if (s)
04687       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04688    else
04689       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04690 
04691    i = ao2_iterator_init(peers, 0);
04692    for (peer = ao2_iterator_next(&i); peer; 
04693       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04694       char nm[20];
04695       char status[20];
04696       char srch[2000];
04697       int retstatus;
04698 
04699       if (registeredonly && !peer->addr.sin_addr.s_addr)
04700          continue;
04701       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04702          continue;
04703 
04704       if (!ast_strlen_zero(peer->username))
04705          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04706       else
04707          ast_copy_string(name, peer->name, sizeof(name));
04708       
04709       retstatus = peer_status(peer, status, sizeof(status));
04710       if (retstatus > 0)
04711          online_peers++;
04712       else if (!retstatus)
04713          offline_peers++;
04714       else
04715          unmonitored_peers++;
04716       
04717       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04718       
04719       snprintf(srch, sizeof(srch), FORMAT, name, 
04720           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04721           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04722           nm,
04723           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04724           peer->encmethods ? "(E)" : "   ", status, term);
04725       
04726       if (s)
04727          astman_append(s, FORMAT, name, 
04728                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04729                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04730                   nm,
04731                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04732                   peer->encmethods ? "(E)" : "   ", status, term);
04733       else
04734          ast_cli(fd, FORMAT, name, 
04735             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04736             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04737             nm,
04738             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04739             peer->encmethods ? "(E)" : "   ", status, term);
04740       total_peers++;
04741    }
04742 
04743    if (s)
04744       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04745    else
04746       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04747 
04748    if (havepattern)
04749       regfree(&regexbuf);
04750 
04751    return RESULT_SUCCESS;
04752 #undef FORMAT
04753 #undef FORMAT2
04754 }
04755 
04756 static int iax2_show_threads(int fd, int argc, char *argv[])
04757 {
04758    struct iax2_thread *thread = NULL;
04759    time_t t;
04760    int threadcount = 0, dynamiccount = 0;
04761    char type;
04762 
04763    if (argc != 3)
04764       return RESULT_SHOWUSAGE;
04765       
04766    ast_cli(fd, "IAX2 Thread Information\n");
04767    time(&t);
04768    ast_cli(fd, "Idle Threads:\n");
04769    AST_LIST_LOCK(&idle_list);
04770    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04771 #ifdef DEBUG_SCHED_MULTITHREAD
04772       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04773          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04774 #else
04775       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04776          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04777 #endif
04778       threadcount++;
04779    }
04780    AST_LIST_UNLOCK(&idle_list);
04781    ast_cli(fd, "Active Threads:\n");
04782    AST_LIST_LOCK(&active_list);
04783    AST_LIST_TRAVERSE(&active_list, thread, list) {
04784       if (thread->type == IAX_TYPE_DYNAMIC)
04785          type = 'D';
04786       else
04787          type = 'P';
04788 #ifdef DEBUG_SCHED_MULTITHREAD
04789       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04790          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04791 #else
04792       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04793          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04794 #endif
04795       threadcount++;
04796    }
04797    AST_LIST_UNLOCK(&active_list);
04798    ast_cli(fd, "Dynamic Threads:\n");
04799         AST_LIST_LOCK(&dynamic_list);
04800         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04801 #ifdef DEBUG_SCHED_MULTITHREAD
04802                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04803                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04804 #else
04805                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04806                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04807 #endif
04808       dynamiccount++;
04809         }
04810         AST_LIST_UNLOCK(&dynamic_list);
04811    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04812    return RESULT_SUCCESS;
04813 }
04814 
04815 static int iax2_show_peers(int fd, int argc, char *argv[])
04816 {
04817    return __iax2_show_peers(0, fd, NULL, argc, argv);
04818 }
04819 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04820 {
04821    ast_cli_netstats(s, -1, 0);
04822    astman_append(s, "\r\n");
04823    return RESULT_SUCCESS;
04824 }
04825 
04826 static int iax2_show_firmware(int fd, int argc, char *argv[])
04827 {
04828 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04829 #if !defined(__FreeBSD__)
04830 #define FORMAT "%-15.15s  %-15d %-15d\n"
04831 #else /* __FreeBSD__ */
04832 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04833 #endif /* __FreeBSD__ */
04834    struct iax_firmware *cur;
04835    if ((argc != 3) && (argc != 4))
04836       return RESULT_SHOWUSAGE;
04837    ast_mutex_lock(&waresl.lock);
04838    
04839    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04840    for (cur = waresl.wares;cur;cur = cur->next) {
04841       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04842          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04843             (int)ntohl(cur->fwh->datalen));
04844    }
04845    ast_mutex_unlock(&waresl.lock);
04846    return RESULT_SUCCESS;
04847 #undef FORMAT
04848 #undef FORMAT2
04849 }
04850 
04851 /* JDG: callback to display iax peers in manager */
04852 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04853 {
04854    char *a[] = { "iax2", "show", "users" };
04855    int ret;
04856    const char *id = astman_get_header(m,"ActionID");
04857 
04858    if (!ast_strlen_zero(id))
04859       astman_append(s, "ActionID: %s\r\n",id);
04860    ret = __iax2_show_peers(1, -1, s, 3, a );
04861    astman_append(s, "\r\n\r\n" );
04862    return ret;
04863 } /* /JDG */
04864 
04865 static char *regstate2str(int regstate)
04866 {
04867    switch(regstate) {
04868    case REG_STATE_UNREGISTERED:
04869       return "Unregistered";
04870    case REG_STATE_REGSENT:
04871       return "Request Sent";
04872    case REG_STATE_AUTHSENT:
04873       return "Auth. Sent";
04874    case REG_STATE_REGISTERED:
04875       return "Registered";
04876    case REG_STATE_REJECTED:
04877       return "Rejected";
04878    case REG_STATE_TIMEOUT:
04879       return "Timeout";
04880    case REG_STATE_NOAUTH:
04881       return "No Authentication";
04882    default:
04883       return "Unknown";
04884    }
04885 }
04886 
04887 static int iax2_show_registry(int fd, int argc, char *argv[])
04888 {
04889 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04890 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04891    struct iax2_registry *reg = NULL;
04892 
04893    char host[80];
04894    char perceived[80];
04895    if (argc != 3)
04896       return RESULT_SHOWUSAGE;
04897    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04898    AST_LIST_LOCK(&registrations);
04899    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04900       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04901       if (reg->us.sin_addr.s_addr) 
04902          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04903       else
04904          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04905       ast_cli(fd, FORMAT, host, 
04906                (reg->dnsmgr) ? "Y" : "N", 
04907                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04908    }
04909    AST_LIST_UNLOCK(&registrations);
04910    return RESULT_SUCCESS;
04911 #undef FORMAT
04912 #undef FORMAT2
04913 }
04914 
04915 static int iax2_show_channels(int fd, int argc, char *argv[])
04916 {
04917 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04918 #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"
04919 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04920    int x;
04921    int numchans = 0;
04922 
04923    if (argc != 3)
04924       return RESULT_SHOWUSAGE;
04925    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04926    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04927       ast_mutex_lock(&iaxsl[x]);
04928       if (iaxs[x]) {
04929          int lag, jitter, localdelay;
04930          jb_info jbinfo;
04931          
04932          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04933             jb_getinfo(iaxs[x]->jb, &jbinfo);
04934             jitter = jbinfo.jitter;
04935             localdelay = jbinfo.current - jbinfo.min;
04936          } else {
04937             jitter = -1;
04938             localdelay = 0;
04939          }
04940          lag = iaxs[x]->remote_rr.delay;
04941          ast_cli(fd, FORMAT,
04942             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04943             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04944             S_OR(iaxs[x]->username, "(None)"),
04945             iaxs[x]->callno, iaxs[x]->peercallno,
04946             iaxs[x]->oseqno, iaxs[x]->iseqno,
04947             lag,
04948             jitter,
04949             localdelay,
04950             ast_getformatname(iaxs[x]->voiceformat) );
04951          numchans++;
04952       }
04953       ast_mutex_unlock(&iaxsl[x]);
04954    }
04955    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04956    return RESULT_SUCCESS;
04957 #undef FORMAT
04958 #undef FORMAT2
04959 #undef FORMATB
04960 }
04961 
04962 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04963 {
04964    int x;
04965    int numchans = 0;
04966    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04967       ast_mutex_lock(&iaxsl[x]);
04968       if (iaxs[x]) {
04969          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04970          char *fmt;
04971          jb_info jbinfo;
04972          
04973          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04974             jb_getinfo(iaxs[x]->jb, &jbinfo);
04975             localjitter = jbinfo.jitter;
04976             localdelay = jbinfo.current - jbinfo.min;
04977             locallost = jbinfo.frames_lost;
04978             locallosspct = jbinfo.losspct/1000;
04979             localdropped = jbinfo.frames_dropped;
04980             localooo = jbinfo.frames_ooo;
04981          } else {
04982             localjitter = -1;
04983             localdelay = 0;
04984             locallost = -1;
04985             locallosspct = -1;
04986             localdropped = 0;
04987             localooo = -1;
04988          }
04989          if (limit_fmt)
04990             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04991          else
04992             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04993          if (s)
04994             
04995             astman_append(s, fmt,
04996                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04997                      iaxs[x]->pingtime,
04998                      localjitter, 
04999                      localdelay,
05000                      locallost,
05001                      locallosspct,
05002                      localdropped,
05003                      localooo,
05004                      iaxs[x]->frames_received/1000,
05005                      iaxs[x]->remote_rr.jitter,
05006                      iaxs[x]->remote_rr.delay,
05007                      iaxs[x]->remote_rr.losscnt,
05008                      iaxs[x]->remote_rr.losspct,
05009                      iaxs[x]->remote_rr.dropped,
05010                      iaxs[x]->remote_rr.ooo,
05011                      iaxs[x]->remote_rr.packets/1000);
05012          else
05013             ast_cli(fd, fmt,
05014                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05015                iaxs[x]->pingtime,
05016                localjitter, 
05017                localdelay,
05018                locallost,
05019                locallosspct,
05020                localdropped,
05021                localooo,
05022                iaxs[x]->frames_received/1000,
05023                iaxs[x]->remote_rr.jitter,
05024                iaxs[x]->remote_rr.delay,
05025                iaxs[x]->remote_rr.losscnt,
05026                iaxs[x]->remote_rr.losspct,
05027                iaxs[x]->remote_rr.dropped,
05028                iaxs[x]->remote_rr.ooo,
05029                iaxs[x]->remote_rr.packets/1000
05030                );
05031          numchans++;
05032       }
05033       ast_mutex_unlock(&iaxsl[x]);
05034    }
05035    return numchans;
05036 }
05037 
05038 static int iax2_show_netstats(int fd, int argc, char *argv[])
05039 {
05040    int numchans = 0;
05041    if (argc != 3)
05042       return RESULT_SHOWUSAGE;
05043    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
05044    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
05045    numchans = ast_cli_netstats(NULL, fd, 1);
05046    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05047    return RESULT_SUCCESS;
05048 }
05049 
05050 static int iax2_do_debug(int fd, int argc, char *argv[])
05051 {
05052    if (argc < 2 || argc > 3)
05053       return RESULT_SHOWUSAGE;
05054    iaxdebug = 1;
05055    ast_cli(fd, "IAX2 Debugging Enabled\n");
05056    return RESULT_SUCCESS;
05057 }
05058 
05059 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
05060 {
05061    if (argc < 3 || argc > 4)
05062       return RESULT_SHOWUSAGE;
05063    iaxtrunkdebug = 1;
05064    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
05065    return RESULT_SUCCESS;
05066 }
05067 
05068 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
05069 {
05070    if (argc < 3 || argc > 4)
05071       return RESULT_SHOWUSAGE;
05072    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05073    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05074    return RESULT_SUCCESS;
05075 }
05076 
05077 static int iax2_no_debug(int fd, int argc, char *argv[])
05078 {
05079    if (argc < 3 || argc > 4)
05080       return RESULT_SHOWUSAGE;
05081    iaxdebug = 0;
05082    ast_cli(fd, "IAX2 Debugging Disabled\n");
05083    return RESULT_SUCCESS;
05084 }
05085 
05086 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05087 {
05088    if (argc < 4 || argc > 5)
05089       return RESULT_SHOWUSAGE;
05090    iaxtrunkdebug = 0;
05091    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05092    return RESULT_SUCCESS;
05093 }
05094 
05095 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05096 {
05097    if (argc < 4 || argc > 5)
05098       return RESULT_SHOWUSAGE;
05099    jb_setoutput(jb_error_output, jb_warning_output, NULL);
05100    jb_debug_output("\n");
05101    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05102    return RESULT_SUCCESS;
05103 }
05104 
05105 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05106 {
05107    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05108    int res = -1;
05109    ast_mutex_lock(&iaxsl[callno]);
05110    if (iaxs[callno]) {
05111    /* If there's an outstanding error, return failure now */
05112       if (!iaxs[callno]->error) {
05113          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05114             res = 0;
05115             /* Don't waste bandwidth sending null frames */
05116          else if (f->frametype == AST_FRAME_NULL)
05117             res = 0;
05118          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05119             res = 0;
05120          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05121             res = 0;
05122          else
05123          /* Simple, just queue for transmission */
05124             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05125       } else {
05126          if (option_debug)
05127             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05128       }
05129    }
05130    /* If it's already gone, just return */
05131    ast_mutex_unlock(&iaxsl[callno]);
05132    return res;
05133 }
05134 
05135 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05136       int now, int transfer, int final)
05137 {
05138    struct ast_frame f = { 0, };
05139 
05140    f.frametype = type;
05141    f.subclass = command;
05142    f.datalen = datalen;
05143    f.src = __FUNCTION__;
05144    f.data = (void *) data;
05145 
05146    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05147 }
05148 
05149 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05150 {
05151    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05152 }
05153 
05154 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05155 {
05156    int res;
05157    ast_mutex_lock(&iaxsl[callno]);
05158    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05159    ast_mutex_unlock(&iaxsl[callno]);
05160    return res;
05161 }
05162 
05163 /*!
05164  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05165  *       the pvt struct for the given call number may disappear during its 
05166  *       execution.
05167  */
05168 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)
05169 {
05170    int call_num = i->callno;
05171    /* It is assumed that the callno has already been locked */
05172    iax2_predestroy(i->callno);
05173    if (!iaxs[call_num])
05174       return -1;
05175    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05176 }
05177 
05178 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)
05179 {
05180    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05181 }
05182 
05183 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05184 {
05185    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05186 }
05187 
05188 static int apply_context(struct iax2_context *con, const char *context)
05189 {
05190    while(con) {
05191       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05192          return -1;
05193       con = con->next;
05194    }
05195    return 0;
05196 }
05197 
05198 
05199 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05200 {
05201    /* Start pessimistic */
05202    int res = -1;
05203    int version = 2;
05204    struct iax2_user *user = NULL, *best = NULL;
05205    int bestscore = 0;
05206    int gotcapability = 0;
05207    struct ast_variable *v = NULL, *tmpvar = NULL;
05208    struct ao2_iterator i;
05209 
05210    if (!iaxs[callno])
05211       return res;
05212    if (ies->called_number)
05213       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05214    if (ies->calling_number) {
05215       ast_shrink_phone_number(ies->calling_number);
05216       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05217    }
05218    if (ies->calling_name)
05219       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05220    if (ies->calling_ani)
05221       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05222    if (ies->dnid)
05223       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05224    if (ies->rdnis)
05225       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05226    if (ies->called_context)
05227       ast_string_field_set(iaxs[callno], context, ies->called_context);
05228    if (ies->language)
05229       ast_string_field_set(iaxs[callno], language, ies->language);
05230    if (ies->username)
05231       ast_string_field_set(iaxs[callno], username, ies->username);
05232    if (ies->calling_ton > -1)
05233       iaxs[callno]->calling_ton = ies->calling_ton;
05234    if (ies->calling_tns > -1)
05235       iaxs[callno]->calling_tns = ies->calling_tns;
05236    if (ies->calling_pres > -1)
05237       iaxs[callno]->calling_pres = ies->calling_pres;
05238    if (ies->format)
05239       iaxs[callno]->peerformat = ies->format;
05240    if (ies->adsicpe)
05241       iaxs[callno]->peeradsicpe = ies->adsicpe;
05242    if (ies->capability) {
05243       gotcapability = 1;
05244       iaxs[callno]->peercapability = ies->capability;
05245    } 
05246    if (ies->version)
05247       version = ies->version;
05248 
05249    /* Use provided preferences until told otherwise for actual preferences */
05250    if(ies->codec_prefs) {
05251       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05252       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05253    }
05254 
05255    if (!gotcapability) 
05256       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05257    if (version > IAX_PROTO_VERSION) {
05258       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05259          ast_inet_ntoa(sin->sin_addr), version);
05260       return res;
05261    }
05262    /* Search the userlist for a compatible entry, and fill in the rest */
05263    i = ao2_iterator_init(users, 0);
05264    while ((user = ao2_iterator_next(&i))) {
05265       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05266          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05267          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05268          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05269               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05270          if (!ast_strlen_zero(iaxs[callno]->username)) {
05271             /* Exact match, stop right now. */
05272             if (best)
05273                user_unref(best);
05274             best = user;
05275             break;
05276          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05277             /* No required authentication */
05278             if (user->ha) {
05279                /* There was host authentication and we passed, bonus! */
05280                if (bestscore < 4) {
05281                   bestscore = 4;
05282                   if (best)
05283                      user_unref(best);
05284                   best = user;
05285                   continue;
05286                }
05287             } else {
05288                /* No host access, but no secret, either, not bad */
05289                if (bestscore < 3) {
05290                   bestscore = 3;
05291                   if (best)
05292                      user_unref(best);
05293                   best = user;
05294                   continue;
05295                }
05296             }
05297          } else {
05298             if (user->ha) {
05299                /* Authentication, but host access too, eh, it's something.. */
05300                if (bestscore < 2) {
05301                   bestscore = 2;
05302                   if (best)
05303                      user_unref(best);
05304                   best = user;
05305                   continue;
05306                }
05307             } else {
05308                /* Authentication and no host access...  This is our baseline */
05309                if (bestscore < 1) {
05310                   bestscore = 1;
05311                   if (best)
05312                      user_unref(best);
05313                   best = user;
05314                   continue;
05315                }
05316             }
05317          }
05318       }
05319       user_unref(user);
05320    }
05321    user = best;
05322    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05323       user = realtime_user(iaxs[callno]->username, sin);
05324       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05325           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05326          user = user_unref(user);
05327       }
05328    }
05329    if (user) {
05330       /* We found our match (use the first) */
05331       /* copy vars */
05332       for (v = user->vars ; v ; v = v->next) {
05333          if((tmpvar = ast_variable_new(v->name, v->value))) {
05334             tmpvar->next = iaxs[callno]->vars; 
05335             iaxs[callno]->vars = tmpvar;
05336          }
05337       }
05338       /* If a max AUTHREQ restriction is in place, activate it */
05339       if (user->maxauthreq > 0)
05340          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05341       iaxs[callno]->prefs = user->prefs;
05342       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05343       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05344       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05345       iaxs[callno]->encmethods = user->encmethods;
05346       /* Store the requested username if not specified */
05347       if (ast_strlen_zero(iaxs[callno]->username))
05348          ast_string_field_set(iaxs[callno], username, user->name);
05349       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05350       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05351       iaxs[callno]->capability = user->capability;
05352       /* And use the default context */
05353       if (ast_strlen_zero(iaxs[callno]->context)) {
05354          if (user->contexts)
05355             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05356          else
05357             ast_string_field_set(iaxs[callno], context, context);
05358       }
05359       /* And any input keys */
05360       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05361       /* And the permitted authentication methods */
05362       iaxs[callno]->authmethods = user->authmethods;
05363       iaxs[callno]->adsi = user->adsi;
05364       /* If the user has callerid, override the remote caller id. */
05365       if (ast_test_flag(user, IAX_HASCALLERID)) {
05366          iaxs[callno]->calling_tns = 0;
05367          iaxs[callno]->calling_ton = 0;
05368          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05369          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05370          ast_string_field_set(iaxs[callno], ani, user->cid_num);
05371          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05372       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
05373          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05374       } /* else user is allowed to set their own CID settings */
05375       if (!ast_strlen_zero(user->accountcode))
05376          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05377       if (!ast_strlen_zero(user->mohinterpret))
05378          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05379       if (!ast_strlen_zero(user->mohsuggest))
05380          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05381       if (user->amaflags)
05382          iaxs[callno]->amaflags = user->amaflags;
05383       if (!ast_strlen_zero(user->language))
05384          ast_string_field_set(iaxs[callno], language, user->language);
05385       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05386       /* Keep this check last */
05387       if (!ast_strlen_zero(user->dbsecret)) {
05388          char *family, *key=NULL;
05389          char buf[80];
05390          family = ast_strdupa(user->dbsecret);
05391          key = strchr(family, '/');
05392          if (key) {
05393             *key = '\0';
05394             key++;
05395          }
05396          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05397             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05398          else
05399             ast_string_field_set(iaxs[callno], secret, buf);
05400       } else
05401          ast_string_field_set(iaxs[callno], secret, user->secret);
05402       res = 0;
05403       user = user_unref(user);
05404    }
05405    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05406    return res;
05407 }
05408 
05409 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05410 {
05411    struct ast_iax2_full_hdr fh;
05412    fh.scallno = htons(src | IAX_FLAG_FULL);
05413    fh.dcallno = htons(dst);
05414    fh.ts = 0;
05415    fh.oseqno = 0;
05416    fh.iseqno = 0;
05417    fh.type = AST_FRAME_IAX;
05418    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05419    if (iaxdebug)
05420        iax_showframe(NULL, &fh, 0, sin, 0);
05421    if (option_debug)
05422       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05423          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05424    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05425 }
05426 
05427 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05428 {
05429    /* Select exactly one common encryption if there are any */
05430    p->encmethods &= enc;
05431    if (p->encmethods) {
05432       if (p->encmethods & IAX_ENCRYPT_AES128)
05433          p->encmethods = IAX_ENCRYPT_AES128;
05434       else
05435          p->encmethods = 0;
05436    }
05437 }
05438 
05439 /*!
05440  * \pre iaxsl[call_num] is locked
05441  *
05442  * \note Since this function calls send_command_final(), the pvt struct for the given
05443  *       call number may disappear while executing this function.
05444  */
05445 static int authenticate_request(int call_num)
05446 {
05447    struct iax_ie_data ied;
05448    int res = -1, authreq_restrict = 0;
05449    char challenge[10];
05450    struct chan_iax2_pvt *p = iaxs[call_num];
05451 
05452    memset(&ied, 0, sizeof(ied));
05453 
05454    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05455    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05456       struct iax2_user *user, tmp_user = {
05457          .name = p->username, 
05458       };
05459 
05460       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05461       if (user) {
05462          if (user->curauthreq == user->maxauthreq)
05463             authreq_restrict = 1;
05464          else
05465             user->curauthreq++;
05466          user = user_unref(user);
05467       }
05468    }
05469 
05470    /* If the AUTHREQ limit test failed, send back an error */
05471    if (authreq_restrict) {
05472       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05473       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05474       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05475       return 0;
05476    }
05477 
05478    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05479    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05480       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05481       ast_string_field_set(p, challenge, challenge);
05482       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05483       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05484    }
05485    if (p->encmethods)
05486       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05487 
05488    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05489 
05490    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05491 
05492    if (p->encmethods)
05493       ast_set_flag(p, IAX_ENCRYPTED);
05494 
05495    return res;
05496 }
05497 
05498 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05499 {
05500    char requeststr[256];
05501    char md5secret[256] = "";
05502    char secret[256] = "";
05503    char rsasecret[256] = "";
05504    int res = -1; 
05505    int x;
05506    struct iax2_user *user, tmp_user = {
05507       .name = p->username, 
05508    };
05509 
05510    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05511    if (user) {
05512       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05513          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05514          ast_clear_flag(p, IAX_MAXAUTHREQ);
05515       }
05516       ast_string_field_set(p, host, user->name);
05517       user = user_unref(user);
05518    }
05519 
05520    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05521       return res;
05522    if (ies->password)
05523       ast_copy_string(secret, ies->password, sizeof(secret));
05524    if (ies->md5_result)
05525       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05526    if (ies->rsa_result)
05527       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05528    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05529       struct ast_key *key;
05530       char *keyn;
05531       char tmpkey[256];
05532       char *stringp=NULL;
05533       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05534       stringp=tmpkey;
05535       keyn = strsep(&stringp, ":");
05536       while(keyn) {
05537          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05538          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05539             res = 0;
05540             break;
05541          } else if (!key)
05542             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05543          keyn = strsep(&stringp, ":");
05544       }
05545    } else if (p->authmethods & IAX_AUTH_MD5) {
05546       struct MD5Context md5;
05547       unsigned char digest[16];
05548       char *tmppw, *stringp;
05549       
05550       tmppw = ast_strdupa(p->secret);
05551       stringp = tmppw;
05552       while((tmppw = strsep(&stringp, ";"))) {
05553          MD5Init(&md5);
05554          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05555          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05556          MD5Final(digest, &md5);
05557          /* If they support md5, authenticate with it.  */
05558          for (x=0;x<16;x++)
05559             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05560          if (!strcasecmp(requeststr, md5secret)) {
05561             res = 0;
05562             break;
05563          }
05564       }
05565    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05566       if (!strcmp(secret, p->secret))
05567          res = 0;
05568    }
05569    return res;
05570 }
05571 
05572 /*! \brief Verify inbound registration */
05573 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05574 {
05575    char requeststr[256] = "";
05576    char peer[256] = "";
05577    char md5secret[256] = "";
05578    char rsasecret[256] = "";
05579    char secret[256] = "";
05580    struct iax2_peer *p = NULL;
05581    struct ast_key *key;
05582    char *keyn;
05583    int x;
05584    int expire = 0;
05585    int res = -1;
05586 
05587    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05588    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05589    if (ies->username)
05590       ast_copy_string(peer, ies->username, sizeof(peer));
05591    if (ies->password)
05592       ast_copy_string(secret, ies->password, sizeof(secret));
05593    if (ies->md5_result)
05594       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05595    if (ies->rsa_result)
05596       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05597    if (ies->refresh)
05598       expire = ies->refresh;
05599 
05600    if (ast_strlen_zero(peer)) {
05601       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05602       return -1;
05603    }
05604 
05605    /* SLD: first call to lookup peer during registration */
05606    ast_mutex_unlock(&iaxsl[callno]);
05607    p = find_peer(peer, 1);
05608    ast_mutex_lock(&iaxsl[callno]);
05609    if (!p || !iaxs[callno]) {
05610       if (iaxs[callno]) {
05611          ast_string_field_set(iaxs[callno], secret, "badsecret");
05612       }
05613       if (authdebug && !p)
05614          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05615       goto return_unref;
05616    }
05617 
05618    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05619       if (authdebug)
05620          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05621       goto return_unref;
05622    }
05623 
05624    if (!ast_apply_ha(p->ha, sin)) {
05625       if (authdebug)
05626          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05627       goto return_unref;
05628    }
05629    if (!inaddrcmp(&p->addr, sin))
05630       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05631    ast_string_field_set(iaxs[callno], secret, p->secret);
05632    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05633    /* Check secret against what we have on file */
05634    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05635       if (!ast_strlen_zero(p->inkeys)) {
05636          char tmpkeys[256];
05637          char *stringp=NULL;
05638          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05639          stringp=tmpkeys;
05640          keyn = strsep(&stringp, ":");
05641          while(keyn) {
05642             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05643             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05644                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05645                break;
05646             } else if (!key) 
05647                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05648             keyn = strsep(&stringp, ":");
05649          }
05650          if (!keyn) {
05651             if (authdebug)
05652                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05653             goto return_unref;
05654          }
05655       } else {
05656          if (authdebug)
05657             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05658          goto return_unref;
05659       }
05660    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05661       struct MD5Context md5;
05662       unsigned char digest[16];
05663       char *tmppw, *stringp;
05664       
05665       tmppw = ast_strdupa(p->secret);
05666       stringp = tmppw;
05667       while((tmppw = strsep(&stringp, ";"))) {
05668          MD5Init(&md5);
05669          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05670          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05671          MD5Final(digest, &md5);
05672          for (x=0;x<16;x++)
05673             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05674          if (!strcasecmp(requeststr, md5secret)) 
05675             break;
05676       }
05677       if (tmppw) {
05678          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05679       } else {
05680          if (authdebug)
05681             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05682          goto return_unref;
05683       }
05684    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05685       /* They've provided a plain text password and we support that */
05686       if (strcmp(secret, p->secret)) {
05687          if (authdebug)
05688             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05689          goto return_unref;
05690       } else
05691          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05692    } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) {
05693       if (authdebug &&
05694          ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) ||
05695           (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) {
05696          ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name);
05697       } /* ELSE this is the first time through and no challenge exists, so it's not quite yet a failure. */
05698       goto return_unref;
05699    }
05700    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05701 
05702 return_unref:
05703    ast_string_field_set(iaxs[callno], peer, peer);
05704    /* Choose lowest expiry number */
05705    if (expire && (expire < iaxs[callno]->expiry)) 
05706       iaxs[callno]->expiry = expire;
05707 
05708    res = 0;
05709 
05710    if (p)
05711       peer_unref(p);
05712 
05713    return res;
05714 }
05715 
05716 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05717 {
05718    int res = -1;
05719    int x;
05720    if (!ast_strlen_zero(keyn)) {
05721       if (!(authmethods & IAX_AUTH_RSA)) {
05722          if (ast_strlen_zero(secret)) 
05723             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));
05724       } else if (ast_strlen_zero(challenge)) {
05725          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05726       } else {
05727          char sig[256];
05728          struct ast_key *key;
05729          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05730          if (!key) {
05731             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05732          } else {
05733             if (ast_sign(key, (char*)challenge, sig)) {
05734                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05735                res = -1;
05736             } else {
05737                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05738                res = 0;
05739             }
05740          }
05741       }
05742    } 
05743    /* Fall back */
05744    if (res && !ast_strlen_zero(secret)) {
05745       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05746          struct MD5Context md5;
05747          unsigned char digest[16];
05748          char digres[128];
05749          MD5Init(&md5);
05750          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05751          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05752          MD5Final(digest, &md5);
05753          /* If they support md5, authenticate with it.  */
05754          for (x=0;x<16;x++)
05755             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05756          if (ecx && dcx)
05757             build_enc_keys(digest, ecx, dcx);
05758          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05759          res = 0;
05760       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05761          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05762          res = 0;
05763       } else
05764          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05765    }
05766    return res;
05767 }
05768 
05769 /*!
05770  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05771  *       so do not call this function with a pvt lock held.
05772  */
05773 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05774 {
05775    struct iax2_peer *peer = NULL;
05776    /* Start pessimistic */
05777    int res = -1;
05778    int authmethods = 0;
05779    struct iax_ie_data ied;
05780    uint16_t callno = p->callno;
05781 
05782    memset(&ied, 0, sizeof(ied));
05783    
05784    if (ies->username)
05785       ast_string_field_set(p, username, ies->username);
05786    if (ies->challenge)
05787       ast_string_field_set(p, challenge, ies->challenge);
05788    if (ies->authmethods)
05789       authmethods = ies->authmethods;
05790    if (authmethods & IAX_AUTH_MD5)
05791       merge_encryption(p, ies->encmethods);
05792    else
05793       p->encmethods = 0;
05794 
05795    /* Check for override RSA authentication first */
05796    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05797       /* Normal password authentication */
05798       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05799    } else {
05800       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05801       while ((peer = ao2_iterator_next(&i))) {
05802          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05803              /* No peer specified at our end, or this is the peer */
05804              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05805              /* No username specified in peer rule, or this is the right username */
05806              && (!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)))
05807              /* No specified host, or this is our host */
05808             ) {
05809             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05810             if (!res) {
05811                peer_unref(peer);
05812                break;
05813             }
05814          }
05815          peer_unref(peer);
05816       }
05817       if (!peer) {
05818          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05819             that we're trying to authenticate *to* a realtime peer */
05820          const char *peer_name = ast_strdupa(p->peer);
05821          ast_mutex_unlock(&iaxsl[callno]);
05822          if ((peer = realtime_peer(peer_name, NULL))) {
05823             ast_mutex_lock(&iaxsl[callno]);
05824             if (!(p = iaxs[callno])) {
05825                peer_unref(peer);
05826                return -1;
05827             }
05828             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05829             peer_unref(peer);
05830          }
05831          if (!peer) {
05832             ast_mutex_lock(&iaxsl[callno]);
05833             if (!(p = iaxs[callno]))
05834                return -1;
05835          }
05836       }
05837    }
05838    if (ies->encmethods)
05839       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05840    if (!res)
05841       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05842    return res;
05843 }
05844 
05845 static int iax2_do_register(struct iax2_registry *reg);
05846 
05847 static void __iax2_do_register_s(const void *data)
05848 {
05849    struct iax2_registry *reg = (struct iax2_registry *)data;
05850    reg->expire = -1;
05851    iax2_do_register(reg);
05852 }
05853 
05854 static int iax2_do_register_s(const void *data)
05855 {
05856 #ifdef SCHED_MULTITHREADED
05857    if (schedule_action(__iax2_do_register_s, data))
05858 #endif      
05859       __iax2_do_register_s(data);
05860    return 0;
05861 }
05862 
05863 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05864 {
05865    int newcall = 0;
05866    char newip[256];
05867    struct iax_ie_data ied;
05868    struct sockaddr_in new;
05869    
05870    
05871    memset(&ied, 0, sizeof(ied));
05872    if (ies->apparent_addr)
05873       bcopy(ies->apparent_addr, &new, sizeof(new));
05874    if (ies->callno)
05875       newcall = ies->callno;
05876    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05877       ast_log(LOG_WARNING, "Invalid transfer request\n");
05878       return -1;
05879    }
05880    pvt->transfercallno = newcall;
05881    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05882    inet_aton(newip, &pvt->transfer.sin_addr);
05883    pvt->transfer.sin_family = AF_INET;
05884    pvt->transferring = TRANSFER_BEGIN;
05885    pvt->transferid = ies->transferid;
05886    if (ies->transferid)
05887       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05888    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05889    return 0; 
05890 }
05891 
05892 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05893 {
05894    char exten[256] = "";
05895    int status = CACHE_FLAG_UNKNOWN;
05896    int expiry = iaxdefaultdpcache;
05897    int x;
05898    int matchmore = 0;
05899    struct iax2_dpcache *dp, *prev;
05900    
05901    if (ies->called_number)
05902       ast_copy_string(exten, ies->called_number, sizeof(exten));
05903 
05904    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05905       status = CACHE_FLAG_EXISTS;
05906    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05907       status = CACHE_FLAG_CANEXIST;
05908    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05909       status = CACHE_FLAG_NONEXISTENT;
05910 
05911    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05912       /* Don't really do anything with this */
05913    }
05914    if (ies->refresh)
05915       expiry = ies->refresh;
05916    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05917       matchmore = CACHE_FLAG_MATCHMORE;
05918    ast_mutex_lock(&dpcache_lock);
05919    prev = NULL;
05920    dp = pvt->dpentries;
05921    while(dp) {
05922       if (!strcmp(dp->exten, exten)) {
05923          /* Let them go */
05924          if (prev)
05925             prev->peer = dp->peer;
05926          else
05927             pvt->dpentries = dp->peer;
05928          dp->peer = NULL;
05929          dp->callno = 0;
05930          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05931          if (dp->flags & CACHE_FLAG_PENDING) {
05932             dp->flags &= ~CACHE_FLAG_PENDING;
05933             dp->flags |= status;
05934             dp->flags |= matchmore;
05935          }
05936          /* Wake up waiters */
05937          for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
05938             if (dp->waiters[x] > -1) {
05939                if (write(dp->waiters[x], "asdf", 4) < 0) {
05940                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
05941                }
05942             }
05943          }
05944       }
05945       prev = dp;
05946       dp = dp->peer;
05947    }
05948    ast_mutex_unlock(&dpcache_lock);
05949    return 0;
05950 }
05951 
05952 static int complete_transfer(int callno, struct iax_ies *ies)
05953 {
05954    int peercallno = 0;
05955    struct chan_iax2_pvt *pvt = iaxs[callno];
05956    struct iax_frame *cur;
05957    jb_frame frame;
05958 
05959    if (ies->callno)
05960       peercallno = ies->callno;
05961 
05962    if (peercallno < 1) {
05963       ast_log(LOG_WARNING, "Invalid transfer request\n");
05964       return -1;
05965    }
05966    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05967    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05968    /* Reset sequence numbers */
05969    pvt->oseqno = 0;
05970    pvt->rseqno = 0;
05971    pvt->iseqno = 0;
05972    pvt->aseqno = 0;
05973 
05974    if (pvt->peercallno) {
05975       remove_by_peercallno(pvt);
05976    }
05977    pvt->peercallno = peercallno;
05978    store_by_peercallno(pvt);
05979 
05980    pvt->transferring = TRANSFER_NONE;
05981    pvt->svoiceformat = -1;
05982    pvt->voiceformat = 0;
05983    pvt->svideoformat = -1;
05984    pvt->videoformat = 0;
05985    pvt->transfercallno = -1;
05986    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05987    memset(&pvt->offset, 0, sizeof(pvt->offset));
05988    /* reset jitterbuffer */
05989    while(jb_getall(pvt->jb,&frame) == JB_OK)
05990       iax2_frame_free(frame.data);
05991    jb_reset(pvt->jb);
05992    pvt->lag = 0;
05993    pvt->last = 0;
05994    pvt->lastsent = 0;
05995    pvt->nextpred = 0;
05996    pvt->pingtime = DEFAULT_RETRY_TIME;
05997    AST_LIST_LOCK(&iaxq.queue);
05998    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05999       /* We must cancel any packets that would have been transmitted
06000          because now we're talking to someone new.  It's okay, they
06001          were transmitted to someone that didn't care anyway. */
06002       if (callno == cur->callno) 
06003          cur->retries = -1;
06004    }
06005    AST_LIST_UNLOCK(&iaxq.queue);
06006    return 0; 
06007 }
06008 
06009 /*! \brief Acknowledgment received for OUR registration */
06010 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06011 {
06012    struct iax2_registry *reg;
06013    /* Start pessimistic */
06014    char peer[256] = "";
06015    char msgstatus[60];
06016    int refresh = 60;
06017    char ourip[256] = "<Unspecified>";
06018    struct sockaddr_in oldus;
06019    struct sockaddr_in us;
06020    int oldmsgs;
06021 
06022    memset(&us, 0, sizeof(us));
06023    if (ies->apparent_addr)
06024       bcopy(ies->apparent_addr, &us, sizeof(us));
06025    if (ies->username)
06026       ast_copy_string(peer, ies->username, sizeof(peer));
06027    if (ies->refresh)
06028       refresh = ies->refresh;
06029    if (ies->calling_number) {
06030       /* We don't do anything with it really, but maybe we should */
06031    }
06032    reg = iaxs[callno]->reg;
06033    if (!reg) {
06034       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06035       return -1;
06036    }
06037    memcpy(&oldus, &reg->us, sizeof(oldus));
06038    oldmsgs = reg->messages;
06039    if (inaddrcmp(&reg->addr, sin)) {
06040       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06041       return -1;
06042    }
06043    memcpy(&reg->us, &us, sizeof(reg->us));
06044    if (ies->msgcount >= 0)
06045       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
06046    /* always refresh the registration at the interval requested by the server
06047       we are registering to
06048    */
06049    reg->refresh = refresh;
06050    AST_SCHED_DEL(sched, reg->expire);
06051    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06052    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
06053       if (option_verbose > 2) {
06054          if (reg->messages > 255)
06055             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06056          else if (reg->messages > 1)
06057             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06058          else if (reg->messages > 0)
06059             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
06060          else
06061             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
06062          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06063          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06064       }
06065       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06066    }
06067    reg->regstate = REG_STATE_REGISTERED;
06068    return 0;
06069 }
06070 
06071 static int iax2_register(char *value, int lineno)
06072 {
06073    struct iax2_registry *reg;
06074    char copy[256];
06075    char *username, *hostname, *secret;
06076    char *porta;
06077    char *stringp=NULL;
06078    
06079    if (!value)
06080       return -1;
06081    ast_copy_string(copy, value, sizeof(copy));
06082    stringp=copy;
06083    username = strsep(&stringp, "@");
06084    hostname = strsep(&stringp, "@");
06085    if (!hostname) {
06086       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06087       return -1;
06088    }
06089    stringp=username;
06090    username = strsep(&stringp, ":");
06091    secret = strsep(&stringp, ":");
06092    stringp=hostname;
06093    hostname = strsep(&stringp, ":");
06094    porta = strsep(&stringp, ":");
06095    
06096    if (porta && !atoi(porta)) {
06097       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06098       return -1;
06099    }
06100    if (!(reg = ast_calloc(1, sizeof(*reg))))
06101       return -1;
06102    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06103       free(reg);
06104       return -1;
06105    }
06106    ast_copy_string(reg->username, username, sizeof(reg->username));
06107    if (secret)
06108       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06109    reg->expire = -1;
06110    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06111    reg->addr.sin_family = AF_INET;
06112    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06113    AST_LIST_LOCK(&registrations);
06114    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06115    AST_LIST_UNLOCK(&registrations);
06116    
06117    return 0;
06118 }
06119 
06120 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06121 {
06122    char multi[256];
06123    char *stringp, *ext;
06124    if (!ast_strlen_zero(regcontext)) {
06125       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06126       stringp = multi;
06127       while((ext = strsep(&stringp, "&"))) {
06128          if (onoff) {
06129             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06130                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06131                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06132          } else
06133             ast_context_remove_extension(regcontext, ext, 1, NULL);
06134       }
06135    }
06136 }
06137 static void prune_peers(void);
06138 
06139 static void unlink_peer(struct iax2_peer *peer)
06140 {
06141    if (peer->expire > -1) {
06142       if (!ast_sched_del(sched, peer->expire)) {
06143          peer->expire = -1;
06144          peer_unref(peer);
06145       }
06146    }
06147 
06148    if (peer->pokeexpire > -1) {
06149       if (!ast_sched_del(sched, peer->pokeexpire)) {
06150          peer->pokeexpire = -1;
06151          peer_unref(peer);
06152       }
06153    }
06154 
06155    ao2_unlink(peers, peer);
06156 }
06157 
06158 static void __expire_registry(const void *data)
06159 {
06160    struct iax2_peer *peer = (struct iax2_peer *) data;
06161 
06162    if (!peer)
06163       return;
06164 
06165    peer->expire = -1;
06166 
06167    if (option_debug)
06168       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06169    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06170       realtime_update_peer(peer->name, &peer->addr, 0);
06171    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06172    /* Reset the address */
06173    memset(&peer->addr, 0, sizeof(peer->addr));
06174    /* Reset expiry value */
06175    peer->expiry = min_reg_expire;
06176    if (!ast_test_flag(peer, IAX_TEMPONLY))
06177       ast_db_del("IAX/Registry", peer->name);
06178    register_peer_exten(peer, 0);
06179    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06180    if (iax2_regfunk)
06181       iax2_regfunk(peer->name, 0);
06182 
06183    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06184       unlink_peer(peer);
06185 
06186    peer_unref(peer);
06187 }
06188 
06189 static int expire_registry(const void *data)
06190 {
06191 #ifdef SCHED_MULTITHREADED
06192    if (schedule_action(__expire_registry, data))
06193 #endif      
06194       __expire_registry(data);
06195    return 0;
06196 }
06197 
06198 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06199 
06200 static void reg_source_db(struct iax2_peer *p)
06201 {
06202    char data[80];
06203    struct in_addr in;
06204    char *c, *d;
06205    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06206       c = strchr(data, ':');
06207       if (c) {
06208          *c = '\0';
06209          c++;
06210          if (inet_aton(data, &in)) {
06211             d = strchr(c, ':');
06212             if (d) {
06213                *d = '\0';
06214                d++;
06215                if (option_verbose > 2)
06216                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06217                   ast_inet_ntoa(in), atoi(c), atoi(d));
06218                iax2_poke_peer(p, 0);
06219                p->expiry = atoi(d);
06220                memset(&p->addr, 0, sizeof(p->addr));
06221                p->addr.sin_family = AF_INET;
06222                p->addr.sin_addr = in;
06223                p->addr.sin_port = htons(atoi(c));
06224                if (p->expire > -1) {
06225                   if (!ast_sched_del(sched, p->expire)) {
06226                      p->expire = -1;
06227                      peer_unref(p);
06228                   }
06229                }
06230                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06231                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06232                if (p->expire == -1)
06233                   peer_unref(p);
06234                if (iax2_regfunk)
06235                   iax2_regfunk(p->name, 1);
06236                register_peer_exten(p, 1);
06237             }              
06238                
06239          }
06240       }
06241    }
06242 }
06243 
06244 /*!
06245  * \pre iaxsl[callno] is locked
06246  *
06247  * \note Since this function calls send_command_final(), the pvt struct for
06248  *       the given call number may disappear while executing this function.
06249  */
06250 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06251 {
06252    /* Called from IAX thread only, with proper iaxsl lock */
06253    struct iax_ie_data ied;
06254    struct iax2_peer *p;
06255    int msgcount;
06256    char data[80];
06257    int version;
06258    const char *peer_name;
06259    int res = -1;
06260 
06261    memset(&ied, 0, sizeof(ied));
06262 
06263    peer_name = ast_strdupa(iaxs[callno]->peer);
06264 
06265    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06266    ast_mutex_unlock(&iaxsl[callno]);
06267    if (!(p = find_peer(peer_name, 1))) {
06268       ast_mutex_lock(&iaxsl[callno]);
06269       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06270       return -1;
06271    }
06272    ast_mutex_lock(&iaxsl[callno]);
06273    if (!iaxs[callno])
06274       goto return_unref;
06275 
06276    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06277       if (sin->sin_addr.s_addr) {
06278          time_t nowtime;
06279          time(&nowtime);
06280          realtime_update_peer(peer_name, sin, nowtime);
06281       } else {
06282          realtime_update_peer(peer_name, sin, 0);
06283       }
06284    }
06285    if (inaddrcmp(&p->addr, sin)) {
06286       if (iax2_regfunk)
06287          iax2_regfunk(p->name, 1);
06288       /* Stash the IP address from which they registered */
06289       memcpy(&p->addr, sin, sizeof(p->addr));
06290       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06291       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06292          ast_db_put("IAX/Registry", p->name, data);
06293          if  (option_verbose > 2)
06294             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06295                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06296          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06297          register_peer_exten(p, 1);
06298          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06299       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06300          if  (option_verbose > 2)
06301             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06302                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06303          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06304          register_peer_exten(p, 0);
06305          ast_db_del("IAX/Registry", p->name);
06306          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06307       }
06308       /* Update the host */
06309       /* Verify that the host is really there */
06310       iax2_poke_peer(p, callno);
06311    }     
06312 
06313    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06314    if (!iaxs[callno]) {
06315       res = -1;
06316       goto return_unref;
06317    }
06318 
06319    /* Store socket fd */
06320    p->sockfd = fd;
06321    /* Setup the expiry */
06322    if (p->expire > -1) {
06323       if (!ast_sched_del(sched, p->expire)) {
06324          p->expire = -1;
06325          peer_unref(p);
06326       }
06327    }
06328    /* treat an unspecified refresh interval as the minimum */
06329    if (!refresh)
06330       refresh = min_reg_expire;
06331    if (refresh > max_reg_expire) {
06332       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06333          p->name, max_reg_expire, refresh);
06334       p->expiry = max_reg_expire;
06335    } else if (refresh < min_reg_expire) {
06336       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06337          p->name, min_reg_expire, refresh);
06338       p->expiry = min_reg_expire;
06339    } else {
06340       p->expiry = refresh;
06341    }
06342    if (p->expiry && sin->sin_addr.s_addr) {
06343       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06344       if (p->expire == -1)
06345          peer_unref(p);
06346    }
06347    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06348    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06349    if (sin->sin_addr.s_addr) {
06350       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06351       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06352       if (!ast_strlen_zero(p->mailbox)) {
06353          int new, old;
06354          ast_app_inboxcount(p->mailbox, &new, &old);
06355          if (new > 255)
06356             new = 255;
06357          if (old > 255)
06358             old = 255;
06359          msgcount = (old << 8) | new;
06360          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06361       }
06362       if (ast_test_flag(p, IAX_HASCALLERID)) {
06363          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06364          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06365       }
06366    }
06367    version = iax_check_version(devtype);
06368    if (version) 
06369       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06370 
06371    res = 0;
06372 
06373 return_unref:
06374    peer_unref(p);
06375 
06376    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06377 }
06378 
06379 static int registry_authrequest(int callno)
06380 {
06381    struct iax_ie_data ied;
06382    struct iax2_peer *p;
06383    char challenge[10];
06384    const char *peer_name;
06385    int sentauthmethod;
06386 
06387    peer_name = ast_strdupa(iaxs[callno]->peer);
06388 
06389    /* SLD: third call to find_peer in registration */
06390    ast_mutex_unlock(&iaxsl[callno]);
06391    if ((p = find_peer(peer_name, 1))) {
06392       last_authmethod = p->authmethods;
06393    }
06394 
06395    ast_mutex_lock(&iaxsl[callno]);
06396    if (!iaxs[callno])
06397       goto return_unref;
06398 
06399    memset(&ied, 0, sizeof(ied));
06400    /* The selection of which delayed reject is sent may leak information,
06401     * if it sets a static response.  For example, if a host is known to only
06402     * use MD5 authentication, then an RSA response would indicate that the
06403     * peer does not exist, and vice-versa.
06404     * Therefore, we use whatever the last peer used (which may vary over the
06405     * course of a server, which should leak minimal information). */
06406    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06407    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06408    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06409       /* Build the challenge */
06410       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06411       ast_string_field_set(iaxs[callno], challenge, challenge);
06412       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06413    }
06414    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06415 
06416 return_unref:
06417    if (p) {
06418       peer_unref(p);
06419    }
06420 
06421    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06422 }
06423 
06424 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06425 {
06426    struct iax2_registry *reg;
06427    /* Start pessimistic */
06428    struct iax_ie_data ied;
06429    char peer[256] = "";
06430    char challenge[256] = "";
06431    int res;
06432    int authmethods = 0;
06433    if (ies->authmethods)
06434       authmethods = ies->authmethods;
06435    if (ies->username)
06436       ast_copy_string(peer, ies->username, sizeof(peer));
06437    if (ies->challenge)
06438       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06439    memset(&ied, 0, sizeof(ied));
06440    reg = iaxs[callno]->reg;
06441    if (reg) {
06442          if (inaddrcmp(&reg->addr, sin)) {
06443             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06444             return -1;
06445          }
06446          if (ast_strlen_zero(reg->secret)) {
06447             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06448             reg->regstate = REG_STATE_NOAUTH;
06449             return -1;
06450          }
06451          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06452          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06453          if (reg->secret[0] == '[') {
06454             char tmpkey[256];
06455             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06456             tmpkey[strlen(tmpkey) - 1] = '\0';
06457             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06458          } else
06459             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06460          if (!res) {
06461             reg->regstate = REG_STATE_AUTHSENT;
06462             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06463          } else
06464             return -1;
06465          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06466    } else   
06467       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06468    return -1;
06469 }
06470 
06471 static void stop_stuff(int callno)
06472 {
06473    iax2_destroy_helper(iaxs[callno]);
06474 }
06475 
06476 static void __auth_reject(const void *nothing)
06477 {
06478    /* Called from IAX thread only, without iaxs lock */
06479    int callno = (int)(long)(nothing);
06480    struct iax_ie_data ied;
06481    ast_mutex_lock(&iaxsl[callno]);
06482    if (iaxs[callno]) {
06483       memset(&ied, 0, sizeof(ied));
06484       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06485          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06486          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06487       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06488          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06489          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06490       }
06491       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06492    }
06493    ast_mutex_unlock(&iaxsl[callno]);
06494 }
06495 
06496 static int auth_reject(const void *data)
06497 {
06498    int callno = (int)(long)(data);
06499    ast_mutex_lock(&iaxsl[callno]);
06500    if (iaxs[callno])
06501       iaxs[callno]->authid = -1;
06502    ast_mutex_unlock(&iaxsl[callno]);
06503 #ifdef SCHED_MULTITHREADED
06504    if (schedule_action(__auth_reject, data))
06505 #endif      
06506       __auth_reject(data);
06507    return 0;
06508 }
06509 
06510 static int auth_fail(int callno, int failcode)
06511 {
06512    /* Schedule sending the authentication failure in one second, to prevent
06513       guessing */
06514    if (iaxs[callno]) {
06515       iaxs[callno]->authfail = failcode;
06516       if (delayreject) {
06517          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06518          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06519       } else
06520          auth_reject((void *)(long)callno);
06521    }
06522    return 0;
06523 }
06524 
06525 static void __auto_hangup(const void *nothing)
06526 {
06527    /* Called from IAX thread only, without iaxs lock */
06528    int callno = (int)(long)(nothing);
06529    struct iax_ie_data ied;
06530    ast_mutex_lock(&iaxsl[callno]);
06531    if (iaxs[callno]) {
06532       memset(&ied, 0, sizeof(ied));
06533       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06534       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06535       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06536    }
06537    ast_mutex_unlock(&iaxsl[callno]);
06538 }
06539 
06540 static int auto_hangup(const void *data)
06541 {
06542    int callno = (int)(long)(data);
06543    ast_mutex_lock(&iaxsl[callno]);
06544    if (iaxs[callno]) {
06545       iaxs[callno]->autoid = -1;
06546    }
06547    ast_mutex_unlock(&iaxsl[callno]);
06548 #ifdef SCHED_MULTITHREADED
06549    if (schedule_action(__auto_hangup, data))
06550 #endif      
06551       __auto_hangup(data);
06552    return 0;
06553 }
06554 
06555 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06556 {
06557    struct iax_ie_data ied;
06558    /* Auto-hangup with 30 seconds of inactivity */
06559    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06560    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06561    memset(&ied, 0, sizeof(ied));
06562    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06563    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06564    dp->flags |= CACHE_FLAG_TRANSMITTED;
06565 }
06566 
06567 static int iax2_vnak(int callno)
06568 {
06569    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06570 }
06571 
06572 static void vnak_retransmit(int callno, int last)
06573 {
06574    struct iax_frame *f;
06575 
06576    AST_LIST_LOCK(&iaxq.queue);
06577    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06578       /* Send a copy immediately */
06579       if ((f->callno == callno) && iaxs[f->callno] &&
06580          ((unsigned char ) (f->oseqno - last) < 128) &&
06581          (f->retries >= 0)) {
06582          send_packet(f);
06583       }
06584    }
06585    AST_LIST_UNLOCK(&iaxq.queue);
06586 }
06587 
06588 static void __iax2_poke_peer_s(const void *data)
06589 {
06590    struct iax2_peer *peer = (struct iax2_peer *)data;
06591    iax2_poke_peer(peer, 0);
06592    peer_unref(peer);
06593 }
06594 
06595 static int iax2_poke_peer_s(const void *data)
06596 {
06597    struct iax2_peer *peer = (struct iax2_peer *)data;
06598    peer->pokeexpire = -1;
06599 #ifdef SCHED_MULTITHREADED
06600    if (schedule_action(__iax2_poke_peer_s, data))
06601 #endif      
06602       __iax2_poke_peer_s(data);
06603    return 0;
06604 }
06605 
06606 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06607 {
06608    int res = 0;
06609    struct iax_frame *fr;
06610    struct ast_iax2_meta_hdr *meta;
06611    struct ast_iax2_meta_trunk_hdr *mth;
06612    int calls = 0;
06613    
06614    /* Point to frame */
06615    fr = (struct iax_frame *)tpeer->trunkdata;
06616    /* Point to meta data */
06617    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06618    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06619    if (tpeer->trunkdatalen) {
06620       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06621       meta->zeros = 0;
06622       meta->metacmd = IAX_META_TRUNK;
06623       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06624          meta->cmddata = IAX_META_TRUNK_MINI;
06625       else
06626          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06627       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06628       /* And the rest of the ast_iax2 header */
06629       fr->direction = DIRECTION_OUTGRESS;
06630       fr->retrans = -1;
06631       fr->transfer = 0;
06632       /* Any appropriate call will do */
06633       fr->data = fr->afdata;
06634       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06635       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06636       calls = tpeer->calls;
06637 #if 0
06638       if (option_debug)
06639          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));
06640 #endif      
06641       /* Reset transmit trunk side data */
06642       tpeer->trunkdatalen = 0;
06643       tpeer->calls = 0;
06644    }
06645    if (res < 0)
06646       return res;
06647    return calls;
06648 }
06649 
06650 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06651 {
06652    /* Drop when trunk is about 5 seconds idle */
06653    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06654       return 1;
06655    return 0;
06656 }
06657 
06658 static int timing_read(int *id, int fd, short events, void *cbdata)
06659 {
06660    char buf[1024];
06661    int res;
06662    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06663    int processed = 0;
06664    int totalcalls = 0;
06665 #ifdef DAHDI_TIMERACK
06666    int x = 1;
06667 #endif
06668    struct timeval now;
06669    if (iaxtrunkdebug)
06670       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06671    gettimeofday(&now, NULL);
06672    if (events & AST_IO_PRI) {
06673 #ifdef DAHDI_TIMERACK
06674       /* Great, this is a timing interface, just call the ioctl */
06675       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
06676          ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
06677          usleep(1);
06678          return -1;
06679       }
06680 #endif      
06681    } else {
06682       /* Read and ignore from the pseudo channel for timing */
06683       res = read(fd, buf, sizeof(buf));
06684       if (res < 1) {
06685          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06686          return 1;
06687       }
06688    }
06689    /* For each peer that supports trunking... */
06690    ast_mutex_lock(&tpeerlock);
06691    tpeer = tpeers;
06692    while(tpeer) {
06693       processed++;
06694       res = 0;
06695       ast_mutex_lock(&tpeer->lock);
06696       /* We can drop a single tpeer per pass.  That makes all this logic
06697          substantially easier */
06698       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06699          /* Take it out of the list, but don't free it yet, because it
06700             could be in use */
06701          if (prev)
06702             prev->next = tpeer->next;
06703          else
06704             tpeers = tpeer->next;
06705          drop = tpeer;
06706       } else {
06707          res = send_trunk(tpeer, &now);
06708          if (iaxtrunkdebug)
06709             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);
06710       }     
06711       totalcalls += res;   
06712       res = 0;
06713       ast_mutex_unlock(&tpeer->lock);
06714       prev = tpeer;
06715       tpeer = tpeer->next;
06716    }
06717    ast_mutex_unlock(&tpeerlock);
06718    if (drop) {
06719       ast_mutex_lock(&drop->lock);
06720       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06721          because by the time they could get tpeerlock, we've already grabbed it */
06722       if (option_debug)
06723          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06724       if (drop->trunkdata) {
06725          free(drop->trunkdata);
06726          drop->trunkdata = NULL;
06727       }
06728       ast_mutex_unlock(&drop->lock);
06729       ast_mutex_destroy(&drop->lock);
06730       free(drop);
06731       
06732    }
06733    if (iaxtrunkdebug)
06734       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06735    iaxtrunkdebug =0;
06736    return 1;
06737 }
06738 
06739 struct dpreq_data {
06740    int callno;
06741    char context[AST_MAX_EXTENSION];
06742    char callednum[AST_MAX_EXTENSION];
06743    char *callerid;
06744 };
06745 
06746 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06747 {
06748    unsigned short dpstatus = 0;
06749    struct iax_ie_data ied1;
06750    int mm;
06751 
06752    memset(&ied1, 0, sizeof(ied1));
06753    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06754    /* Must be started */
06755    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06756       dpstatus = IAX_DPSTATUS_EXISTS;
06757    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06758       dpstatus = IAX_DPSTATUS_CANEXIST;
06759    } else {
06760       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06761    }
06762    if (ast_ignore_pattern(context, callednum))
06763       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06764    if (mm)
06765       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06766    if (!skiplock)
06767       ast_mutex_lock(&iaxsl[callno]);
06768    if (iaxs[callno]) {
06769       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06770       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06771       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06772       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06773    }
06774    if (!skiplock)
06775       ast_mutex_unlock(&iaxsl[callno]);
06776 }
06777 
06778 static void *dp_lookup_thread(void *data)
06779 {
06780    /* Look up for dpreq */
06781    struct dpreq_data *dpr = data;
06782    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06783    if (dpr->callerid)
06784       free(dpr->callerid);
06785    free(dpr);
06786    return NULL;
06787 }
06788 
06789 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06790 {
06791    pthread_t newthread;
06792    struct dpreq_data *dpr;
06793    pthread_attr_t attr;
06794    
06795    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06796       return;
06797 
06798    pthread_attr_init(&attr);
06799    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06800 
06801    dpr->callno = callno;
06802    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06803    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06804    if (callerid)
06805       dpr->callerid = ast_strdup(callerid);
06806    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06807       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06808    }
06809 
06810    pthread_attr_destroy(&attr);
06811 }
06812 
06813 struct iax_dual {
06814    struct ast_channel *chan1;
06815    struct ast_channel *chan2;
06816 };
06817 
06818 static void *iax_park_thread(void *stuff)
06819 {
06820    struct ast_channel *chan1, *chan2;
06821    struct iax_dual *d;
06822    struct ast_frame *f;
06823    int ext;
06824    int res;
06825    d = stuff;
06826    chan1 = d->chan1;
06827    chan2 = d->chan2;
06828    free(d);
06829    f = ast_read(chan1);
06830    if (f)
06831       ast_frfree(f);
06832    res = ast_park_call(chan1, chan2, 0, &ext);
06833    ast_hangup(chan2);
06834    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06835    return NULL;
06836 }
06837 
06838 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06839 {
06840    struct iax_dual *d;
06841    struct ast_channel *chan1m, *chan2m;
06842    pthread_t th;
06843    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06844    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06845    if (chan2m && chan1m) {
06846       /* Make formats okay */
06847       chan1m->readformat = chan1->readformat;
06848       chan1m->writeformat = chan1->writeformat;
06849       ast_channel_masquerade(chan1m, chan1);
06850       /* Setup the extensions and such */
06851       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06852       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06853       chan1m->priority = chan1->priority;
06854       
06855       /* We make a clone of the peer channel too, so we can play
06856          back the announcement */
06857       /* Make formats okay */
06858       chan2m->readformat = chan2->readformat;
06859       chan2m->writeformat = chan2->writeformat;
06860       ast_channel_masquerade(chan2m, chan2);
06861       /* Setup the extensions and such */
06862       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06863       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06864       chan2m->priority = chan2->priority;
06865       if (ast_do_masquerade(chan2m)) {
06866          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06867          ast_hangup(chan2m);
06868          return -1;
06869       }
06870    } else {
06871       if (chan1m)
06872          ast_hangup(chan1m);
06873       if (chan2m)
06874          ast_hangup(chan2m);
06875       return -1;
06876    }
06877    if ((d = ast_calloc(1, sizeof(*d)))) {
06878       pthread_attr_t attr;
06879 
06880       pthread_attr_init(&attr);
06881       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06882 
06883       d->chan1 = chan1m;
06884       d->chan2 = chan2m;
06885       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06886          pthread_attr_destroy(&attr);
06887          return 0;
06888       }
06889       pthread_attr_destroy(&attr);
06890       free(d);
06891    }
06892    return -1;
06893 }
06894 
06895 
06896 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06897 
06898 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06899 {
06900    unsigned int ourver;
06901    char rsi[80];
06902    snprintf(rsi, sizeof(rsi), "si-%s", si);
06903    if (iax_provision_version(&ourver, rsi, 1))
06904       return 0;
06905    if (option_debug)
06906       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06907    if (ourver != ver) 
06908       iax2_provision(sin, sockfd, NULL, rsi, 1);
06909    return 0;
06910 }
06911 
06912 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06913 {
06914    jb_info stats;
06915    jb_getinfo(pvt->jb, &stats);
06916    
06917    memset(iep, 0, sizeof(*iep));
06918 
06919    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06920    if(stats.frames_in == 0) stats.frames_in = 1;
06921    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06922    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06923    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06924    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06925    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06926 }
06927 
06928 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06929 {
06930    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06931    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06932    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06933    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06934    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06935    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06936    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06937 }
06938 
06939 static int socket_process(struct iax2_thread *thread);
06940 
06941 /*!
06942  * \brief Handle any deferred full frames for this thread
06943  */
06944 static void handle_deferred_full_frames(struct iax2_thread *thread)
06945 {
06946    struct iax2_pkt_buf *pkt_buf;
06947 
06948    ast_mutex_lock(&thread->lock);
06949 
06950    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06951       ast_mutex_unlock(&thread->lock);
06952 
06953       thread->buf = pkt_buf->buf;
06954       thread->buf_len = pkt_buf->len;
06955       thread->buf_size = pkt_buf->len + 1;
06956       
06957       socket_process(thread);
06958 
06959       thread->buf = NULL;
06960       ast_free(pkt_buf);
06961 
06962       ast_mutex_lock(&thread->lock);
06963    }
06964 
06965    ast_mutex_unlock(&thread->lock);
06966 }
06967 
06968 /*!
06969  * \brief Queue the last read full frame for processing by a certain thread
06970  *
06971  * If there are already any full frames queued, they are sorted
06972  * by sequence number.
06973  */
06974 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06975 {
06976    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06977    struct ast_iax2_full_hdr *fh, *cur_fh;
06978 
06979    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06980       return;
06981 
06982    pkt_buf->len = from_here->buf_len;
06983    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06984 
06985    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06986    ast_mutex_lock(&to_here->lock);
06987    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06988       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06989       if (fh->oseqno < cur_fh->oseqno) {
06990          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06991          break;
06992       }
06993    }
06994    AST_LIST_TRAVERSE_SAFE_END
06995 
06996    if (!cur_pkt_buf)
06997       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06998    
06999    ast_mutex_unlock(&to_here->lock);
07000 }
07001 
07002 static int socket_read(int *id, int fd, short events, void *cbdata)
07003 {
07004    struct iax2_thread *thread;
07005    socklen_t len;
07006    time_t t;
07007    static time_t last_errtime = 0;
07008    struct ast_iax2_full_hdr *fh;
07009 
07010    if (!(thread = find_idle_thread())) {
07011       time(&t);
07012       if (t != last_errtime && option_debug)
07013          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
07014       last_errtime = t;
07015       usleep(1);
07016       return 1;
07017    }
07018 
07019    len = sizeof(thread->iosin);
07020    thread->iofd = fd;
07021    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07022    thread->buf_size = sizeof(thread->readbuf);
07023    thread->buf = thread->readbuf;
07024    if (thread->buf_len < 0) {
07025       if (errno != ECONNREFUSED && errno != EAGAIN)
07026          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07027       handle_error();
07028       thread->iostate = IAX_IOSTATE_IDLE;
07029       signal_condition(&thread->lock, &thread->cond);
07030       return 1;
07031    }
07032    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
07033       thread->iostate = IAX_IOSTATE_IDLE;
07034       signal_condition(&thread->lock, &thread->cond);
07035       return 1;
07036    }
07037    
07038    /* Determine if this frame is a full frame; if so, and any thread is currently
07039       processing a full frame for the same callno from this peer, then drop this
07040       frame (and the peer will retransmit it) */
07041    fh = (struct ast_iax2_full_hdr *) thread->buf;
07042    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
07043       struct iax2_thread *cur = NULL;
07044       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
07045       
07046       AST_LIST_LOCK(&active_list);
07047       AST_LIST_TRAVERSE(&active_list, cur, list) {
07048          if ((cur->ffinfo.callno == callno) &&
07049              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
07050             break;
07051       }
07052       if (cur) {
07053          /* we found another thread processing a full frame for this call,
07054             so queue it up for processing later. */
07055          defer_full_frame(thread, cur);
07056          AST_LIST_UNLOCK(&active_list);
07057          thread->iostate = IAX_IOSTATE_IDLE;
07058          signal_condition(&thread->lock, &thread->cond);
07059          return 1;
07060       } else {
07061          /* this thread is going to process this frame, so mark it */
07062          thread->ffinfo.callno = callno;
07063          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
07064          thread->ffinfo.type = fh->type;
07065          thread->ffinfo.csub = fh->csub;
07066       }
07067       AST_LIST_UNLOCK(&active_list);
07068    }
07069    
07070    /* Mark as ready and send on its way */
07071    thread->iostate = IAX_IOSTATE_READY;
07072 #ifdef DEBUG_SCHED_MULTITHREAD
07073    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07074 #endif
07075    signal_condition(&thread->lock, &thread->cond);
07076 
07077    return 1;
07078 }
07079 
07080 static int socket_process(struct iax2_thread *thread)
07081 {
07082    struct sockaddr_in sin;
07083    int res;
07084    int updatehistory=1;
07085    int new = NEW_PREVENT;
07086    void *ptr;
07087    int dcallno = 0;
07088    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07089    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07090    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07091    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07092    struct ast_iax2_meta_trunk_hdr *mth;
07093    struct ast_iax2_meta_trunk_entry *mte;
07094    struct ast_iax2_meta_trunk_mini *mtm;
07095    struct iax_frame *fr;
07096    struct iax_frame *cur;
07097    struct ast_frame f = { 0, };
07098    struct ast_channel *c;
07099    struct iax2_dpcache *dp;
07100    struct iax2_peer *peer;
07101    struct iax2_trunk_peer *tpeer;
07102    struct timeval rxtrunktime;
07103    struct iax_ies ies;
07104    struct iax_ie_data ied0, ied1;
07105    int format;
07106    int fd;
07107    int exists;
07108    int minivid = 0;
07109    unsigned int ts;
07110    char empty[32]="";      /* Safety measure */
07111    struct iax_frame *duped_fr;
07112    char host_pref_buf[128];
07113    char caller_pref_buf[128];
07114    struct ast_codec_pref pref;
07115    char *using_prefs = "mine";
07116 
07117    /* allocate an iax_frame with 4096 bytes of data buffer */
07118    fr = alloca(sizeof(*fr) + 4096);
07119    memset(fr, 0, sizeof(*fr));
07120    fr->afdatalen = 4096; /* From alloca() above */
07121 
07122    /* Copy frequently used parameters to the stack */
07123    res = thread->buf_len;
07124    fd = thread->iofd;
07125    memcpy(&sin, &thread->iosin, sizeof(sin));
07126 
07127    if (res < sizeof(*mh)) {
07128       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07129       return 1;
07130    }
07131    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07132       if (res < sizeof(*vh)) {
07133          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));
07134          return 1;
07135       }
07136 
07137       /* This is a video frame, get call number */
07138       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07139       minivid = 1;
07140    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07141       unsigned char metatype;
07142 
07143       if (res < sizeof(*meta)) {
07144          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));
07145          return 1;
07146       }
07147 
07148       /* This is a meta header */
07149       switch(meta->metacmd) {
07150       case IAX_META_TRUNK:
07151          if (res < (sizeof(*meta) + sizeof(*mth))) {
07152             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07153                sizeof(*meta) + sizeof(*mth));
07154             return 1;
07155          }
07156          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07157          ts = ntohl(mth->ts);
07158          metatype = meta->cmddata;
07159          res -= (sizeof(*meta) + sizeof(*mth));
07160          ptr = mth->data;
07161          tpeer = find_tpeer(&sin, fd);
07162          if (!tpeer) {
07163             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));
07164             return 1;
07165          }
07166          tpeer->trunkact = ast_tvnow();
07167          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07168             tpeer->rxtrunktime = tpeer->trunkact;
07169          rxtrunktime = tpeer->rxtrunktime;
07170          ast_mutex_unlock(&tpeer->lock);
07171          while(res >= sizeof(*mte)) {
07172             /* Process channels */
07173             unsigned short callno, trunked_ts, len;
07174 
07175             if (metatype == IAX_META_TRUNK_MINI) {
07176                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07177                ptr += sizeof(*mtm);
07178                res -= sizeof(*mtm);
07179                len = ntohs(mtm->len);
07180                callno = ntohs(mtm->mini.callno);
07181                trunked_ts = ntohs(mtm->mini.ts);
07182             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07183                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07184                ptr += sizeof(*mte);
07185                res -= sizeof(*mte);
07186                len = ntohs(mte->len);
07187                callno = ntohs(mte->callno);
07188                trunked_ts = 0;
07189             } else {
07190                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07191                break;
07192             }
07193             /* Stop if we don't have enough data */
07194             if (len > res)
07195                break;
07196             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07197             if (fr->callno) {
07198                /* If it's a valid call, deliver the contents.  If not, we
07199                   drop it, since we don't have a scallno to use for an INVAL */
07200                /* Process as a mini frame */
07201                memset(&f, 0, sizeof(f));
07202                f.frametype = AST_FRAME_VOICE;
07203                if (iaxs[fr->callno]) {
07204                   if (iaxs[fr->callno]->voiceformat > 0) {
07205                      f.subclass = iaxs[fr->callno]->voiceformat;
07206                      f.datalen = len;
07207                      if (f.datalen >= 0) {
07208                         if (f.datalen)
07209                            f.data = ptr;
07210                         if(trunked_ts) {
07211                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07212                         } else
07213                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07214                         /* Don't pass any packets until we're started */
07215                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07216                            /* Common things */
07217                            f.src = "IAX2";
07218                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07219                               f.samples = ast_codec_get_samples(&f);
07220                            iax_frame_wrap(fr, &f);
07221                            duped_fr = iaxfrdup2(fr);
07222                            if (duped_fr) {
07223                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07224                            }
07225                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07226                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07227                               iaxs[fr->callno]->last = fr->ts;
07228 #if 1
07229                               if (option_debug && iaxdebug)
07230                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07231 #endif
07232                            }
07233                         }
07234                      } else {
07235                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07236                      }
07237                   } else {
07238                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
07239                      iax2_vnak(fr->callno);
07240                   }
07241                }
07242                ast_mutex_unlock(&iaxsl[fr->callno]);
07243             }
07244             ptr += len;
07245             res -= len;
07246          }
07247          
07248       }
07249       return 1;
07250    }
07251 
07252 #ifdef DEBUG_SUPPORT
07253    if (iaxdebug && (res >= sizeof(*fh)))
07254       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07255 #endif
07256    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07257       if (res < sizeof(*fh)) {
07258          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));
07259          return 1;
07260       }
07261 
07262       /* Get the destination call number */
07263       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07264       /* Retrieve the type and subclass */
07265       f.frametype = fh->type;
07266       if (f.frametype == AST_FRAME_VIDEO) {
07267          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07268       } else {
07269          f.subclass = uncompress_subclass(fh->csub);
07270       }
07271 
07272       /* Deal with POKE/PONG without allocating a callno */
07273       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07274          /* Reply back with a PONG, but don't care about the result. */
07275          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1);
07276          return 1;
07277       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07278          /* Ignore */
07279          return 1;
07280       }
07281 
07282       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07283                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07284                          (f.subclass == IAX_COMMAND_REGREL)))
07285          new = NEW_ALLOW;
07286    } else {
07287       /* Don't know anything about it yet */
07288       f.frametype = AST_FRAME_NULL;
07289       f.subclass = 0;
07290    }
07291 
07292    if (!fr->callno) {
07293       int check_dcallno = 0;
07294 
07295       /*
07296        * We enforce accurate destination call numbers for all full frames except
07297        * LAGRQ and PING commands.  This is because older versions of Asterisk
07298        * schedule these commands to get sent very quickly, and they will sometimes
07299        * be sent before they receive the first frame from the other side.  When
07300        * that happens, it doesn't contain the destination call number.  However,
07301        * not checking it for these frames is safe.
07302        * 
07303        * Discussed in the following thread:
07304        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07305        */
07306 
07307       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07308          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07309       }
07310 
07311       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07312    }
07313 
07314    if (fr->callno > 0)
07315       ast_mutex_lock(&iaxsl[fr->callno]);
07316 
07317    if (!fr->callno || !iaxs[fr->callno]) {
07318       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07319          frame, reply with an inval */
07320       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07321          /* We can only raw hangup control frames */
07322          if (((f.subclass != IAX_COMMAND_INVAL) &&
07323              (f.subclass != IAX_COMMAND_TXCNT) &&
07324              (f.subclass != IAX_COMMAND_TXACC) &&
07325              (f.subclass != IAX_COMMAND_FWDOWNL))||
07326              (f.frametype != AST_FRAME_IAX))
07327             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07328             fd);
07329       }
07330       if (fr->callno > 0) 
07331          ast_mutex_unlock(&iaxsl[fr->callno]);
07332       return 1;
07333    }
07334    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07335       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07336          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07337          ast_mutex_unlock(&iaxsl[fr->callno]);
07338          return 1;
07339       }
07340 #ifdef DEBUG_SUPPORT
07341       else if (iaxdebug)
07342          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07343 #endif
07344    }
07345 
07346    /* count this frame */
07347    iaxs[fr->callno]->frames_received++;
07348 
07349    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07350       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07351       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07352       unsigned short new_peercallno;
07353 
07354       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07355       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07356          if (iaxs[fr->callno]->peercallno) {
07357             remove_by_peercallno(iaxs[fr->callno]);
07358          }
07359          iaxs[fr->callno]->peercallno = new_peercallno;
07360          store_by_peercallno(iaxs[fr->callno]);
07361       }
07362    }
07363    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07364       if (option_debug  && iaxdebug)
07365          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07366       /* Check if it's out of order (and not an ACK or INVAL) */
07367       fr->oseqno = fh->oseqno;
07368       fr->iseqno = fh->iseqno;
07369       fr->ts = ntohl(fh->ts);
07370 #ifdef IAXTESTS
07371       if (test_resync) {
07372          if (option_debug)
07373             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07374          fr->ts += test_resync;
07375       }
07376 #endif /* IAXTESTS */
07377 #if 0
07378       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07379            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07380                         (f.subclass == IAX_COMMAND_NEW ||
07381                          f.subclass == IAX_COMMAND_AUTHREQ ||
07382                          f.subclass == IAX_COMMAND_ACCEPT ||
07383                          f.subclass == IAX_COMMAND_REJECT))      ) )
07384 #endif
07385       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07386          updatehistory = 0;
07387       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07388          (iaxs[fr->callno]->iseqno ||
07389             ((f.subclass != IAX_COMMAND_TXCNT) &&
07390             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07391             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07392             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07393             (f.subclass != IAX_COMMAND_TXACC)) ||
07394             (f.frametype != AST_FRAME_IAX))) {
07395          if (
07396           ((f.subclass != IAX_COMMAND_ACK) &&
07397            (f.subclass != IAX_COMMAND_INVAL) &&
07398            (f.subclass != IAX_COMMAND_TXCNT) &&
07399            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07400            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07401            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07402            (f.subclass != IAX_COMMAND_TXACC) &&
07403            (f.subclass != IAX_COMMAND_VNAK)) ||
07404            (f.frametype != AST_FRAME_IAX)) {
07405             /* If it's not an ACK packet, it's out of order. */
07406             if (option_debug)
07407                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07408                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07409             /* Check to see if we need to request retransmission,
07410              * and take sequence number wraparound into account */
07411             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07412                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07413                if ((f.frametype != AST_FRAME_IAX) || 
07414                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07415                   if (option_debug)
07416                      ast_log(LOG_DEBUG, "Acking anyway\n");
07417                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07418                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07419                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07420                }
07421             } else {
07422                /* Send a VNAK requesting retransmission */
07423                iax2_vnak(fr->callno);
07424             }
07425             ast_mutex_unlock(&iaxsl[fr->callno]);
07426             return 1;
07427          }
07428       } else {
07429          /* Increment unless it's an ACK or VNAK */
07430          if (((f.subclass != IAX_COMMAND_ACK) &&
07431              (f.subclass != IAX_COMMAND_INVAL) &&
07432              (f.subclass != IAX_COMMAND_TXCNT) &&
07433              (f.subclass != IAX_COMMAND_TXACC) &&
07434             (f.subclass != IAX_COMMAND_VNAK)) ||
07435              (f.frametype != AST_FRAME_IAX))
07436             iaxs[fr->callno]->iseqno++;
07437       }
07438       /* A full frame */
07439       if (res < sizeof(*fh)) {
07440          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07441          ast_mutex_unlock(&iaxsl[fr->callno]);
07442          return 1;
07443       }
07444       /* Ensure text frames are NULL-terminated */
07445       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07446          if (res < thread->buf_size)
07447             thread->buf[res++] = '\0';
07448          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07449             thread->buf[res - 1] = '\0';
07450       }
07451       f.datalen = res - sizeof(*fh);
07452 
07453       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07454          from the real peer, not the transfer peer */
07455       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07456           ((f.subclass != IAX_COMMAND_INVAL) ||
07457            (f.frametype != AST_FRAME_IAX))) {
07458          unsigned char x;
07459          int call_to_destroy;
07460          /* XXX This code is not very efficient.  Surely there is a better way which still
07461                 properly handles boundary conditions? XXX */
07462          /* First we have to qualify that the ACKed value is within our window */
07463          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07464             if (fr->iseqno == x)
07465                break;
07466          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07467             /* The acknowledgement is within our window.  Time to acknowledge everything
07468                that it says to */
07469             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07470                /* Ack the packet with the given timestamp */
07471                if (option_debug && iaxdebug)
07472                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07473                call_to_destroy = 0;
07474                AST_LIST_LOCK(&iaxq.queue);
07475                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07476                   /* If it's our call, and our timestamp, mark -1 retries */
07477                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07478                      cur->retries = -1;
07479                      /* Destroy call if this is the end */
07480                      if (cur->final)
07481                         call_to_destroy = fr->callno;
07482                   }
07483                }
07484                AST_LIST_UNLOCK(&iaxq.queue);
07485                if (call_to_destroy) {
07486                   if (iaxdebug && option_debug)
07487                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07488                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07489                   iax2_destroy(call_to_destroy);
07490                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07491                }
07492             }
07493             /* Note how much we've received acknowledgement for */
07494             if (iaxs[fr->callno])
07495                iaxs[fr->callno]->rseqno = fr->iseqno;
07496             else {
07497                /* Stop processing now */
07498                ast_mutex_unlock(&iaxsl[fr->callno]);
07499                return 1;
07500             }
07501          } else if (option_debug)
07502             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07503       }
07504       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07505          ((f.frametype != AST_FRAME_IAX) || 
07506           ((f.subclass != IAX_COMMAND_TXACC) &&
07507            (f.subclass != IAX_COMMAND_TXCNT)))) {
07508          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07509          ast_mutex_unlock(&iaxsl[fr->callno]);
07510          return 1;
07511       }
07512 
07513       if (f.datalen) {
07514          if (f.frametype == AST_FRAME_IAX) {
07515             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07516                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07517                ast_mutex_unlock(&iaxsl[fr->callno]);
07518                return 1;
07519             }
07520             f.data = NULL;
07521             f.datalen = 0;
07522          } else
07523             f.data = thread->buf + sizeof(*fh);
07524       } else {
07525          if (f.frametype == AST_FRAME_IAX)
07526             f.data = NULL;
07527          else
07528             f.data = empty;
07529          memset(&ies, 0, sizeof(ies));
07530       }
07531 
07532       /* when we receive the first full frame for a new incoming channel,
07533          it is safe to start the PBX on the channel because we have now
07534          completed a 3-way handshake with the peer */
07535       if ((f.frametype == AST_FRAME_VOICE) ||
07536           (f.frametype == AST_FRAME_VIDEO) ||
07537           (f.frametype == AST_FRAME_IAX)) {
07538          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07539             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07540             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07541                ast_mutex_unlock(&iaxsl[fr->callno]);
07542                return 1;
07543             }
07544          }
07545       }
07546 
07547       if (f.frametype == AST_FRAME_VOICE) {
07548          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07549                iaxs[fr->callno]->voiceformat = f.subclass;
07550                if (option_debug)
07551                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07552                if (iaxs[fr->callno]->owner) {
07553                   int orignative;
07554 retryowner:
07555                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07556                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07557                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07558                   }
07559                   if (iaxs[fr->callno]) {
07560                      if (iaxs[fr->callno]->owner) {
07561                         orignative = iaxs[fr->callno]->owner->nativeformats;
07562                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07563                         if (iaxs[fr->callno]->owner->readformat)
07564                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07565                         iaxs[fr->callno]->owner->nativeformats = orignative;
07566                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07567                      }
07568                   } else {
07569                      if (option_debug)
07570                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07571                      ast_mutex_unlock(&iaxsl[fr->callno]);
07572                      return 1;
07573                   }
07574                }
07575          }
07576       }
07577       if (f.frametype == AST_FRAME_VIDEO) {
07578          if (f.subclass != iaxs[fr->callno]->videoformat) {
07579             if (option_debug)
07580                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07581             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07582          }
07583       }
07584       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
07585          if (f.subclass == AST_CONTROL_BUSY) {
07586             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
07587          } else if (f.subclass == AST_CONTROL_CONGESTION) {
07588             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
07589          }
07590       }
07591       if (f.frametype == AST_FRAME_IAX) {
07592          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07593          /* Handle the IAX pseudo frame itself */
07594          if (option_debug && iaxdebug)
07595             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07596 
07597                         /* Update last ts unless the frame's timestamp originated with us. */
07598          if (iaxs[fr->callno]->last < fr->ts &&
07599                             f.subclass != IAX_COMMAND_ACK &&
07600                             f.subclass != IAX_COMMAND_PONG &&
07601                             f.subclass != IAX_COMMAND_LAGRP) {
07602             iaxs[fr->callno]->last = fr->ts;
07603             if (option_debug && iaxdebug)
07604                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07605          }
07606 
07607          switch(f.subclass) {
07608          case IAX_COMMAND_ACK:
07609             /* Do nothing */
07610             break;
07611          case IAX_COMMAND_QUELCH:
07612             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07613                     /* Generate Manager Hold event, if necessary*/
07614                if (iaxs[fr->callno]->owner) {
07615                   manager_event(EVENT_FLAG_CALL, "Hold",
07616                      "Channel: %s\r\n"
07617                      "Uniqueid: %s\r\n",
07618                      iaxs[fr->callno]->owner->name, 
07619                      iaxs[fr->callno]->owner->uniqueid);
07620                }
07621 
07622                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07623                if (ies.musiconhold) {
07624                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07625                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07626                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07627                         S_OR(mohsuggest, NULL),
07628                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07629                      if (!iaxs[fr->callno]) {
07630                         ast_mutex_unlock(&iaxsl[fr->callno]);
07631                         return 1;
07632                      }
07633                   }
07634                }
07635             }
07636             break;
07637          case IAX_COMMAND_UNQUELCH:
07638             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07639                     /* Generate Manager Unhold event, if necessary*/
07640                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07641                   manager_event(EVENT_FLAG_CALL, "Unhold",
07642                      "Channel: %s\r\n"
07643                      "Uniqueid: %s\r\n",
07644                      iaxs[fr->callno]->owner->name, 
07645                      iaxs[fr->callno]->owner->uniqueid);
07646                }
07647 
07648                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07649                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07650                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07651                   if (!iaxs[fr->callno]) {
07652                      ast_mutex_unlock(&iaxsl[fr->callno]);
07653                      return 1;
07654                   }
07655                }
07656             }
07657             break;
07658          case IAX_COMMAND_TXACC:
07659             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07660                /* Ack the packet with the given timestamp */
07661                AST_LIST_LOCK(&iaxq.queue);
07662                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07663                   /* Cancel any outstanding txcnt's */
07664                   if ((fr->callno == cur->callno) && (cur->transfer))
07665                      cur->retries = -1;
07666                }
07667                AST_LIST_UNLOCK(&iaxq.queue);
07668                memset(&ied1, 0, sizeof(ied1));
07669                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07670                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07671                iaxs[fr->callno]->transferring = TRANSFER_READY;
07672             }
07673             break;
07674          case IAX_COMMAND_NEW:
07675             /* Ignore if it's already up */
07676             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07677                break;
07678             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07679                ast_mutex_unlock(&iaxsl[fr->callno]);
07680                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07681                ast_mutex_lock(&iaxsl[fr->callno]);
07682                if (!iaxs[fr->callno]) {
07683                   ast_mutex_unlock(&iaxsl[fr->callno]);
07684                   return 1;
07685                }
07686             }
07687             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07688             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07689                int new_callno;
07690                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07691                   fr->callno = new_callno;
07692             }
07693             /* For security, always ack immediately */
07694             if (delayreject)
07695                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07696             if (check_access(fr->callno, &sin, &ies)) {
07697                /* They're not allowed on */
07698                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07699                if (authdebug)
07700                   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);
07701                break;
07702             }
07703             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07704                const char *context, *exten, *cid_num;
07705 
07706                context = ast_strdupa(iaxs[fr->callno]->context);
07707                exten = ast_strdupa(iaxs[fr->callno]->exten);
07708                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07709 
07710                /* This might re-enter the IAX code and need the lock */
07711                ast_mutex_unlock(&iaxsl[fr->callno]);
07712                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07713                ast_mutex_lock(&iaxsl[fr->callno]);
07714 
07715                if (!iaxs[fr->callno]) {
07716                   ast_mutex_unlock(&iaxsl[fr->callno]);
07717                   return 1;
07718                }
07719             } else
07720                exists = 0;
07721             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07722                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07723                   memset(&ied0, 0, sizeof(ied0));
07724                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07725                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07726                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07727                   if (!iaxs[fr->callno]) {
07728                      ast_mutex_unlock(&iaxsl[fr->callno]);
07729                      return 1;
07730                   }
07731                   if (authdebug)
07732                      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);
07733                } else {
07734                   /* Select an appropriate format */
07735 
07736                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07737                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07738                         using_prefs = "reqonly";
07739                      } else {
07740                         using_prefs = "disabled";
07741                      }
07742                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07743                      memset(&pref, 0, sizeof(pref));
07744                      strcpy(caller_pref_buf, "disabled");
07745                      strcpy(host_pref_buf, "disabled");
07746                   } else {
07747                      using_prefs = "mine";
07748                      /* If the information elements are in here... use them */
07749                      if (ies.codec_prefs)
07750                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07751                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07752                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07753                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07754                            pref = iaxs[fr->callno]->rprefs;
07755                            using_prefs = "caller";
07756                         } else {
07757                            pref = iaxs[fr->callno]->prefs;
07758                         }
07759                      } else
07760                         pref = iaxs[fr->callno]->prefs;
07761                      
07762                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07763                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07764                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07765                   }
07766                   if (!format) {
07767                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07768                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07769                      if (!format) {
07770                         memset(&ied0, 0, sizeof(ied0));
07771                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07772                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07773                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07774                         if (!iaxs[fr->callno]) {
07775                            ast_mutex_unlock(&iaxsl[fr->callno]);
07776                            return 1;
07777                         }
07778                         if (authdebug) {
07779                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07780                               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);
07781                            else 
07782                               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);
07783                         }
07784                      } else {
07785                         /* Pick one... */
07786                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07787                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07788                               format = 0;
07789                         } else {
07790                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07791                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07792                               memset(&pref, 0, sizeof(pref));
07793                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07794                               strcpy(caller_pref_buf,"disabled");
07795                               strcpy(host_pref_buf,"disabled");
07796                            } else {
07797                               using_prefs = "mine";
07798                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07799                                  /* Do the opposite of what we tried above. */
07800                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07801                                     pref = iaxs[fr->callno]->prefs;                       
07802                                  } else {
07803                                     pref = iaxs[fr->callno]->rprefs;
07804                                     using_prefs = "caller";
07805                                  }
07806                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07807                            
07808                               } else /* if no codec_prefs IE do it the old way */
07809                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07810                            }
07811                         }
07812 
07813                         if (!format) {
07814                            memset(&ied0, 0, sizeof(ied0));
07815                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07816                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07817                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07818                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07819                            if (!iaxs[fr->callno]) {
07820                               ast_mutex_unlock(&iaxsl[fr->callno]);
07821                               return 1;
07822                            }
07823                            if (authdebug)
07824                               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);
07825                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07826                            break;
07827                         }
07828                      }
07829                   }
07830                   if (format) {
07831                      /* No authentication required, let them in */
07832                      memset(&ied1, 0, sizeof(ied1));
07833                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07834                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07835                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07836                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07837                         if (option_verbose > 2) 
07838                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07839                                     "%srequested format = %s,\n"
07840                                     "%srequested prefs = %s,\n"
07841                                     "%sactual format = %s,\n"
07842                                     "%shost prefs = %s,\n"
07843                                     "%spriority = %s\n",
07844                                     ast_inet_ntoa(sin.sin_addr), 
07845                                     VERBOSE_PREFIX_4,
07846                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07847                                     VERBOSE_PREFIX_4,
07848                                     caller_pref_buf,
07849                                     VERBOSE_PREFIX_4,
07850                                     ast_getformatname(format), 
07851                                     VERBOSE_PREFIX_4,
07852                                     host_pref_buf, 
07853                                     VERBOSE_PREFIX_4,
07854                                     using_prefs);
07855                         
07856                         iaxs[fr->callno]->chosenformat = format;
07857                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07858                      } else {
07859                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07860                         /* If this is a TBD call, we're ready but now what...  */
07861                         if (option_verbose > 2)
07862                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07863                      }
07864                   }
07865                }
07866                break;
07867             }
07868             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07869                merge_encryption(iaxs[fr->callno],ies.encmethods);
07870             else
07871                iaxs[fr->callno]->encmethods = 0;
07872             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07873                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07874             if (!iaxs[fr->callno]) {
07875                ast_mutex_unlock(&iaxsl[fr->callno]);
07876                return 1;
07877             }
07878             break;
07879          case IAX_COMMAND_DPREQ:
07880             /* Request status in the dialplan */
07881             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07882                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07883                if (iaxcompat) {
07884                   /* Spawn a thread for the lookup */
07885                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07886                } else {
07887                   /* Just look it up */
07888                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07889                }
07890             }
07891             break;
07892          case IAX_COMMAND_HANGUP:
07893             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07894             if (option_debug)
07895                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07896             /* Set hangup cause according to remote */
07897             if (ies.causecode && iaxs[fr->callno]->owner)
07898                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07899             /* Send ack immediately, before we destroy */
07900             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07901             iax2_destroy(fr->callno);
07902             break;
07903          case IAX_COMMAND_REJECT:
07904             /* Set hangup cause according to remote */
07905             if (ies.causecode && iaxs[fr->callno]->owner)
07906                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07907 
07908             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07909                if (iaxs[fr->callno]->owner && authdebug)
07910                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07911                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07912                      ies.cause ? ies.cause : "<Unknown>");
07913                if (option_debug)
07914                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07915                      fr->callno);
07916             }
07917             /* Send ack immediately, before we destroy */
07918             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07919                          fr->ts, NULL, 0, fr->iseqno);
07920             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07921                iaxs[fr->callno]->error = EPERM;
07922             iax2_destroy(fr->callno);
07923             break;
07924          case IAX_COMMAND_TRANSFER:
07925          {
07926             struct ast_channel *bridged_chan;
07927 
07928             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07929                /* Set BLINDTRANSFER channel variables */
07930 
07931                ast_mutex_unlock(&iaxsl[fr->callno]);
07932                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07933                ast_mutex_lock(&iaxsl[fr->callno]);
07934                if (!iaxs[fr->callno]) {
07935                   ast_mutex_unlock(&iaxsl[fr->callno]);
07936                   return 1;
07937                }
07938 
07939                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07940                if (!strcmp(ies.called_number, ast_parking_ext())) {
07941                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
07942                   ast_mutex_unlock(&iaxsl[fr->callno]);
07943                   if (iax_park(bridged_chan, saved_channel)) {
07944                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07945                   } else {
07946                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07947                   }
07948                   ast_mutex_lock(&iaxsl[fr->callno]);
07949                } else {
07950                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07951                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07952                         ies.called_number, iaxs[fr->callno]->context);
07953                   else
07954                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07955                         ies.called_number, iaxs[fr->callno]->context);
07956                }
07957             } else
07958                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07959 
07960             break;
07961          }
07962          case IAX_COMMAND_ACCEPT:
07963             /* Ignore if call is already up or needs authentication or is a TBD */
07964             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07965                break;
07966             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07967                /* Send ack immediately, before we destroy */
07968                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07969                iax2_destroy(fr->callno);
07970                break;
07971             }
07972             if (ies.format) {
07973                iaxs[fr->callno]->peerformat = ies.format;
07974             } else {
07975                if (iaxs[fr->callno]->owner)
07976                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07977                else
07978                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07979             }
07980             if (option_verbose > 2)
07981                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));
07982             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07983                memset(&ied0, 0, sizeof(ied0));
07984                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07985                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07986                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07987                if (!iaxs[fr->callno]) {
07988                   ast_mutex_unlock(&iaxsl[fr->callno]);
07989                   return 1;
07990                }
07991                if (authdebug)
07992                   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);
07993             } else {
07994                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07995                if (iaxs[fr->callno]->owner) {
07996                   /* Switch us to use a compatible format */
07997                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07998                   if (option_verbose > 2)
07999                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
08000 retryowner2:
08001                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08002                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08003                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
08004                   }
08005                   
08006                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
08007                      /* Setup read/write formats properly. */
08008                      if (iaxs[fr->callno]->owner->writeformat)
08009                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
08010                      if (iaxs[fr->callno]->owner->readformat)
08011                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
08012                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08013                   }
08014                }
08015             }
08016             if (iaxs[fr->callno]) {
08017                ast_mutex_lock(&dpcache_lock);
08018                dp = iaxs[fr->callno]->dpentries;
08019                while(dp) {
08020                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
08021                      iax2_dprequest(dp, fr->callno);
08022                   }
08023                   dp = dp->peer;
08024                }
08025                ast_mutex_unlock(&dpcache_lock);
08026             }
08027             break;
08028          case IAX_COMMAND_POKE:
08029             /* Send back a pong packet with the original timestamp */
08030             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
08031             if (!iaxs[fr->callno]) {
08032                ast_mutex_unlock(&iaxsl[fr->callno]);
08033                return 1;
08034             }
08035             break;
08036          case IAX_COMMAND_PING:
08037          {
08038             struct iax_ie_data pingied;
08039             construct_rr(iaxs[fr->callno], &pingied);
08040             /* Send back a pong packet with the original timestamp */
08041             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
08042          }
08043             break;
08044          case IAX_COMMAND_PONG:
08045             /* Calculate ping time */
08046             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
08047             /* save RR info */
08048             save_rr(fr, &ies);
08049 
08050             if (iaxs[fr->callno]->peerpoke) {
08051                peer = iaxs[fr->callno]->peerpoke;
08052                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
08053                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
08054                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
08055                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08056                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08057                   }
08058                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
08059                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
08060                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
08061                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08062                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08063                   }
08064                }
08065                peer->lastms = iaxs[fr->callno]->pingtime;
08066                if (peer->smoothing && (peer->lastms > -1))
08067                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
08068                else if (peer->smoothing && peer->lastms < 0)
08069                   peer->historicms = (0 + peer->historicms) / 2;
08070                else              
08071                   peer->historicms = iaxs[fr->callno]->pingtime;
08072 
08073                /* Remove scheduled iax2_poke_noanswer */
08074                if (peer->pokeexpire > -1) {
08075                   if (!ast_sched_del(sched, peer->pokeexpire)) {
08076                      peer_unref(peer);
08077                      peer->pokeexpire = -1;
08078                   }
08079                }
08080                /* Schedule the next cycle */
08081                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
08082                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08083                else
08084                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08085                if (peer->pokeexpire == -1)
08086                   peer_unref(peer);
08087                /* and finally send the ack */
08088                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08089                /* And wrap up the qualify call */
08090                iax2_destroy(fr->callno);
08091                peer->callno = 0;
08092                if (option_debug)
08093                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08094             }
08095             break;
08096          case IAX_COMMAND_LAGRQ:
08097          case IAX_COMMAND_LAGRP:
08098             f.src = "LAGRQ";
08099             f.mallocd = 0;
08100             f.offset = 0;
08101             f.samples = 0;
08102             iax_frame_wrap(fr, &f);
08103             if(f.subclass == IAX_COMMAND_LAGRQ) {
08104                /* Received a LAGRQ - echo back a LAGRP */
08105                fr->af.subclass = IAX_COMMAND_LAGRP;
08106                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08107             } else {
08108                /* Received LAGRP in response to our LAGRQ */
08109                unsigned int ts;
08110                /* This is a reply we've been given, actually measure the difference */
08111                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08112                iaxs[fr->callno]->lag = ts - fr->ts;
08113                if (option_debug && iaxdebug)
08114                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08115                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08116             }
08117             break;
08118          case IAX_COMMAND_AUTHREQ:
08119             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08120                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>");
08121                break;
08122             }
08123             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08124                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08125                         .subclass = AST_CONTROL_HANGUP,
08126                };
08127                ast_log(LOG_WARNING, 
08128                   "I don't know how to authenticate %s to %s\n", 
08129                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08130                iax2_queue_frame(fr->callno, &hangup_fr);
08131             }
08132             if (!iaxs[fr->callno]) {
08133                ast_mutex_unlock(&iaxsl[fr->callno]);
08134                return 1;
08135             }
08136             break;
08137          case IAX_COMMAND_AUTHREP:
08138             /* For security, always ack immediately */
08139             if (delayreject)
08140                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08141             /* Ignore once we've started */
08142             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08143                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>");
08144                break;
08145             }
08146             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08147                if (authdebug)
08148                   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);
08149                memset(&ied0, 0, sizeof(ied0));
08150                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08151                break;
08152             }
08153             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08154                /* This might re-enter the IAX code and need the lock */
08155                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08156             } else
08157                exists = 0;
08158             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08159                if (authdebug)
08160                   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);
08161                memset(&ied0, 0, sizeof(ied0));
08162                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08163                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08164                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08165                if (!iaxs[fr->callno]) {
08166                   ast_mutex_unlock(&iaxsl[fr->callno]);
08167                   return 1;
08168                }
08169             } else {
08170                /* Select an appropriate format */
08171                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08172                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08173                      using_prefs = "reqonly";
08174                   } else {
08175                      using_prefs = "disabled";
08176                   }
08177                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08178                   memset(&pref, 0, sizeof(pref));
08179                   strcpy(caller_pref_buf, "disabled");
08180                   strcpy(host_pref_buf, "disabled");
08181                } else {
08182                   using_prefs = "mine";
08183                   if (ies.codec_prefs)
08184                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08185                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08186                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08187                         pref = iaxs[fr->callno]->rprefs;
08188                         using_prefs = "caller";
08189                      } else {
08190                         pref = iaxs[fr->callno]->prefs;
08191                      }
08192                   } else /* if no codec_prefs IE do it the old way */
08193                      pref = iaxs[fr->callno]->prefs;
08194                
08195                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08196                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08197                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08198                }
08199                if (!format) {
08200                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08201                      if (option_debug)
08202                         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);
08203                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08204                   }
08205                   if (!format) {
08206                      if (authdebug) {
08207                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08208                            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);
08209                         else
08210                            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);
08211                      }
08212                      memset(&ied0, 0, sizeof(ied0));
08213                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08214                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08215                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08216                      if (!iaxs[fr->callno]) {
08217                         ast_mutex_unlock(&iaxsl[fr->callno]);
08218                         return 1;
08219                      }
08220                   } else {
08221                      /* Pick one... */
08222                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08223                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08224                            format = 0;
08225                      } else {
08226                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08227                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08228                            memset(&pref, 0, sizeof(pref));
08229                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08230                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08231                            strcpy(caller_pref_buf,"disabled");
08232                            strcpy(host_pref_buf,"disabled");
08233                         } else {
08234                            using_prefs = "mine";
08235                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08236                               /* Do the opposite of what we tried above. */
08237                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08238                                  pref = iaxs[fr->callno]->prefs;                 
08239                               } else {
08240                                  pref = iaxs[fr->callno]->rprefs;
08241                                  using_prefs = "caller";
08242                               }
08243                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08244                            } else /* if no codec_prefs IE do it the old way */
08245                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08246                         }
08247                      }
08248                      if (!format) {
08249                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08250                         if (authdebug) {
08251                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08252                               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);
08253                            else
08254                               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);
08255                         }
08256                         memset(&ied0, 0, sizeof(ied0));
08257                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08258                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08259                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08260                         if (!iaxs[fr->callno]) {
08261                            ast_mutex_unlock(&iaxsl[fr->callno]);
08262                            return 1;
08263                         }
08264                      }
08265                   }
08266                }
08267                if (format) {
08268                   /* Authentication received */
08269                   memset(&ied1, 0, sizeof(ied1));
08270                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08271                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08272                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08273                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08274                      if (option_verbose > 2) 
08275                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08276                                  "%srequested format = %s,\n"
08277                                  "%srequested prefs = %s,\n"
08278                                  "%sactual format = %s,\n"
08279                                  "%shost prefs = %s,\n"
08280                                  "%spriority = %s\n", 
08281                                  ast_inet_ntoa(sin.sin_addr), 
08282                                  VERBOSE_PREFIX_4,
08283                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08284                                  VERBOSE_PREFIX_4,
08285                                  caller_pref_buf,
08286                                  VERBOSE_PREFIX_4,
08287                                  ast_getformatname(format),
08288                                  VERBOSE_PREFIX_4,
08289                                  host_pref_buf,
08290                                  VERBOSE_PREFIX_4,
08291                                  using_prefs);
08292 
08293                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08294                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08295                         iax2_destroy(fr->callno);
08296                   } else {
08297                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08298                      /* If this is a TBD call, we're ready but now what...  */
08299                      if (option_verbose > 2)
08300                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08301                   }
08302                }
08303             }
08304             break;
08305          case IAX_COMMAND_DIAL:
08306             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08307                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08308                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08309                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08310                   if (authdebug)
08311                      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);
08312                   memset(&ied0, 0, sizeof(ied0));
08313                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08314                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08315                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08316                   if (!iaxs[fr->callno]) {
08317                      ast_mutex_unlock(&iaxsl[fr->callno]);
08318                      return 1;
08319                   }
08320                } else {
08321                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08322                   if (option_verbose > 2) 
08323                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08324                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08325                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08326                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08327                      iax2_destroy(fr->callno);
08328                }
08329             }
08330             break;
08331          case IAX_COMMAND_INVAL:
08332             iaxs[fr->callno]->error = ENOTCONN;
08333             if (option_debug)
08334                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08335             iax2_destroy(fr->callno);
08336             if (option_debug)
08337                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08338             break;
08339          case IAX_COMMAND_VNAK:
08340             if (option_debug)
08341                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08342             /* Force retransmission */
08343             vnak_retransmit(fr->callno, fr->iseqno);
08344             break;
08345          case IAX_COMMAND_REGREQ:
08346          case IAX_COMMAND_REGREL:
08347             /* For security, always ack immediately */
08348             if (delayreject)
08349                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08350             if (register_verify(fr->callno, &sin, &ies)) {
08351                if (!iaxs[fr->callno]) {
08352                   ast_mutex_unlock(&iaxsl[fr->callno]);
08353                   return 1;
08354                }
08355                /* Send delayed failure */
08356                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08357                break;
08358             }
08359             if (!iaxs[fr->callno]) {
08360                ast_mutex_unlock(&iaxsl[fr->callno]);
08361                return 1;
08362             }
08363             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08364                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08365                if (f.subclass == IAX_COMMAND_REGREL)
08366                   memset(&sin, 0, sizeof(sin));
08367                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08368                   ast_log(LOG_WARNING, "Registry error\n");
08369                if (!iaxs[fr->callno]) {
08370                   ast_mutex_unlock(&iaxsl[fr->callno]);
08371                   return 1;
08372                }
08373                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08374                   ast_mutex_unlock(&iaxsl[fr->callno]);
08375                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08376                   ast_mutex_lock(&iaxsl[fr->callno]);
08377                   if (!iaxs[fr->callno]) {
08378                      ast_mutex_unlock(&iaxsl[fr->callno]);
08379                      return 1;
08380                   }
08381                }
08382                break;
08383             }
08384             registry_authrequest(fr->callno);
08385             if (!iaxs[fr->callno]) {
08386                ast_mutex_unlock(&iaxsl[fr->callno]);
08387                return 1;
08388             }
08389             break;
08390          case IAX_COMMAND_REGACK:
08391             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08392                ast_log(LOG_WARNING, "Registration failure\n");
08393             /* Send ack immediately, before we destroy */
08394             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08395             iax2_destroy(fr->callno);
08396             break;
08397          case IAX_COMMAND_REGREJ:
08398             if (iaxs[fr->callno]->reg) {
08399                if (authdebug) {
08400                   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));
08401                   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>");
08402                }
08403                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08404             }
08405             /* Send ack immediately, before we destroy */
08406             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08407             iax2_destroy(fr->callno);
08408             break;
08409          case IAX_COMMAND_REGAUTH:
08410             /* Authentication request */
08411             if (registry_rerequest(&ies, fr->callno, &sin)) {
08412                memset(&ied0, 0, sizeof(ied0));
08413                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08414                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08415                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08416                if (!iaxs[fr->callno]) {
08417                   ast_mutex_unlock(&iaxsl[fr->callno]);
08418                   return 1;
08419                }
08420             }
08421             break;
08422          case IAX_COMMAND_TXREJ:
08423             iaxs[fr->callno]->transferring = 0;
08424             if (option_verbose > 2) 
08425                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08426             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08427             if (iaxs[fr->callno]->bridgecallno) {
08428                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08429                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08430                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08431                }
08432             }
08433             break;
08434          case IAX_COMMAND_TXREADY:
08435             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08436                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08437                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08438                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08439                else
08440                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08441                if (option_verbose > 2) 
08442                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08443                if (iaxs[fr->callno]->bridgecallno) {
08444                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08445                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08446                      /* They're both ready, now release them. */
08447                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08448                         if (option_verbose > 2) 
08449                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08450                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08451 
08452                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08453                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08454 
08455                         memset(&ied0, 0, sizeof(ied0));
08456                         memset(&ied1, 0, sizeof(ied1));
08457                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08458                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08459                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08460                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08461                      } else {
08462                         if (option_verbose > 2) 
08463                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08464                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08465 
08466                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08467                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08468                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08469                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08470 
08471                         /* Stop doing lag & ping requests */
08472                         stop_stuff(fr->callno);
08473                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08474 
08475                         memset(&ied0, 0, sizeof(ied0));
08476                         memset(&ied1, 0, sizeof(ied1));
08477                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08478                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08479                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08480                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08481                      }
08482 
08483                   }
08484                }
08485             }
08486             break;
08487          case IAX_COMMAND_TXREQ:
08488             try_transfer(iaxs[fr->callno], &ies);
08489             break;
08490          case IAX_COMMAND_TXCNT:
08491             if (iaxs[fr->callno]->transferring)
08492                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08493             break;
08494          case IAX_COMMAND_TXREL:
08495             /* Send ack immediately, rather than waiting until we've changed addresses */
08496             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08497             complete_transfer(fr->callno, &ies);
08498             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08499             break;   
08500          case IAX_COMMAND_TXMEDIA:
08501             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08502                                         AST_LIST_LOCK(&iaxq.queue);
08503                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08504                                                 /* Cancel any outstanding frames and start anew */
08505                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08506                                                         cur->retries = -1;
08507                                                 }
08508                                         }
08509                                         AST_LIST_UNLOCK(&iaxq.queue);
08510                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08511                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08512             }
08513             break;   
08514          case IAX_COMMAND_DPREP:
08515             complete_dpreply(iaxs[fr->callno], &ies);
08516             break;
08517          case IAX_COMMAND_UNSUPPORT:
08518             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08519             break;
08520          case IAX_COMMAND_FWDOWNL:
08521             /* Firmware download */
08522             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08523                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08524                break;
08525             }
08526             memset(&ied0, 0, sizeof(ied0));
08527             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08528             if (res < 0)
08529                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08530             else if (res > 0)
08531                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08532             else
08533                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08534             if (!iaxs[fr->callno]) {
08535                ast_mutex_unlock(&iaxsl[fr->callno]);
08536                return 1;
08537             }
08538             break;
08539          default:
08540             if (option_debug)
08541                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08542             memset(&ied0, 0, sizeof(ied0));
08543             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08544             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08545          }
08546          /* Don't actually pass these frames along */
08547          if ((f.subclass != IAX_COMMAND_ACK) && 
08548            (f.subclass != IAX_COMMAND_TXCNT) && 
08549            (f.subclass != IAX_COMMAND_TXACC) && 
08550            (f.subclass != IAX_COMMAND_INVAL) &&
08551            (f.subclass != IAX_COMMAND_VNAK)) { 
08552             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08553                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08554          }
08555          ast_mutex_unlock(&iaxsl[fr->callno]);
08556          return 1;
08557       }
08558       /* Unless this is an ACK or INVAL frame, ack it */
08559       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08560          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08561    } else if (minivid) {
08562       f.frametype = AST_FRAME_VIDEO;
08563       if (iaxs[fr->callno]->videoformat > 0) 
08564          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08565       else {
08566          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
08567          iax2_vnak(fr->callno);
08568          ast_mutex_unlock(&iaxsl[fr->callno]);
08569          return 1;
08570       }
08571       f.datalen = res - sizeof(*vh);
08572       if (f.datalen)
08573          f.data = thread->buf + sizeof(*vh);
08574       else
08575          f.data = NULL;
08576 #ifdef IAXTESTS
08577       if (test_resync) {
08578          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08579       } else
08580 #endif /* IAXTESTS */
08581          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08582    } else {
08583       /* A mini frame */
08584       f.frametype = AST_FRAME_VOICE;
08585       if (iaxs[fr->callno]->voiceformat > 0)
08586          f.subclass = iaxs[fr->callno]->voiceformat;
08587       else {
08588          if (option_debug)
08589             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08590          iax2_vnak(fr->callno);
08591          ast_mutex_unlock(&iaxsl[fr->callno]);
08592          return 1;
08593       }
08594       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08595       if (f.datalen < 0) {
08596          ast_log(LOG_WARNING, "Datalen < 0?\n");
08597          ast_mutex_unlock(&iaxsl[fr->callno]);
08598          return 1;
08599       }
08600       if (f.datalen)
08601          f.data = thread->buf + sizeof(*mh);
08602       else
08603          f.data = NULL;
08604 #ifdef IAXTESTS
08605       if (test_resync) {
08606          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08607       } else
08608 #endif /* IAXTESTS */
08609       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08610       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08611    }
08612    /* Don't pass any packets until we're started */
08613    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08614       ast_mutex_unlock(&iaxsl[fr->callno]);
08615       return 1;
08616    }
08617    /* Common things */
08618    f.src = "IAX2";
08619    f.mallocd = 0;
08620    f.offset = 0;
08621    f.len = 0;
08622    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08623       f.samples = ast_codec_get_samples(&f);
08624       /* We need to byteswap incoming slinear samples from network byte order */
08625       if (f.subclass == AST_FORMAT_SLINEAR)
08626          ast_frame_byteswap_be(&f);
08627    } else
08628       f.samples = 0;
08629    iax_frame_wrap(fr, &f);
08630 
08631    /* If this is our most recent packet, use it as our basis for timestamping */
08632    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08633       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08634       fr->outoforder = 0;
08635    } else {
08636       if (option_debug && iaxdebug && iaxs[fr->callno])
08637          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);
08638       fr->outoforder = -1;
08639    }
08640    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08641    duped_fr = iaxfrdup2(fr);
08642    if (duped_fr) {
08643       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08644    }
08645    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08646       iaxs[fr->callno]->last = fr->ts;
08647 #if 1
08648       if (option_debug && iaxdebug)
08649          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08650 #endif
08651    }
08652 
08653    /* Always run again */
08654    ast_mutex_unlock(&iaxsl[fr->callno]);
08655    return 1;
08656 }
08657 
08658 /* Function to clean up process thread if it is cancelled */
08659 static void iax2_process_thread_cleanup(void *data)
08660 {
08661    struct iax2_thread *thread = data;
08662    ast_mutex_destroy(&thread->lock);
08663    ast_cond_destroy(&thread->cond);
08664    free(thread);
08665    ast_atomic_dec_and_test(&iaxactivethreadcount);
08666 }
08667 
08668 static void *iax2_process_thread(void *data)
08669 {
08670    struct iax2_thread *thread = data;
08671    struct timeval tv;
08672    struct timespec ts;
08673    int put_into_idle = 0;
08674 
08675    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08676    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08677    for(;;) {
08678       /* Wait for something to signal us to be awake */
08679       ast_mutex_lock(&thread->lock);
08680 
08681       /* Flag that we're ready to accept signals */
08682       thread->ready_for_signal = 1;
08683       
08684       /* Put into idle list if applicable */
08685       if (put_into_idle)
08686          insert_idle_thread(thread);
08687 
08688       if (thread->type == IAX_TYPE_DYNAMIC) {
08689          struct iax2_thread *t = NULL;
08690          /* Wait to be signalled or time out */
08691          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08692          ts.tv_sec = tv.tv_sec;
08693          ts.tv_nsec = tv.tv_usec * 1000;
08694          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08695             /* This thread was never put back into the available dynamic
08696              * thread list, so just go away. */
08697             if (!put_into_idle) {
08698                ast_mutex_unlock(&thread->lock);
08699                break;
08700             }
08701             AST_LIST_LOCK(&dynamic_list);
08702             /* Account for the case where this thread is acquired *right* after a timeout */
08703             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08704                iaxdynamicthreadcount--;
08705             AST_LIST_UNLOCK(&dynamic_list);
08706             if (t) {
08707                /* This dynamic thread timed out waiting for a task and was
08708                 * not acquired immediately after the timeout, 
08709                 * so it's time to go away. */
08710                ast_mutex_unlock(&thread->lock);
08711                break;
08712             }
08713             /* Someone grabbed our thread *right* after we timed out.
08714              * Wait for them to set us up with something to do and signal
08715              * us to continue. */
08716             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08717             ts.tv_sec = tv.tv_sec;
08718             ts.tv_nsec = tv.tv_usec * 1000;
08719             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08720             {
08721                ast_mutex_unlock(&thread->lock);
08722                break;
08723             }
08724          }
08725       } else {
08726          ast_cond_wait(&thread->cond, &thread->lock);
08727       }
08728 
08729       /* Go back into our respective list */
08730       put_into_idle = 1;
08731 
08732       ast_mutex_unlock(&thread->lock);
08733 
08734       if (thread->iostate == IAX_IOSTATE_IDLE)
08735          continue;
08736 
08737       /* Add ourselves to the active list now */
08738       AST_LIST_LOCK(&active_list);
08739       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08740       AST_LIST_UNLOCK(&active_list);
08741 
08742       /* See what we need to do */
08743       switch(thread->iostate) {
08744       case IAX_IOSTATE_READY:
08745          thread->actions++;
08746          thread->iostate = IAX_IOSTATE_PROCESSING;
08747          socket_process(thread);
08748          handle_deferred_full_frames(thread);
08749          break;
08750       case IAX_IOSTATE_SCHEDREADY:
08751          thread->actions++;
08752          thread->iostate = IAX_IOSTATE_PROCESSING;
08753 #ifdef SCHED_MULTITHREADED
08754          thread->schedfunc(thread->scheddata);
08755 #endif      
08756          break;
08757       }
08758       time(&thread->checktime);
08759       thread->iostate = IAX_IOSTATE_IDLE;
08760 #ifdef DEBUG_SCHED_MULTITHREAD
08761       thread->curfunc[0]='\0';
08762 #endif      
08763 
08764       /* Now... remove ourselves from the active list, and return to the idle list */
08765       AST_LIST_LOCK(&active_list);
08766       AST_LIST_REMOVE(&active_list, thread, list);
08767       AST_LIST_UNLOCK(&active_list);
08768 
08769       /* Make sure another frame didn't sneak in there after we thought we were done. */
08770       handle_deferred_full_frames(thread);
08771    }
08772 
08773    /*!\note For some reason, idle threads are exiting without being removed
08774     * from an idle list, which is causing memory corruption.  Forcibly remove
08775     * it from the list, if it's there.
08776     */
08777    AST_LIST_LOCK(&idle_list);
08778    AST_LIST_REMOVE(&idle_list, thread, list);
08779    AST_LIST_UNLOCK(&idle_list);
08780 
08781    AST_LIST_LOCK(&dynamic_list);
08782    AST_LIST_REMOVE(&dynamic_list, thread, list);
08783    AST_LIST_UNLOCK(&dynamic_list);
08784 
08785    /* I am exiting here on my own volition, I need to clean up my own data structures
08786    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08787    */
08788    pthread_cleanup_pop(1);
08789 
08790    return NULL;
08791 }
08792 
08793 static int iax2_do_register(struct iax2_registry *reg)
08794 {
08795    struct iax_ie_data ied;
08796    if (option_debug && iaxdebug)
08797       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08798 
08799    if (reg->dnsmgr && 
08800        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08801       /* Maybe the IP has changed, force DNS refresh */
08802       ast_dnsmgr_refresh(reg->dnsmgr);
08803    }
08804    
08805    /*
08806     * if IP has Changed, free allocated call to create a new one with new IP
08807     * call has the pointer to IP and must be updated to the new one
08808     */
08809    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08810       int callno = reg->callno;
08811       ast_mutex_lock(&iaxsl[callno]);
08812       iax2_destroy(callno);
08813       ast_mutex_unlock(&iaxsl[callno]);
08814       reg->callno = 0;
08815    }
08816    if (!reg->addr.sin_addr.s_addr) {
08817       if (option_debug && iaxdebug)
08818          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08819       /* Setup the next registration attempt */
08820       AST_SCHED_DEL(sched, reg->expire);
08821       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08822       return -1;
08823    }
08824 
08825    if (!reg->callno) {
08826       if (option_debug)
08827          ast_log(LOG_DEBUG, "Allocate call number\n");
08828       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08829       if (reg->callno < 1) {
08830          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08831          return -1;
08832       } else if (option_debug)
08833          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08834       iaxs[reg->callno]->reg = reg;
08835       ast_mutex_unlock(&iaxsl[reg->callno]);
08836    }
08837    /* Schedule the next registration attempt */
08838    AST_SCHED_DEL(sched, reg->expire);
08839    /* Setup the next registration a little early */
08840    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08841    /* Send the request */
08842    memset(&ied, 0, sizeof(ied));
08843    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08844    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08845    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08846    reg->regstate = REG_STATE_REGSENT;
08847    return 0;
08848 }
08849 
08850 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08851 {
08852    if (pos != 3)
08853       return NULL;
08854    return iax_prov_complete_template(line, word, pos, state);
08855 }
08856 
08857 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08858 {
08859    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08860       is found for template */
08861    struct iax_ie_data provdata;
08862    struct iax_ie_data ied;
08863    unsigned int sig;
08864    struct sockaddr_in sin;
08865    int callno;
08866    struct create_addr_info cai;
08867 
08868    memset(&cai, 0, sizeof(cai));
08869 
08870    if (option_debug)
08871       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08872 
08873    if (iax_provision_build(&provdata, &sig, template, force)) {
08874       if (option_debug)
08875          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08876       return 0;
08877    }
08878 
08879    if (end) {
08880       memcpy(&sin, end, sizeof(sin));
08881       cai.sockfd = sockfd;
08882    } else if (create_addr(dest, NULL, &sin, &cai))
08883       return -1;
08884 
08885    /* Build the rest of the message */
08886    memset(&ied, 0, sizeof(ied));
08887    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08888 
08889    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08890    if (!callno)
08891       return -1;
08892 
08893    if (iaxs[callno]) {
08894       /* Schedule autodestruct in case they don't ever give us anything back */
08895       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08896       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08897       ast_set_flag(iaxs[callno], IAX_PROVISION);
08898       /* Got a call number now, so go ahead and send the provisioning information */
08899       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08900    }
08901    ast_mutex_unlock(&iaxsl[callno]);
08902 
08903    return 1;
08904 }
08905 
08906 static char *papp = "IAX2Provision";
08907 static char *psyn = "Provision a calling IAXy with a given template";
08908 static char *pdescrip = 
08909 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08910 "the calling entity is in fact an IAXy) with the given template or\n"
08911 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08912 
08913 /*! iax2provision
08914 \ingroup applications
08915 */
08916 static int iax2_prov_app(struct ast_channel *chan, void *data)
08917 {
08918    int res;
08919    char *sdata;
08920    char *opts;
08921    int force =0;
08922    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08923    if (ast_strlen_zero(data))
08924       data = "default";
08925    sdata = ast_strdupa(data);
08926    opts = strchr(sdata, '|');
08927    if (opts)
08928       *opts='\0';
08929 
08930    if (chan->tech != &iax2_tech) {
08931       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08932       return -1;
08933    } 
08934    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08935       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08936       return -1;
08937    }
08938    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08939    if (option_verbose > 2)
08940       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08941       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08942       sdata, res);
08943    return res;
08944 }
08945 
08946 
08947 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08948 {
08949    int force = 0;
08950    int res;
08951    if (argc < 4)
08952       return RESULT_SHOWUSAGE;
08953    if ((argc > 4)) {
08954       if (!strcasecmp(argv[4], "forced"))
08955          force = 1;
08956       else
08957          return RESULT_SHOWUSAGE;
08958    }
08959    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08960    if (res < 0)
08961       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08962    else if (res < 1)
08963       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08964    else
08965       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08966    return RESULT_SUCCESS;
08967 }
08968 
08969 static void __iax2_poke_noanswer(const void *data)
08970 {
08971    struct iax2_peer *peer = (struct iax2_peer *)data;
08972    int callno;
08973 
08974    if (peer->lastms > -1) {
08975       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08976       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08977       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08978    }
08979    if ((callno = peer->callno) > 0) {
08980       ast_mutex_lock(&iaxsl[callno]);
08981       iax2_destroy(callno);
08982       ast_mutex_unlock(&iaxsl[callno]);
08983    }
08984    peer->callno = 0;
08985    peer->lastms = -1;
08986    /* Try again quickly */
08987    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08988    if (peer->pokeexpire == -1)
08989       peer_unref(peer);
08990 }
08991 
08992 static int iax2_poke_noanswer(const void *data)
08993 {
08994    struct iax2_peer *peer = (struct iax2_peer *)data;
08995    peer->pokeexpire = -1;
08996 #ifdef SCHED_MULTITHREADED
08997    if (schedule_action(__iax2_poke_noanswer, data))
08998 #endif      
08999       __iax2_poke_noanswer(data);
09000    peer_unref(peer);
09001    return 0;
09002 }
09003 
09004 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
09005 {
09006    struct iax2_peer *peer = obj;
09007 
09008    iax2_poke_peer(peer, 0);
09009 
09010    return 0;
09011 }
09012 
09013 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
09014 {
09015    int callno;
09016    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
09017       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
09018         immediately after clearing things out */
09019       peer->lastms = 0;
09020       peer->historicms = 0;
09021       peer->pokeexpire = -1;
09022       peer->callno = 0;
09023       return 0;
09024    }
09025 
09026    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
09027    if ((callno = peer->callno) > 0) {
09028       ast_log(LOG_NOTICE, "Still have a callno...\n");
09029       ast_mutex_lock(&iaxsl[callno]);
09030       iax2_destroy(callno);
09031       ast_mutex_unlock(&iaxsl[callno]);
09032    }
09033    if (heldcall)
09034       ast_mutex_unlock(&iaxsl[heldcall]);
09035    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
09036    if (heldcall)
09037       ast_mutex_lock(&iaxsl[heldcall]);
09038    if (peer->callno < 1) {
09039       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
09040       return -1;
09041    }
09042 
09043    /* Speed up retransmission times for this qualify call */
09044    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
09045    iaxs[peer->callno]->peerpoke = peer;
09046    
09047    /* Remove any pending pokeexpire task */
09048    if (peer->pokeexpire > -1) {
09049       if (!ast_sched_del(sched, peer->pokeexpire)) {
09050          peer->pokeexpire = -1;
09051          peer_unref(peer);
09052       }
09053    }
09054 
09055    /* Queue up a new task to handle no reply */
09056    /* If the host is already unreachable then use the unreachable interval instead */
09057    if (peer->lastms < 0) {
09058       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
09059    } else
09060       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
09061 
09062    if (peer->pokeexpire == -1)
09063       peer_unref(peer);
09064 
09065    /* And send the poke */
09066    ast_mutex_lock(&iaxsl[callno]);
09067    if (iaxs[callno]) {
09068       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
09069    }
09070    ast_mutex_unlock(&iaxsl[callno]);
09071 
09072    return 0;
09073 }
09074 
09075 static void free_context(struct iax2_context *con)
09076 {
09077    struct iax2_context *conl;
09078    while(con) {
09079       conl = con;
09080       con = con->next;
09081       free(conl);
09082    }
09083 }
09084 
09085 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09086 {
09087    int callno;
09088    int res;
09089    int fmt, native;
09090    struct sockaddr_in sin;
09091    struct ast_channel *c;
09092    struct parsed_dial_string pds;
09093    struct create_addr_info cai;
09094    char *tmpstr;
09095 
09096    memset(&pds, 0, sizeof(pds));
09097    tmpstr = ast_strdupa(data);
09098    parse_dial_string(tmpstr, &pds);
09099 
09100    if (ast_strlen_zero(pds.peer)) {
09101       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09102       return NULL;
09103    }
09104           
09105    memset(&cai, 0, sizeof(cai));
09106    cai.capability = iax2_capability;
09107 
09108    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09109    
09110    /* Populate our address from the given */
09111    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09112       *cause = AST_CAUSE_UNREGISTERED;
09113       return NULL;
09114    }
09115 
09116    if (pds.port)
09117       sin.sin_port = htons(atoi(pds.port));
09118 
09119    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09120    if (callno < 1) {
09121       ast_log(LOG_WARNING, "Unable to create call\n");
09122       *cause = AST_CAUSE_CONGESTION;
09123       return NULL;
09124    }
09125 
09126    /* If this is a trunk, update it now */
09127    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09128    if (ast_test_flag(&cai, IAX_TRUNK)) {
09129       int new_callno;
09130       if ((new_callno = make_trunk(callno, 1)) != -1)
09131          callno = new_callno;
09132    }
09133    iaxs[callno]->maxtime = cai.maxtime;
09134    if (cai.found)
09135       ast_string_field_set(iaxs[callno], host, pds.peer);
09136 
09137    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09138 
09139    ast_mutex_unlock(&iaxsl[callno]);
09140 
09141    if (c) {
09142       /* Choose a format we can live with */
09143       if (c->nativeformats & format) 
09144          c->nativeformats &= format;
09145       else {
09146          native = c->nativeformats;
09147          fmt = format;
09148          res = ast_translator_best_choice(&fmt, &native);
09149          if (res < 0) {
09150             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09151                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09152             ast_hangup(c);
09153             return NULL;
09154          }
09155          c->nativeformats = native;
09156       }
09157       c->readformat = ast_best_codec(c->nativeformats);
09158       c->writeformat = c->readformat;
09159    }
09160 
09161    return c;
09162 }
09163 
09164 static void *sched_thread(void *ignore)
09165 {
09166    int count;
09167    int res;
09168    struct timeval tv;
09169    struct timespec ts;
09170 
09171    for (;;) {
09172       pthread_testcancel();
09173       ast_mutex_lock(&sched_lock);
09174       res = ast_sched_wait(sched);
09175       if ((res > 1000) || (res < 0))
09176          res = 1000;
09177       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09178       ts.tv_sec = tv.tv_sec;
09179       ts.tv_nsec = tv.tv_usec * 1000;
09180       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09181       ast_mutex_unlock(&sched_lock);
09182       pthread_testcancel();
09183 
09184       count = ast_sched_runq(sched);
09185       if (option_debug && count >= 20)
09186          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09187    }
09188    return NULL;
09189 }
09190 
09191 static void *network_thread(void *ignore)
09192 {
09193    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09194       from the network, and queue them for delivery to the channels */
09195    int res, count, wakeup;
09196    struct iax_frame *f;
09197 
09198    if (timingfd > -1)
09199       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09200    
09201    for(;;) {
09202       pthread_testcancel();
09203 
09204       /* Go through the queue, sending messages which have not yet been
09205          sent, and scheduling retransmissions if appropriate */
09206       AST_LIST_LOCK(&iaxq.queue);
09207       count = 0;
09208       wakeup = -1;
09209       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09210          if (f->sentyet)
09211             continue;
09212          
09213          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09214          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09215             wakeup = 1;
09216             continue;
09217          }
09218 
09219          f->sentyet++;
09220 
09221          if (iaxs[f->callno]) {
09222             send_packet(f);
09223             count++;
09224          } 
09225 
09226          ast_mutex_unlock(&iaxsl[f->callno]);
09227 
09228          if (f->retries < 0) {
09229             /* This is not supposed to be retransmitted */
09230             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09231             iaxq.count--;
09232             /* Free the iax frame */
09233             iax_frame_free(f);
09234          } else {
09235             /* We need reliable delivery.  Schedule a retransmission */
09236             f->retries++;
09237             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09238          }
09239       }
09240       AST_LIST_TRAVERSE_SAFE_END
09241       AST_LIST_UNLOCK(&iaxq.queue);
09242 
09243       pthread_testcancel();
09244 
09245       if (option_debug && count >= 20)
09246          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09247 
09248       /* Now do the IO, and run scheduled tasks */
09249       res = ast_io_wait(io, wakeup);
09250       if (res >= 0) {
09251          if (option_debug && res >= 20)
09252             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09253       }
09254    }
09255    return NULL;
09256 }
09257 
09258 static int start_network_thread(void)
09259 {
09260    pthread_attr_t attr;
09261    int threadcount = 0;
09262    int x;
09263    for (x = 0; x < iaxthreadcount; x++) {
09264       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09265       if (thread) {
09266          thread->type = IAX_TYPE_POOL;
09267          thread->threadnum = ++threadcount;
09268          ast_mutex_init(&thread->lock);
09269          ast_cond_init(&thread->cond, NULL);
09270          pthread_attr_init(&attr);
09271          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09272          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09273             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09274             free(thread);
09275             thread = NULL;
09276          }
09277          AST_LIST_LOCK(&idle_list);
09278          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09279          AST_LIST_UNLOCK(&idle_list);
09280       }
09281    }
09282    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09283    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09284    if (option_verbose > 1)
09285       ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
09286    return 0;
09287 }
09288 
09289 static struct iax2_context *build_context(char *context)
09290 {
09291    struct iax2_context *con;
09292 
09293    if ((con = ast_calloc(1, sizeof(*con))))
09294       ast_copy_string(con->context, context, sizeof(con->context));
09295    
09296    return con;
09297 }
09298 
09299 static int get_auth_methods(char *value)
09300 {
09301    int methods = 0;
09302    if (strstr(value, "rsa"))
09303       methods |= IAX_AUTH_RSA;
09304    if (strstr(value, "md5"))
09305       methods |= IAX_AUTH_MD5;
09306    if (strstr(value, "plaintext"))
09307       methods |= IAX_AUTH_PLAINTEXT;
09308    return methods;
09309 }
09310 
09311 
09312 /*! \brief Check if address can be used as packet source.
09313  \return 0  address available, 1  address unavailable, -1  error
09314 */
09315 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09316 {
09317    int sd;
09318    int res;
09319    
09320    sd = socket(AF_INET, SOCK_DGRAM, 0);
09321    if (sd < 0) {
09322       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09323       return -1;
09324    }
09325 
09326    res = bind(sd, sa, salen);
09327    if (res < 0) {
09328       if (option_debug)
09329          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09330       close(sd);
09331       return 1;
09332    }
09333 
09334    close(sd);
09335    return 0;
09336 }
09337 
09338 /*! \brief Parse the "sourceaddress" value,
09339   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09340   not found. */
09341 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09342 {
09343    struct sockaddr_in sin;
09344    int nonlocal = 1;
09345    int port = IAX_DEFAULT_PORTNO;
09346    int sockfd = defaultsockfd;
09347    char *tmp;
09348    char *addr;
09349    char *portstr;
09350 
09351    if (!(tmp = ast_strdupa(srcaddr)))
09352       return -1;
09353 
09354    addr = strsep(&tmp, ":");
09355    portstr = tmp;
09356 
09357    if (portstr) {
09358       port = atoi(portstr);
09359       if (port < 1)
09360          port = IAX_DEFAULT_PORTNO;
09361    }
09362    
09363    if (!ast_get_ip(&sin, addr)) {
09364       struct ast_netsock *sock;
09365       int res;
09366 
09367       sin.sin_port = 0;
09368       sin.sin_family = AF_INET;
09369       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09370       if (res == 0) {
09371          /* ip address valid. */
09372          sin.sin_port = htons(port);
09373          if (!(sock = ast_netsock_find(netsock, &sin)))
09374             sock = ast_netsock_find(outsock, &sin);
09375          if (sock) {
09376             sockfd = ast_netsock_sockfd(sock);
09377             nonlocal = 0;
09378          } else {
09379             unsigned int orig_saddr = sin.sin_addr.s_addr;
09380             /* INADDR_ANY matches anyway! */
09381             sin.sin_addr.s_addr = INADDR_ANY;
09382             if (ast_netsock_find(netsock, &sin)) {
09383                sin.sin_addr.s_addr = orig_saddr;
09384                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09385                if (sock) {
09386                   sockfd = ast_netsock_sockfd(sock);
09387                   ast_netsock_unref(sock);
09388                   nonlocal = 0;
09389                } else {
09390                   nonlocal = 2;
09391                }
09392             }
09393          }
09394       }
09395    }
09396       
09397    peer->sockfd = sockfd;
09398 
09399    if (nonlocal == 1) {
09400       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09401          srcaddr, peer->name);
09402       return -1;
09403         } else if (nonlocal == 2) {
09404       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09405          srcaddr, peer->name);
09406          return -1;
09407    } else {
09408       if (option_debug)
09409          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09410       return 0;
09411    }
09412 }
09413 
09414 static void peer_destructor(void *obj)
09415 {
09416    struct iax2_peer *peer = obj;
09417    int callno = peer->callno;
09418 
09419    ast_free_ha(peer->ha);
09420 
09421    if (callno > 0) {
09422       ast_mutex_lock(&iaxsl[callno]);
09423       iax2_destroy(callno);
09424       ast_mutex_unlock(&iaxsl[callno]);
09425    }
09426 
09427    register_peer_exten(peer, 0);
09428 
09429    if (peer->dnsmgr)
09430       ast_dnsmgr_release(peer->dnsmgr);
09431 
09432    ast_string_field_free_memory(peer);
09433 }
09434 
09435 /*! \brief Create peer structure based on configuration */
09436 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09437 {
09438    struct iax2_peer *peer = NULL;
09439    struct ast_ha *oldha = NULL;
09440    int maskfound=0;
09441    int found=0;
09442    int firstpass=1;
09443    struct iax2_peer tmp_peer = {
09444       .name = name,
09445    };
09446 
09447    if (!temponly) {
09448       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09449       if (peer && !ast_test_flag(peer, IAX_DELME))
09450          firstpass = 0;
09451    }
09452 
09453    if (peer) {
09454       found++;
09455       if (firstpass) {
09456          oldha = peer->ha;
09457          peer->ha = NULL;
09458       }
09459       unlink_peer(peer);
09460    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09461       peer->expire = -1;
09462       peer->pokeexpire = -1;
09463       peer->sockfd = defaultsockfd;
09464       if (ast_string_field_init(peer, 32))
09465          peer = peer_unref(peer);
09466    }
09467 
09468    if (peer) {
09469       if (firstpass) {
09470          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09471          peer->encmethods = iax2_encryption;
09472          peer->adsi = adsi;
09473          ast_string_field_set(peer,secret,"");
09474          if (!found) {
09475             ast_string_field_set(peer, name, name);
09476             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09477             peer->expiry = min_reg_expire;
09478          }
09479          peer->prefs = prefs;
09480          peer->capability = iax2_capability;
09481          peer->smoothing = 0;
09482          peer->pokefreqok = DEFAULT_FREQ_OK;
09483          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09484          ast_string_field_set(peer,context,"");
09485          ast_string_field_set(peer,peercontext,"");
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 
09491       if (!v) {
09492          v = alt;
09493          alt = NULL;
09494       }
09495       while(v) {
09496          if (!strcasecmp(v->name, "secret")) {
09497             ast_string_field_set(peer, secret, v->value);
09498          } else if (!strcasecmp(v->name, "mailbox")) {
09499             ast_string_field_set(peer, mailbox, v->value);
09500          } else if (!strcasecmp(v->name, "hasvoicemail")) {
09501             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
09502                ast_string_field_set(peer, mailbox, name);
09503             }
09504          } else if (!strcasecmp(v->name, "mohinterpret")) {
09505             ast_string_field_set(peer, mohinterpret, v->value);
09506          } else if (!strcasecmp(v->name, "mohsuggest")) {
09507             ast_string_field_set(peer, mohsuggest, v->value);
09508          } else if (!strcasecmp(v->name, "dbsecret")) {
09509             ast_string_field_set(peer, dbsecret, v->value);
09510          } else if (!strcasecmp(v->name, "trunk")) {
09511             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09512             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09513                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
09514                ast_clear_flag(peer, IAX_TRUNK);
09515             }
09516          } else if (!strcasecmp(v->name, "auth")) {
09517             peer->authmethods = get_auth_methods(v->value);
09518          } else if (!strcasecmp(v->name, "encryption")) {
09519             peer->encmethods = get_encrypt_methods(v->value);
09520          } else if (!strcasecmp(v->name, "notransfer")) {
09521             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09522             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09523             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09524          } else if (!strcasecmp(v->name, "transfer")) {
09525             if (!strcasecmp(v->value, "mediaonly")) {
09526                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09527             } else if (ast_true(v->value)) {
09528                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09529             } else 
09530                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09531          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09532             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09533          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09534             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09535          } else if (!strcasecmp(v->name, "host")) {
09536             if (!strcasecmp(v->value, "dynamic")) {
09537                /* They'll register with us */
09538                ast_set_flag(peer, IAX_DYNAMIC); 
09539                if (!found) {
09540                   /* Initialize stuff iff we're not found, otherwise
09541                      we keep going with what we had */
09542                   memset(&peer->addr.sin_addr, 0, 4);
09543                   if (peer->addr.sin_port) {
09544                      /* If we've already got a port, make it the default rather than absolute */
09545                      peer->defaddr.sin_port = peer->addr.sin_port;
09546                      peer->addr.sin_port = 0;
09547                   }
09548                }
09549             } else {
09550                /* Non-dynamic.  Make sure we become that way if we're not */
09551                AST_SCHED_DEL(sched, peer->expire);
09552                ast_clear_flag(peer, IAX_DYNAMIC);
09553                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09554                   return peer_unref(peer);
09555                if (!peer->addr.sin_port)
09556                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09557             }
09558             if (!maskfound)
09559                inet_aton("255.255.255.255", &peer->mask);
09560          } else if (!strcasecmp(v->name, "defaultip")) {
09561             if (ast_get_ip(&peer->defaddr, v->value))
09562                return peer_unref(peer);
09563          } else if (!strcasecmp(v->name, "sourceaddress")) {
09564             peer_set_srcaddr(peer, v->value);
09565          } else if (!strcasecmp(v->name, "permit") ||
09566                   !strcasecmp(v->name, "deny")) {
09567             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09568          } else if (!strcasecmp(v->name, "mask")) {
09569             maskfound++;
09570             inet_aton(v->value, &peer->mask);
09571          } else if (!strcasecmp(v->name, "context")) {
09572             ast_string_field_set(peer, context, v->value);
09573          } else if (!strcasecmp(v->name, "regexten")) {
09574             ast_string_field_set(peer, regexten, v->value);
09575          } else if (!strcasecmp(v->name, "peercontext")) {
09576             ast_string_field_set(peer, peercontext, v->value);
09577          } else if (!strcasecmp(v->name, "port")) {
09578             if (ast_test_flag(peer, IAX_DYNAMIC))
09579                peer->defaddr.sin_port = htons(atoi(v->value));
09580             else
09581                peer->addr.sin_port = htons(atoi(v->value));
09582          } else if (!strcasecmp(v->name, "username")) {
09583             ast_string_field_set(peer, username, v->value);
09584          } else if (!strcasecmp(v->name, "allow")) {
09585             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09586          } else if (!strcasecmp(v->name, "disallow")) {
09587             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09588          } else if (!strcasecmp(v->name, "callerid")) {
09589             if (!ast_strlen_zero(v->value)) {
09590                char name2[80];
09591                char num2[80];
09592                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09593                ast_string_field_set(peer, cid_name, name2);
09594                ast_string_field_set(peer, cid_num, num2);
09595             } else {
09596                ast_string_field_set(peer, cid_name, "");
09597                ast_string_field_set(peer, cid_num, "");
09598             }
09599             ast_set_flag(peer, IAX_HASCALLERID);
09600          } else if (!strcasecmp(v->name, "fullname")) {
09601             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
09602             ast_set_flag(peer, IAX_HASCALLERID);
09603          } else if (!strcasecmp(v->name, "cid_number")) {
09604             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
09605             ast_set_flag(peer, IAX_HASCALLERID);
09606          } else if (!strcasecmp(v->name, "sendani")) {
09607             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09608          } else if (!strcasecmp(v->name, "inkeys")) {
09609             ast_string_field_set(peer, inkeys, v->value);
09610          } else if (!strcasecmp(v->name, "outkey")) {
09611             ast_string_field_set(peer, outkey, v->value);
09612          } else if (!strcasecmp(v->name, "qualify")) {
09613             if (!strcasecmp(v->value, "no")) {
09614                peer->maxms = 0;
09615             } else if (!strcasecmp(v->value, "yes")) {
09616                peer->maxms = DEFAULT_MAXMS;
09617             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09618                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);
09619                peer->maxms = 0;
09620             }
09621          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09622             peer->smoothing = ast_true(v->value);
09623          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09624             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09625                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);
09626             }
09627          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09628             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09629                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);
09630             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09631          } else if (!strcasecmp(v->name, "timezone")) {
09632             ast_string_field_set(peer, zonetag, v->value);
09633          } else if (!strcasecmp(v->name, "adsi")) {
09634             peer->adsi = ast_true(v->value);
09635          }/* else if (strcasecmp(v->name,"type")) */
09636          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09637          v = v->next;
09638          if (!v) {
09639             v = alt;
09640             alt = NULL;
09641          }
09642       }
09643       if (!peer->authmethods)
09644          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09645       ast_clear_flag(peer, IAX_DELME); 
09646       /* Make sure these are IPv4 addresses */
09647       peer->addr.sin_family = AF_INET;
09648    }
09649    if (oldha)
09650       ast_free_ha(oldha);
09651    return peer;
09652 }
09653 
09654 static void user_destructor(void *obj)
09655 {
09656    struct iax2_user *user = obj;
09657 
09658    ast_free_ha(user->ha);
09659    free_context(user->contexts);
09660    if(user->vars) {
09661       ast_variables_destroy(user->vars);
09662       user->vars = NULL;
09663    }
09664    ast_string_field_free_memory(user);
09665 }
09666 
09667 /*! \brief Create in-memory user structure from configuration */
09668 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09669 {
09670    struct iax2_user *user = NULL;
09671    struct iax2_context *con, *conl = NULL;
09672    struct ast_ha *oldha = NULL;
09673    struct iax2_context *oldcon = NULL;
09674    int format;
09675    int firstpass=1;
09676    int oldcurauthreq = 0;
09677    char *varname = NULL, *varval = NULL;
09678    struct ast_variable *tmpvar = NULL;
09679    struct iax2_user tmp_user = {
09680       .name = name,
09681    };
09682 
09683    if (!temponly) {
09684       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09685       if (user && !ast_test_flag(user, IAX_DELME))
09686          firstpass = 0;
09687    }
09688 
09689    if (user) {
09690       if (firstpass) {
09691          oldcurauthreq = user->curauthreq;
09692          oldha = user->ha;
09693          oldcon = user->contexts;
09694          user->ha = NULL;
09695          user->contexts = NULL;
09696       }
09697       /* Already in the list, remove it and it will be added back (or FREE'd) */
09698       ao2_unlink(users, user);
09699    } else {
09700       user = ao2_alloc(sizeof(*user), user_destructor);
09701    }
09702    
09703    if (user) {
09704       if (firstpass) {
09705          ast_string_field_free_memory(user);
09706          memset(user, 0, sizeof(struct iax2_user));
09707          if (ast_string_field_init(user, 32)) {
09708             user = user_unref(user);
09709             goto cleanup;
09710          }
09711          user->maxauthreq = maxauthreq;
09712          user->curauthreq = oldcurauthreq;
09713          user->prefs = prefs;
09714          user->capability = iax2_capability;
09715          user->encmethods = iax2_encryption;
09716          user->adsi = adsi;
09717          ast_string_field_set(user, name, name);
09718          ast_string_field_set(user, language, language);
09719          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09720          ast_clear_flag(user, IAX_HASCALLERID);
09721          ast_string_field_set(user, cid_name, "");
09722          ast_string_field_set(user, cid_num, "");
09723       }
09724       if (!v) {
09725          v = alt;
09726          alt = NULL;
09727       }
09728       while(v) {
09729          if (!strcasecmp(v->name, "context")) {
09730             con = build_context(v->value);
09731             if (con) {
09732                if (conl)
09733                   conl->next = con;
09734                else
09735                   user->contexts = con;
09736                conl = con;
09737             }
09738          } else if (!strcasecmp(v->name, "permit") ||
09739                   !strcasecmp(v->name, "deny")) {
09740             user->ha = ast_append_ha(v->name, v->value, user->ha);
09741          } else if (!strcasecmp(v->name, "setvar")) {
09742             varname = ast_strdupa(v->value);
09743             if (varname && (varval = strchr(varname,'='))) {
09744                *varval = '\0';
09745                varval++;
09746                if((tmpvar = ast_variable_new(varname, varval))) {
09747                   tmpvar->next = user->vars; 
09748                   user->vars = tmpvar;
09749                }
09750             }
09751          } else if (!strcasecmp(v->name, "allow")) {
09752             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09753          } else if (!strcasecmp(v->name, "disallow")) {
09754             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09755          } else if (!strcasecmp(v->name, "trunk")) {
09756             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09757             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09758                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
09759                ast_clear_flag(user, IAX_TRUNK);
09760             }
09761          } else if (!strcasecmp(v->name, "auth")) {
09762             user->authmethods = get_auth_methods(v->value);
09763          } else if (!strcasecmp(v->name, "encryption")) {
09764             user->encmethods = get_encrypt_methods(v->value);
09765          } else if (!strcasecmp(v->name, "notransfer")) {
09766             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09767             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09768             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09769          } else if (!strcasecmp(v->name, "transfer")) {
09770             if (!strcasecmp(v->value, "mediaonly")) {
09771                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09772             } else if (ast_true(v->value)) {
09773                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09774             } else 
09775                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09776          } else if (!strcasecmp(v->name, "codecpriority")) {
09777             if(!strcasecmp(v->value, "caller"))
09778                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09779             else if(!strcasecmp(v->value, "disabled"))
09780                ast_set_flag(user, IAX_CODEC_NOPREFS);
09781             else if(!strcasecmp(v->value, "reqonly")) {
09782                ast_set_flag(user, IAX_CODEC_NOCAP);
09783                ast_set_flag(user, IAX_CODEC_NOPREFS);
09784             }
09785          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09786             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09787          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09788             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09789          } else if (!strcasecmp(v->name, "dbsecret")) {
09790             ast_string_field_set(user, dbsecret, v->value);
09791          } else if (!strcasecmp(v->name, "secret")) {
09792             if (!ast_strlen_zero(user->secret)) {
09793                char *old = ast_strdupa(user->secret);
09794 
09795                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09796             } else
09797                ast_string_field_set(user, secret, v->value);
09798          } else if (!strcasecmp(v->name, "callerid")) {
09799             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09800                char name2[80];
09801                char num2[80];
09802                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09803                ast_string_field_set(user, cid_name, name2);
09804                ast_string_field_set(user, cid_num, num2);
09805                ast_set_flag(user, IAX_HASCALLERID);
09806             } else {
09807                ast_clear_flag(user, IAX_HASCALLERID);
09808                ast_string_field_set(user, cid_name, "");
09809                ast_string_field_set(user, cid_num, "");
09810             }
09811          } else if (!strcasecmp(v->name, "fullname")) {
09812             if (!ast_strlen_zero(v->value)) {
09813                ast_string_field_set(user, cid_name, v->value);
09814                ast_set_flag(user, IAX_HASCALLERID);
09815             } else {
09816                ast_string_field_set(user, cid_name, "");
09817                if (ast_strlen_zero(user->cid_num))
09818                   ast_clear_flag(user, IAX_HASCALLERID);
09819             }
09820          } else if (!strcasecmp(v->name, "cid_number")) {
09821             if (!ast_strlen_zero(v->value)) {
09822                ast_string_field_set(user, cid_num, v->value);
09823                ast_set_flag(user, IAX_HASCALLERID);
09824             } else {
09825                ast_string_field_set(user, cid_num, "");
09826                if (ast_strlen_zero(user->cid_name))
09827                   ast_clear_flag(user, IAX_HASCALLERID);
09828             }
09829          } else if (!strcasecmp(v->name, "accountcode")) {
09830             ast_string_field_set(user, accountcode, v->value);
09831          } else if (!strcasecmp(v->name, "mohinterpret")) {
09832             ast_string_field_set(user, mohinterpret, v->value);
09833          } else if (!strcasecmp(v->name, "mohsuggest")) {
09834             ast_string_field_set(user, mohsuggest, v->value);
09835          } else if (!strcasecmp(v->name, "language")) {
09836             ast_string_field_set(user, language, v->value);
09837          } else if (!strcasecmp(v->name, "amaflags")) {
09838             format = ast_cdr_amaflags2int(v->value);
09839             if (format < 0) {
09840                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09841             } else {
09842                user->amaflags = format;
09843             }
09844          } else if (!strcasecmp(v->name, "inkeys")) {
09845             ast_string_field_set(user, inkeys, v->value);
09846          } else if (!strcasecmp(v->name, "maxauthreq")) {
09847             user->maxauthreq = atoi(v->value);
09848             if (user->maxauthreq < 0)
09849                user->maxauthreq = 0;
09850          } else if (!strcasecmp(v->name, "adsi")) {
09851             user->adsi = ast_true(v->value);
09852          }/* else if (strcasecmp(v->name,"type")) */
09853          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09854          v = v->next;
09855          if (!v) {
09856             v = alt;
09857             alt = NULL;
09858          }
09859       }
09860       if (!user->authmethods) {
09861          if (!ast_strlen_zero(user->secret)) {
09862             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09863             if (!ast_strlen_zero(user->inkeys))
09864                user->authmethods |= IAX_AUTH_RSA;
09865          } else if (!ast_strlen_zero(user->inkeys)) {
09866             user->authmethods = IAX_AUTH_RSA;
09867          } else {
09868             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09869          }
09870       }
09871       ast_clear_flag(user, IAX_DELME);
09872    }
09873 cleanup:
09874    if (oldha)
09875       ast_free_ha(oldha);
09876    if (oldcon)
09877       free_context(oldcon);
09878    return user;
09879 }
09880 
09881 static int peer_delme_cb(void *obj, void *arg, int flags)
09882 {
09883    struct iax2_peer *peer = obj;
09884 
09885    ast_set_flag(peer, IAX_DELME);
09886 
09887    return 0;
09888 }
09889 
09890 static int user_delme_cb(void *obj, void *arg, int flags)
09891 {
09892    struct iax2_user *user = obj;
09893 
09894    ast_set_flag(user, IAX_DELME);
09895 
09896    return 0;
09897 }
09898 
09899 static void delete_users(void)
09900 {
09901    struct iax2_registry *reg;
09902 
09903    ao2_callback(users, 0, user_delme_cb, NULL);
09904 
09905    AST_LIST_LOCK(&registrations);
09906    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09907       ast_sched_del(sched, reg->expire);
09908       if (reg->callno) {
09909          int callno = reg->callno;
09910          ast_mutex_lock(&iaxsl[callno]);
09911          if (iaxs[callno]) {
09912             iaxs[callno]->reg = NULL;
09913             iax2_destroy(callno);
09914          }
09915          ast_mutex_unlock(&iaxsl[callno]);
09916       }
09917       if (reg->dnsmgr)
09918          ast_dnsmgr_release(reg->dnsmgr);
09919       free(reg);
09920    }
09921    AST_LIST_UNLOCK(&registrations);
09922 
09923    ao2_callback(peers, 0, peer_delme_cb, NULL);
09924 }
09925 
09926 static void prune_users(void)
09927 {
09928    struct iax2_user *user;
09929    struct ao2_iterator i;
09930 
09931    i = ao2_iterator_init(users, 0);
09932    while ((user = ao2_iterator_next(&i))) {
09933       if (ast_test_flag(user, IAX_DELME))
09934          ao2_unlink(users, user);
09935       user_unref(user);
09936    }
09937 }
09938 
09939 /* Prune peers who still are supposed to be deleted */
09940 static void prune_peers(void)
09941 {
09942    struct iax2_peer *peer;
09943    struct ao2_iterator i;
09944 
09945    i = ao2_iterator_init(peers, 0);
09946    while ((peer = ao2_iterator_next(&i))) {
09947       if (ast_test_flag(peer, IAX_DELME))
09948          unlink_peer(peer);
09949       peer_unref(peer);
09950    }
09951 }
09952 
09953 static void set_timing(void)
09954 {
09955 #ifdef HAVE_DAHDI
09956    int bs = trunkfreq * 8;
09957    if (timingfd > -1) {
09958       if (
09959 #ifdef DAHDI_TIMERACK
09960          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
09961 #endif         
09962          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
09963          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09964    }
09965 #endif
09966 }
09967 
09968 static void set_config_destroy(void)
09969 {
09970    strcpy(accountcode, "");
09971    strcpy(language, "");
09972    strcpy(mohinterpret, "default");
09973    strcpy(mohsuggest, "");
09974    amaflags = 0;
09975    delayreject = 0;
09976    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09977    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09978    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09979    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09980    delete_users();
09981 }
09982 
09983 /*! \brief Load configuration */
09984 static int set_config(char *config_file, int reload)
09985 {
09986    struct ast_config *cfg, *ucfg;
09987    int capability=iax2_capability;
09988    struct ast_variable *v;
09989    char *cat;
09990    const char *utype;
09991    const char *tosval;
09992    int format;
09993    int portno = IAX_DEFAULT_PORTNO;
09994    int  x;
09995    struct iax2_user *user;
09996    struct iax2_peer *peer;
09997    struct ast_netsock *ns;
09998 #if 0
09999    static unsigned short int last_port=0;
10000 #endif
10001 
10002    cfg = ast_config_load(config_file);
10003    
10004    if (!cfg) {
10005       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
10006       return -1;
10007    }
10008 
10009    if (reload) {
10010       set_config_destroy();
10011    }
10012 
10013    /* Reset global codec prefs */   
10014    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
10015    
10016    /* Reset Global Flags */
10017    memset(&globalflags, 0, sizeof(globalflags));
10018    ast_set_flag(&globalflags, IAX_RTUPDATE);
10019 
10020 #ifdef SO_NO_CHECK
10021    nochecksums = 0;
10022 #endif
10023 
10024    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10025    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10026 
10027    maxauthreq = 3;
10028 
10029    v = ast_variable_browse(cfg, "general");
10030 
10031    /* Seed initial tos value */
10032    tosval = ast_variable_retrieve(cfg, "general", "tos");
10033    if (tosval) {
10034       if (ast_str2tos(tosval, &tos))
10035          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
10036    }
10037    while(v) {
10038       if (!strcasecmp(v->name, "bindport")){ 
10039          if (reload)
10040             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
10041          else
10042             portno = atoi(v->value);
10043       } else if (!strcasecmp(v->name, "pingtime")) 
10044          ping_time = atoi(v->value);
10045       else if (!strcasecmp(v->name, "iaxthreadcount")) {
10046          if (reload) {
10047             if (atoi(v->value) != iaxthreadcount)
10048                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
10049          } else {
10050             iaxthreadcount = atoi(v->value);
10051             if (iaxthreadcount < 1) {
10052                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
10053                iaxthreadcount = 1;
10054             } else if (iaxthreadcount > 256) {
10055                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
10056                iaxthreadcount = 256;
10057             }
10058          }
10059       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
10060          if (reload) {
10061             AST_LIST_LOCK(&dynamic_list);
10062             iaxmaxthreadcount = atoi(v->value);
10063             AST_LIST_UNLOCK(&dynamic_list);
10064          } else {
10065             iaxmaxthreadcount = atoi(v->value);
10066             if (iaxmaxthreadcount < 0) {
10067                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
10068                iaxmaxthreadcount = 0;
10069             } else if (iaxmaxthreadcount > 256) {
10070                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
10071                iaxmaxthreadcount = 256;
10072             }
10073          }
10074       } else if (!strcasecmp(v->name, "nochecksums")) {
10075 #ifdef SO_NO_CHECK
10076          if (ast_true(v->value))
10077             nochecksums = 1;
10078          else
10079             nochecksums = 0;
10080 #else
10081          if (ast_true(v->value))
10082             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10083 #endif
10084       }
10085       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
10086          maxjitterbuffer = atoi(v->value);
10087       else if (!strcasecmp(v->name, "resyncthreshold")) 
10088          resyncthreshold = atoi(v->value);
10089       else if (!strcasecmp(v->name, "maxjitterinterps")) 
10090          maxjitterinterps = atoi(v->value);
10091       else if (!strcasecmp(v->name, "lagrqtime")) 
10092          lagrq_time = atoi(v->value);
10093       else if (!strcasecmp(v->name, "maxregexpire")) 
10094          max_reg_expire = atoi(v->value);
10095       else if (!strcasecmp(v->name, "minregexpire")) 
10096          min_reg_expire = atoi(v->value);
10097       else if (!strcasecmp(v->name, "bindaddr")) {
10098          if (reload) {
10099             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10100          } else {
10101             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10102                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10103             } else {
10104                if (option_verbose > 1) {
10105                   if (strchr(v->value, ':'))
10106                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10107                   else
10108                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10109                }
10110                if (defaultsockfd < 0) 
10111                   defaultsockfd = ast_netsock_sockfd(ns);
10112                ast_netsock_unref(ns);
10113             }
10114          }
10115       } else if (!strcasecmp(v->name, "authdebug"))
10116          authdebug = ast_true(v->value);
10117       else if (!strcasecmp(v->name, "encryption"))
10118          iax2_encryption = get_encrypt_methods(v->value);
10119       else if (!strcasecmp(v->name, "notransfer")) {
10120          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10121          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10122          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10123       } else if (!strcasecmp(v->name, "transfer")) {
10124          if (!strcasecmp(v->value, "mediaonly")) {
10125             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10126          } else if (ast_true(v->value)) {
10127             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10128          } else 
10129             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10130       } else if (!strcasecmp(v->name, "codecpriority")) {
10131          if(!strcasecmp(v->value, "caller"))
10132             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10133          else if(!strcasecmp(v->value, "disabled"))
10134             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10135          else if(!strcasecmp(v->value, "reqonly")) {
10136             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10137             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10138          }
10139       } else if (!strcasecmp(v->name, "jitterbuffer"))
10140          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10141       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10142          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10143       else if (!strcasecmp(v->name, "delayreject"))
10144          delayreject = ast_true(v->value);
10145       else if (!strcasecmp(v->name, "allowfwdownload"))
10146          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10147       else if (!strcasecmp(v->name, "rtcachefriends"))
10148          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10149       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10150          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10151       else if (!strcasecmp(v->name, "rtupdate"))
10152          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10153       else if (!strcasecmp(v->name, "trunktimestamps"))
10154          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10155       else if (!strcasecmp(v->name, "rtautoclear")) {
10156          int i = atoi(v->value);
10157          if(i > 0)
10158             global_rtautoclear = i;
10159          else
10160             i = 0;
10161          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10162       } else if (!strcasecmp(v->name, "trunkfreq")) {
10163          trunkfreq = atoi(v->value);
10164          if (trunkfreq < 10)
10165             trunkfreq = 10;
10166       } else if (!strcasecmp(v->name, "autokill")) {
10167          if (sscanf(v->value, "%d", &x) == 1) {
10168             if (x >= 0)
10169                autokill = x;
10170             else
10171                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10172          } else if (ast_true(v->value)) {
10173             autokill = DEFAULT_MAXMS;
10174          } else {
10175             autokill = 0;
10176          }
10177       } else if (!strcasecmp(v->name, "bandwidth")) {
10178          if (!strcasecmp(v->value, "low")) {
10179             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10180          } else if (!strcasecmp(v->value, "medium")) {
10181             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10182          } else if (!strcasecmp(v->value, "high")) {
10183             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10184          } else
10185             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10186       } else if (!strcasecmp(v->name, "allow")) {
10187          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10188       } else if (!strcasecmp(v->name, "disallow")) {
10189          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10190       } else if (!strcasecmp(v->name, "register")) {
10191          iax2_register(v->value, v->lineno);
10192       } else if (!strcasecmp(v->name, "iaxcompat")) {
10193          iaxcompat = ast_true(v->value);
10194       } else if (!strcasecmp(v->name, "regcontext")) {
10195          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10196          /* Create context if it doesn't exist already */
10197          if (!ast_context_find(regcontext))
10198             ast_context_create(NULL, regcontext, "IAX2");
10199       } else if (!strcasecmp(v->name, "tos")) {
10200          if (ast_str2tos(v->value, &tos))
10201             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10202       } else if (!strcasecmp(v->name, "accountcode")) {
10203          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10204       } else if (!strcasecmp(v->name, "mohinterpret")) {
10205          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
10206       } else if (!strcasecmp(v->name, "mohsuggest")) {
10207          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
10208       } else if (!strcasecmp(v->name, "amaflags")) {
10209          format = ast_cdr_amaflags2int(v->value);
10210          if (format < 0) {
10211             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10212          } else {
10213             amaflags = format;
10214          }
10215       } else if (!strcasecmp(v->name, "language")) {
10216          ast_copy_string(language, v->value, sizeof(language));
10217       } else if (!strcasecmp(v->name, "maxauthreq")) {
10218          maxauthreq = atoi(v->value);
10219          if (maxauthreq < 0)
10220             maxauthreq = 0;
10221       } else if (!strcasecmp(v->name, "adsi")) {
10222          adsi = ast_true(v->value);
10223       } /*else if (strcasecmp(v->name,"type")) */
10224       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10225       v = v->next;
10226    }
10227    
10228    if (defaultsockfd < 0) {
10229       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10230          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10231       } else {
10232          if (option_verbose > 1)
10233             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10234          defaultsockfd = ast_netsock_sockfd(ns);
10235          ast_netsock_unref(ns);
10236       }
10237    }
10238    if (reload) {
10239       ast_netsock_release(outsock);
10240       outsock = ast_netsock_list_alloc();
10241       if (!outsock) {
10242          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10243          return -1;
10244       }
10245       ast_netsock_init(outsock);
10246    }
10247 
10248    if (min_reg_expire > max_reg_expire) {
10249       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10250          min_reg_expire, max_reg_expire, max_reg_expire);
10251       min_reg_expire = max_reg_expire;
10252    }
10253    iax2_capability = capability;
10254    
10255    ucfg = ast_config_load("users.conf");
10256    if (ucfg) {
10257       struct ast_variable *gen;
10258       int genhasiax;
10259       int genregisteriax;
10260       const char *hasiax, *registeriax;
10261       
10262       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10263       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10264       gen = ast_variable_browse(ucfg, "general");
10265       cat = ast_category_browse(ucfg, NULL);
10266       while (cat) {
10267          if (strcasecmp(cat, "general")) {
10268             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10269             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10270             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10271                /* Start with general parameters, then specific parameters, user and peer */
10272                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10273                if (user) {
10274                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10275                   user = user_unref(user);
10276                }
10277                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10278                if (peer) {
10279                   if (ast_test_flag(peer, IAX_DYNAMIC))
10280                      reg_source_db(peer);
10281                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10282                   peer = peer_unref(peer);
10283                }
10284             }
10285             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10286                char tmp[256];
10287                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10288                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10289                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10290                if (!host)
10291                   host = ast_variable_retrieve(ucfg, "general", "host");
10292                if (!username)
10293                   username = ast_variable_retrieve(ucfg, "general", "username");
10294                if (!secret)
10295                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10296                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10297                   if (!ast_strlen_zero(secret))
10298                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10299                   else
10300                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10301                   iax2_register(tmp, 0);
10302                }
10303             }
10304          }
10305          cat = ast_category_browse(ucfg, cat);
10306       }
10307       ast_config_destroy(ucfg);
10308    }
10309    
10310    cat = ast_category_browse(cfg, NULL);
10311    while(cat) {
10312       if (strcasecmp(cat, "general")) {
10313          utype = ast_variable_retrieve(cfg, cat, "type");
10314          if (utype) {
10315             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10316                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10317                if (user) {
10318                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10319                   user = user_unref(user);
10320                }
10321             }
10322             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10323                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10324                if (peer) {
10325                   if (ast_test_flag(peer, IAX_DYNAMIC))
10326                      reg_source_db(peer);
10327                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10328                   peer = peer_unref(peer);
10329                }
10330             } else if (strcasecmp(utype, "user")) {
10331                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10332             }
10333          } else
10334             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10335       }
10336       cat = ast_category_browse(cfg, cat);
10337    }
10338    ast_config_destroy(cfg);
10339    set_timing();
10340    return 1;
10341 }
10342 
10343 static void poke_all_peers(void)
10344 {
10345    struct ao2_iterator i;
10346    struct iax2_peer *peer;
10347 
10348    i = ao2_iterator_init(peers, 0);
10349    while ((peer = ao2_iterator_next(&i))) {
10350       iax2_poke_peer(peer, 0);
10351       peer_unref(peer);
10352    }
10353 }
10354 static int reload_config(void)
10355 {
10356    char *config = "iax.conf";
10357    struct iax2_registry *reg;
10358 
10359    if (set_config(config, 1) > 0) {
10360       prune_peers();
10361       prune_users();
10362       AST_LIST_LOCK(&registrations);
10363       AST_LIST_TRAVERSE(&registrations, reg, entry)
10364          iax2_do_register(reg);
10365       AST_LIST_UNLOCK(&registrations);
10366       /* Qualify hosts, too */
10367       poke_all_peers();
10368    }
10369    reload_firmware(0);
10370    iax_provision_reload();
10371 
10372    return 0;
10373 }
10374 
10375 static int iax2_reload(int fd, int argc, char *argv[])
10376 {
10377    return reload_config();
10378 }
10379 
10380 static int reload(void)
10381 {
10382    return reload_config();
10383 }
10384 
10385 static int cache_get_callno_locked(const char *data)
10386 {
10387    struct sockaddr_in sin;
10388    int x;
10389    int callno;
10390    struct iax_ie_data ied;
10391    struct create_addr_info cai;
10392    struct parsed_dial_string pds;
10393    char *tmpstr;
10394 
10395    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10396       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10397          look up entries for a single context */
10398       if (!ast_mutex_trylock(&iaxsl[x])) {
10399          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10400             return x;
10401          ast_mutex_unlock(&iaxsl[x]);
10402       }
10403    }
10404 
10405    /* No match found, we need to create a new one */
10406 
10407    memset(&cai, 0, sizeof(cai));
10408    memset(&ied, 0, sizeof(ied));
10409    memset(&pds, 0, sizeof(pds));
10410 
10411    tmpstr = ast_strdupa(data);
10412    parse_dial_string(tmpstr, &pds);
10413 
10414    if (ast_strlen_zero(pds.peer)) {
10415       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10416       return -1;
10417    }
10418 
10419    /* Populate our address from the given */
10420    if (create_addr(pds.peer, NULL, &sin, &cai))
10421       return -1;
10422 
10423    if (option_debug)
10424       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10425          pds.peer, pds.username, pds.password, pds.context);
10426 
10427    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10428    if (callno < 1) {
10429       ast_log(LOG_WARNING, "Unable to create call\n");
10430       return -1;
10431    }
10432 
10433    ast_string_field_set(iaxs[callno], dproot, data);
10434    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10435 
10436    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10437    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10438    /* the string format is slightly different from a standard dial string,
10439       because the context appears in the 'exten' position
10440    */
10441    if (pds.exten)
10442       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10443    if (pds.username)
10444       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10445    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10446    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10447    /* Keep password handy */
10448    if (pds.password)
10449       ast_string_field_set(iaxs[callno], secret, pds.password);
10450    if (pds.key)
10451       ast_string_field_set(iaxs[callno], outkey, pds.key);
10452    /* Start the call going */
10453    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10454 
10455    return callno;
10456 }
10457 
10458 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10459 {
10460    struct iax2_dpcache *dp, *prev = NULL, *next;
10461    struct timeval tv;
10462    int x;
10463    int com[2];
10464    int timeout;
10465    int old=0;
10466    int outfd;
10467    int abort;
10468    int callno;
10469    struct ast_channel *c;
10470    struct ast_frame *f;
10471    gettimeofday(&tv, NULL);
10472    dp = dpcache;
10473    while(dp) {
10474       next = dp->next;
10475       /* Expire old caches */
10476       if (ast_tvcmp(tv, dp->expiry) > 0) {
10477             /* It's expired, let it disappear */
10478             if (prev)
10479                prev->next = dp->next;
10480             else
10481                dpcache = dp->next;
10482             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10483                /* Free memory and go again */
10484                free(dp);
10485             } else {
10486                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);
10487             }
10488             dp = next;
10489             continue;
10490       }
10491       /* We found an entry that matches us! */
10492       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10493          break;
10494       prev = dp;
10495       dp = next;
10496    }
10497    if (!dp) {
10498       /* No matching entry.  Create a new one. */
10499       /* First, can we make a callno? */
10500       callno = cache_get_callno_locked(data);
10501       if (callno < 0) {
10502          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10503          return NULL;
10504       }
10505       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10506          ast_mutex_unlock(&iaxsl[callno]);
10507          return NULL;
10508       }
10509       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10510       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10511       gettimeofday(&dp->expiry, NULL);
10512       dp->orig = dp->expiry;
10513       /* Expires in 30 mins by default */
10514       dp->expiry.tv_sec += iaxdefaultdpcache;
10515       dp->next = dpcache;
10516       dp->flags = CACHE_FLAG_PENDING;
10517       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10518          dp->waiters[x] = -1;
10519       dpcache = dp;
10520       dp->peer = iaxs[callno]->dpentries;
10521       iaxs[callno]->dpentries = dp;
10522       /* Send the request if we're already up */
10523       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10524          iax2_dprequest(dp, callno);
10525       ast_mutex_unlock(&iaxsl[callno]);
10526    }
10527    /* By here we must have a dp */
10528    if (dp->flags & CACHE_FLAG_PENDING) {
10529       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10530          for a reply to come back so long as it's pending */
10531       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10532          /* Find an empty slot */
10533          if (dp->waiters[x] < 0)
10534             break;
10535       }
10536       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10537          ast_log(LOG_WARNING, "No more waiter positions available\n");
10538          return NULL;
10539       }
10540       if (pipe(com)) {
10541          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10542          return NULL;
10543       }
10544       dp->waiters[x] = com[1];
10545       /* Okay, now we wait */
10546       timeout = iaxdefaulttimeout * 1000;
10547       /* Temporarily unlock */
10548       ast_mutex_unlock(&dpcache_lock);
10549       /* Defer any dtmf */
10550       if (chan)
10551          old = ast_channel_defer_dtmf(chan);
10552       abort = 0;
10553       while(timeout) {
10554          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10555          if (outfd > -1) {
10556             break;
10557          }
10558          if (c) {
10559             f = ast_read(c);
10560             if (f)
10561                ast_frfree(f);
10562             else {
10563                /* Got hung up on, abort! */
10564                break;
10565                abort = 1;
10566             }
10567          }
10568       }
10569       if (!timeout) {
10570          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10571       }
10572       ast_mutex_lock(&dpcache_lock);
10573       dp->waiters[x] = -1;
10574       close(com[1]);
10575       close(com[0]);
10576       if (abort) {
10577          /* Don't interpret anything, just abort.  Not sure what th epoint
10578            of undeferring dtmf on a hung up channel is but hey whatever */
10579          if (!old && chan)
10580             ast_channel_undefer_dtmf(chan);
10581          return NULL;
10582       }
10583       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10584          /* Now to do non-independent analysis the results of our wait */
10585          if (dp->flags & CACHE_FLAG_PENDING) {
10586             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10587                pending.  Don't let it take as long to timeout. */
10588             dp->flags &= ~CACHE_FLAG_PENDING;
10589             dp->flags |= CACHE_FLAG_TIMEOUT;
10590             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10591                systems without leaving it unavailable once the server comes back online */
10592             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10593             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
10594                if (dp->waiters[x] > -1) {
10595                   if (write(dp->waiters[x], "asdf", 4) < 0) {
10596                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10597                   }
10598                }
10599             }
10600          }
10601       }
10602       /* Our caller will obtain the rest */
10603       if (!old && chan)
10604          ast_channel_undefer_dtmf(chan);
10605    }
10606    return dp;  
10607 }
10608 
10609 /*! \brief Part of the IAX2 switch interface */
10610 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10611 {
10612    struct iax2_dpcache *dp;
10613    int res = 0;
10614 #if 0
10615    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10616 #endif
10617    if ((priority != 1) && (priority != 2))
10618       return 0;
10619    ast_mutex_lock(&dpcache_lock);
10620    dp = find_cache(chan, data, context, exten, priority);
10621    if (dp) {
10622       if (dp->flags & CACHE_FLAG_EXISTS)
10623          res= 1;
10624    }
10625    ast_mutex_unlock(&dpcache_lock);
10626    if (!dp) {
10627       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10628    }
10629    return res;
10630 }
10631 
10632 /*! \brief part of the IAX2 dial plan switch interface */
10633 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10634 {
10635    int res = 0;
10636    struct iax2_dpcache *dp;
10637 #if 0
10638    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10639 #endif
10640    if ((priority != 1) && (priority != 2))
10641       return 0;
10642    ast_mutex_lock(&dpcache_lock);
10643    dp = find_cache(chan, data, context, exten, priority);
10644    if (dp) {
10645       if (dp->flags & CACHE_FLAG_CANEXIST)
10646          res= 1;
10647    }
10648    ast_mutex_unlock(&dpcache_lock);
10649    if (!dp) {
10650       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10651    }
10652    return res;
10653 }
10654 
10655 /*! \brief Part of the IAX2 Switch interface */
10656 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10657 {
10658    int res = 0;
10659    struct iax2_dpcache *dp;
10660 #if 0
10661    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10662 #endif
10663    if ((priority != 1) && (priority != 2))
10664       return 0;
10665    ast_mutex_lock(&dpcache_lock);
10666    dp = find_cache(chan, data, context, exten, priority);
10667    if (dp) {
10668       if (dp->flags & CACHE_FLAG_MATCHMORE)
10669          res= 1;
10670    }
10671    ast_mutex_unlock(&dpcache_lock);
10672    if (!dp) {
10673       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10674    }
10675    return res;
10676 }
10677 
10678 /*! \brief Execute IAX2 dialplan switch */
10679 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10680 {
10681    char odata[256];
10682    char req[256];
10683    char *ncontext;
10684    struct iax2_dpcache *dp;
10685    struct ast_app *dial;
10686 #if 0
10687    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);
10688 #endif
10689    if (priority == 2) {
10690       /* Indicate status, can be overridden in dialplan */
10691       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10692       if (dialstatus) {
10693          dial = pbx_findapp(dialstatus);
10694          if (dial) 
10695             pbx_exec(chan, dial, "");
10696       }
10697       return -1;
10698    } else if (priority != 1)
10699       return -1;
10700    ast_mutex_lock(&dpcache_lock);
10701    dp = find_cache(chan, data, context, exten, priority);
10702    if (dp) {
10703       if (dp->flags & CACHE_FLAG_EXISTS) {
10704          ast_copy_string(odata, data, sizeof(odata));
10705          ncontext = strchr(odata, '/');
10706          if (ncontext) {
10707             *ncontext = '\0';
10708             ncontext++;
10709             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10710          } else {
10711             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10712          }
10713          if (option_verbose > 2)
10714             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10715       } else {
10716          ast_mutex_unlock(&dpcache_lock);
10717          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10718          return -1;
10719       }
10720    }
10721    ast_mutex_unlock(&dpcache_lock);
10722    dial = pbx_findapp("Dial");
10723    if (dial) {
10724       return pbx_exec(chan, dial, req);
10725    } else {
10726       ast_log(LOG_WARNING, "No dial application registered\n");
10727    }
10728    return -1;
10729 }
10730 
10731 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10732 {
10733    struct iax2_peer *peer;
10734    char *peername, *colname;
10735 
10736    peername = ast_strdupa(data);
10737 
10738    /* if our channel, return the IP address of the endpoint of current channel */
10739    if (!strcmp(peername,"CURRENTCHANNEL")) {
10740            unsigned short callno;
10741       if (chan->tech != &iax2_tech)
10742          return -1;
10743       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10744       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10745       return 0;
10746    }
10747 
10748    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10749       *colname++ = '\0';
10750    else if ((colname = strchr(peername, '|')))
10751       *colname++ = '\0';
10752    else
10753       colname = "ip";
10754 
10755    if (!(peer = find_peer(peername, 1)))
10756       return -1;
10757 
10758    if (!strcasecmp(colname, "ip")) {
10759       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10760    } else  if (!strcasecmp(colname, "status")) {
10761       peer_status(peer, buf, len); 
10762    } else  if (!strcasecmp(colname, "mailbox")) {
10763       ast_copy_string(buf, peer->mailbox, len);
10764    } else  if (!strcasecmp(colname, "context")) {
10765       ast_copy_string(buf, peer->context, len);
10766    } else  if (!strcasecmp(colname, "expire")) {
10767       snprintf(buf, len, "%d", peer->expire);
10768    } else  if (!strcasecmp(colname, "dynamic")) {
10769       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10770    } else  if (!strcasecmp(colname, "callerid_name")) {
10771       ast_copy_string(buf, peer->cid_name, len);
10772    } else  if (!strcasecmp(colname, "callerid_num")) {
10773       ast_copy_string(buf, peer->cid_num, len);
10774    } else  if (!strcasecmp(colname, "codecs")) {
10775       ast_getformatname_multiple(buf, len -1, peer->capability);
10776    } else  if (!strncasecmp(colname, "codec[", 6)) {
10777       char *codecnum, *ptr;
10778       int index = 0, codec = 0;
10779       
10780       codecnum = strchr(colname, '[');
10781       *codecnum = '\0';
10782       codecnum++;
10783       if ((ptr = strchr(codecnum, ']'))) {
10784          *ptr = '\0';
10785       }
10786       index = atoi(codecnum);
10787       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10788          ast_copy_string(buf, ast_getformatname(codec), len);
10789       } else {
10790          buf[0] = '\0';
10791       }
10792    } else {
10793       buf[0] = '\0';
10794    }
10795 
10796    peer_unref(peer);
10797 
10798    return 0;
10799 }
10800 
10801 struct ast_custom_function iaxpeer_function = {
10802    .name = "IAXPEER",
10803    .synopsis = "Gets IAX peer information",
10804    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10805    .read = function_iaxpeer,
10806    .desc = "If peername specified, valid items are:\n"
10807    "- ip (default)          The IP address.\n"
10808    "- status                The peer's status (if qualify=yes)\n"
10809    "- mailbox               The configured mailbox.\n"
10810    "- context               The configured context.\n"
10811    "- expire                The epoch time of the next expire.\n"
10812    "- dynamic               Is it dynamic? (yes/no).\n"
10813    "- callerid_name         The configured Caller ID name.\n"
10814    "- callerid_num          The configured Caller ID number.\n"
10815    "- codecs                The configured codecs.\n"
10816    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10817    "\n"
10818    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10819    "\n"
10820 };
10821 
10822 
10823 /*! \brief Part of the device state notification system ---*/
10824 static int iax2_devicestate(void *data) 
10825 {
10826    struct parsed_dial_string pds;
10827    char *tmp = ast_strdupa(data);
10828    struct iax2_peer *p;
10829    int res = AST_DEVICE_INVALID;
10830 
10831    memset(&pds, 0, sizeof(pds));
10832    parse_dial_string(tmp, &pds);
10833 
10834    if (ast_strlen_zero(pds.peer)) {
10835       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10836       return res;
10837    }
10838    
10839    if (option_debug > 2)
10840       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10841 
10842    /* SLD: FIXME: second call to find_peer during registration */
10843    if (!(p = find_peer(pds.peer, 1)))
10844       return res;
10845 
10846    res = AST_DEVICE_UNAVAILABLE;
10847    if (option_debug > 2) 
10848       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10849          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10850    
10851    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10852        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10853       /* Peer is registered, or have default IP address
10854          and a valid registration */
10855       if (p->historicms == 0 || p->historicms <= p->maxms)
10856          /* let the core figure out whether it is in use or not */
10857          res = AST_DEVICE_UNKNOWN;  
10858    }
10859 
10860    peer_unref(p);
10861 
10862    return res;
10863 }
10864 
10865 static struct ast_switch iax2_switch = 
10866 {
10867    name:          "IAX2",
10868    description:      "IAX Remote Dialplan Switch",
10869    exists:        iax2_exists,
10870    canmatch:      iax2_canmatch,
10871    exec:       iax2_exec,
10872    matchmore:     iax2_matchmore,
10873 };
10874 
10875 static char show_stats_usage[] =
10876 "Usage: iax2 show stats\n"
10877 "       Display statistics on IAX channel driver.\n";
10878 
10879 static char show_cache_usage[] =
10880 "Usage: iax2 show cache\n"
10881 "       Display currently cached IAX Dialplan results.\n";
10882 
10883 static char show_peer_usage[] =
10884 "Usage: iax2 show peer <name>\n"
10885 "       Display details on specific IAX peer\n";
10886 
10887 static char prune_realtime_usage[] =
10888 "Usage: iax2 prune realtime [<peername>|all]\n"
10889 "       Prunes object(s) from the cache\n";
10890 
10891 static char iax2_reload_usage[] =
10892 "Usage: iax2 reload\n"
10893 "       Reloads IAX configuration from iax.conf\n";
10894 
10895 static char show_prov_usage[] =
10896 "Usage: iax2 provision <host> <template> [forced]\n"
10897 "       Provisions the given peer or IP address using a template\n"
10898 "       matching either 'template' or '*' if the template is not\n"
10899 "       found.  If 'forced' is specified, even empty provisioning\n"
10900 "       fields will be provisioned as empty fields.\n";
10901 
10902 static char show_users_usage[] = 
10903 "Usage: iax2 show users [like <pattern>]\n"
10904 "       Lists all known IAX2 users.\n"
10905 "       Optional regular expression pattern is used to filter the user list.\n";
10906 
10907 static char show_channels_usage[] = 
10908 "Usage: iax2 show channels\n"
10909 "       Lists all currently active IAX channels.\n";
10910 
10911 static char show_netstats_usage[] = 
10912 "Usage: iax2 show netstats\n"
10913 "       Lists network status for all currently active IAX channels.\n";
10914 
10915 static char show_threads_usage[] = 
10916 "Usage: iax2 show threads\n"
10917 "       Lists status of IAX helper threads\n";
10918 
10919 static char show_peers_usage[] = 
10920 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10921 "       Lists all known IAX2 peers.\n"
10922 "       Optional 'registered' argument lists only peers with known addresses.\n"
10923 "       Optional regular expression pattern is used to filter the peer list.\n";
10924 
10925 static char show_firmware_usage[] = 
10926 "Usage: iax2 show firmware\n"
10927 "       Lists all known IAX firmware images.\n";
10928 
10929 static char show_reg_usage[] =
10930 "Usage: iax2 show registry\n"
10931 "       Lists all registration requests and status.\n";
10932 
10933 static char debug_usage[] = 
10934 "Usage: iax2 set debug\n"
10935 "       Enables dumping of IAX packets for debugging purposes\n";
10936 
10937 static char no_debug_usage[] = 
10938 "Usage: iax2 set debug off\n"
10939 "       Disables dumping of IAX packets for debugging purposes\n";
10940 
10941 static char debug_trunk_usage[] =
10942 "Usage: iax2 set debug trunk\n"
10943 "       Requests current status of IAX trunking\n";
10944 
10945 static char no_debug_trunk_usage[] =
10946 "Usage: iax2 set debug trunk off\n"
10947 "       Requests current status of IAX trunking\n";
10948 
10949 static char debug_jb_usage[] =
10950 "Usage: iax2 set debug jb\n"
10951 "       Enables jitterbuffer debugging information\n";
10952 
10953 static char no_debug_jb_usage[] =
10954 "Usage: iax2 set debug jb off\n"
10955 "       Disables jitterbuffer debugging information\n";
10956 
10957 static char iax2_test_losspct_usage[] =
10958 "Usage: iax2 test losspct <percentage>\n"
10959 "       For testing, throws away <percentage> percent of incoming packets\n";
10960 
10961 #ifdef IAXTESTS
10962 static char iax2_test_late_usage[] =
10963 "Usage: iax2 test late <ms>\n"
10964 "       For testing, count the next frame as <ms> ms late\n";
10965 
10966 static char iax2_test_resync_usage[] =
10967 "Usage: iax2 test resync <ms>\n"
10968 "       For testing, adjust all future frames by <ms> ms\n";
10969 
10970 static char iax2_test_jitter_usage[] =
10971 "Usage: iax2 test jitter <ms> <pct>\n"
10972 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10973 #endif /* IAXTESTS */
10974 
10975 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10976    { "iax2", "trunk", "debug", NULL },
10977    iax2_do_trunk_debug, NULL,
10978    NULL };
10979 
10980 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10981    { "iax2", "jb", "debug", NULL },
10982    iax2_do_jb_debug, NULL,
10983    NULL };
10984 
10985 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10986    { "iax2", "no", "debug", NULL },
10987    iax2_no_debug, NULL,
10988    NULL };
10989 
10990 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10991    { "iax2", "no", "trunk", "debug", NULL },
10992    iax2_no_trunk_debug, NULL,
10993    NULL };
10994 
10995 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10996    { "iax2", "no", "jb", "debug", NULL },
10997    iax2_no_jb_debug, NULL,
10998    NULL };
10999 
11000 static struct ast_cli_entry cli_iax2[] = {
11001    { { "iax2", "show", "cache", NULL },
11002    iax2_show_cache, "Display IAX cached dialplan",
11003    show_cache_usage, NULL, },
11004 
11005    { { "iax2", "show", "channels", NULL },
11006    iax2_show_channels, "List active IAX channels",
11007    show_channels_usage, NULL, },
11008 
11009    { { "iax2", "show", "firmware", NULL },
11010    iax2_show_firmware, "List available IAX firmwares",
11011    show_firmware_usage, NULL, },
11012 
11013    { { "iax2", "show", "netstats", NULL },
11014    iax2_show_netstats, "List active IAX channel netstats",
11015    show_netstats_usage, NULL, },
11016 
11017    { { "iax2", "show", "peers", NULL },
11018    iax2_show_peers, "List defined IAX peers",
11019    show_peers_usage, NULL, },
11020 
11021    { { "iax2", "show", "registry", NULL },
11022    iax2_show_registry, "Display IAX registration status",
11023    show_reg_usage, NULL, },
11024 
11025    { { "iax2", "show", "stats", NULL },
11026    iax2_show_stats, "Display IAX statistics",
11027    show_stats_usage, NULL, },
11028 
11029    { { "iax2", "show", "threads", NULL },
11030    iax2_show_threads, "Display IAX helper thread info",
11031    show_threads_usage, NULL, },
11032 
11033    { { "iax2", "show", "users", NULL },
11034    iax2_show_users, "List defined IAX users",
11035    show_users_usage, NULL, },
11036 
11037    { { "iax2", "prune", "realtime", NULL },
11038    iax2_prune_realtime, "Prune a cached realtime lookup",
11039    prune_realtime_usage, complete_iax2_show_peer },
11040 
11041    { { "iax2", "reload", NULL },
11042    iax2_reload, "Reload IAX configuration",
11043    iax2_reload_usage },
11044 
11045    { { "iax2", "show", "peer", NULL },
11046    iax2_show_peer, "Show details on specific IAX peer",
11047    show_peer_usage, complete_iax2_show_peer },
11048 
11049    { { "iax2", "set", "debug", NULL },
11050    iax2_do_debug, "Enable IAX debugging",
11051    debug_usage },
11052 
11053    { { "iax2", "set", "debug", "trunk", NULL },
11054    iax2_do_trunk_debug, "Enable IAX trunk debugging",
11055    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
11056 
11057    { { "iax2", "set", "debug", "jb", NULL },
11058    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
11059    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
11060 
11061    { { "iax2", "set", "debug", "off", NULL },
11062    iax2_no_debug, "Disable IAX debugging",
11063    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
11064 
11065    { { "iax2", "set", "debug", "trunk", "off", NULL },
11066    iax2_no_trunk_debug, "Disable IAX trunk debugging",
11067    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
11068 
11069    { { "iax2", "set", "debug", "jb", "off", NULL },
11070    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
11071    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
11072 
11073    { { "iax2", "test", "losspct", NULL },
11074    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
11075    iax2_test_losspct_usage },
11076 
11077    { { "iax2", "provision", NULL },
11078    iax2_prov_cmd, "Provision an IAX device",
11079    show_prov_usage, iax2_prov_complete_template_3rd },
11080 
11081 #ifdef IAXTESTS
11082    { { "iax2", "test", "late", NULL },
11083    iax2_test_late, "Test the receipt of a late frame",
11084    iax2_test_late_usage },
11085 
11086    { { "iax2", "test", "resync", NULL },
11087    iax2_test_resync, "Test a resync in received timestamps",
11088    iax2_test_resync_usage },
11089 
11090    { { "iax2", "test", "jitter", NULL },
11091    iax2_test_jitter, "Simulates jitter for testing",
11092    iax2_test_jitter_usage },
11093 #endif /* IAXTESTS */
11094 };
11095 
11096 static int __unload_module(void)
11097 {
11098    struct iax2_thread *thread = NULL;
11099    int x;
11100 
11101    /* Make sure threads do not hold shared resources when they are canceled */
11102    
11103    /* Grab the sched lock resource to keep it away from threads about to die */
11104    /* Cancel the network thread, close the net socket */
11105    if (netthreadid != AST_PTHREADT_NULL) {
11106       AST_LIST_LOCK(&iaxq.queue);
11107       ast_mutex_lock(&sched_lock);
11108       pthread_cancel(netthreadid);
11109       ast_cond_signal(&sched_cond);
11110       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11111       AST_LIST_UNLOCK(&iaxq.queue);
11112       pthread_join(netthreadid, NULL);
11113    }
11114    if (schedthreadid != AST_PTHREADT_NULL) {
11115       ast_mutex_lock(&sched_lock);  
11116       pthread_cancel(schedthreadid);
11117       ast_cond_signal(&sched_cond);
11118       ast_mutex_unlock(&sched_lock);   
11119       pthread_join(schedthreadid, NULL);
11120    }
11121    
11122    /* Call for all threads to halt */
11123    AST_LIST_LOCK(&idle_list);
11124    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11125       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11126       pthread_cancel(thread->threadid);
11127    }
11128    AST_LIST_TRAVERSE_SAFE_END
11129    AST_LIST_UNLOCK(&idle_list);
11130 
11131    AST_LIST_LOCK(&active_list);
11132    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11133       AST_LIST_REMOVE_CURRENT(&active_list, list);
11134       pthread_cancel(thread->threadid);
11135    }
11136    AST_LIST_TRAVERSE_SAFE_END
11137    AST_LIST_UNLOCK(&active_list);
11138 
11139    AST_LIST_LOCK(&dynamic_list);
11140         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11141       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11142       pthread_cancel(thread->threadid);
11143         }
11144    AST_LIST_TRAVERSE_SAFE_END
11145         AST_LIST_UNLOCK(&dynamic_list);
11146 
11147    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11148 
11149    /* Wait for threads to exit */
11150    while(0 < iaxactivethreadcount)
11151       usleep(10000);
11152    
11153    ast_netsock_release(netsock);
11154    ast_netsock_release(outsock);
11155    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11156       if (iaxs[x]) {
11157          iax2_destroy(x);
11158       }
11159    }
11160    ast_manager_unregister( "IAXpeers" );
11161    ast_manager_unregister( "IAXnetstats" );
11162    ast_unregister_application(papp);
11163    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11164    ast_unregister_switch(&iax2_switch);
11165    ast_channel_unregister(&iax2_tech);
11166    delete_users();
11167    iax_provision_unload();
11168    sched_context_destroy(sched);
11169    reload_firmware(1);
11170 
11171    ast_mutex_destroy(&waresl.lock);
11172 
11173    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11174       ast_mutex_destroy(&iaxsl[x]);
11175    }
11176 
11177    ao2_ref(peers, -1);
11178    ao2_ref(users, -1);
11179    ao2_ref(iax_peercallno_pvts, -1);
11180 
11181    return 0;
11182 }
11183 
11184 static int unload_module(void)
11185 {
11186    ast_custom_function_unregister(&iaxpeer_function);
11187    return __unload_module();
11188 }
11189 
11190 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11191 {
11192    struct iax2_peer *peer = obj;
11193 
11194    if (peer->sockfd < 0)
11195       peer->sockfd = defaultsockfd;
11196 
11197    return 0;
11198 }
11199 
11200 static int pvt_hash_cb(const void *obj, const int flags)
11201 {
11202    const struct chan_iax2_pvt *pvt = obj;
11203 
11204    return pvt->peercallno;
11205 }
11206 
11207 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11208 {
11209    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11210 
11211    /* The frames_received field is used to hold whether we're matching
11212     * against a full frame or not ... */
11213 
11214    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11215       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11216 }
11217 
11218 /*! \brief Load IAX2 module, load configuraiton ---*/
11219 static int load_module(void)
11220 {
11221    char *config = "iax.conf";
11222    int res = 0;
11223    int x;
11224    struct iax2_registry *reg = NULL;
11225 
11226    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11227    if (!peers)
11228       return AST_MODULE_LOAD_FAILURE;
11229    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11230    if (!users) {
11231       ao2_ref(peers, -1);
11232       return AST_MODULE_LOAD_FAILURE;
11233    }
11234    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11235    if (!iax_peercallno_pvts) {
11236       ao2_ref(peers, -1);
11237       ao2_ref(users, -1);
11238       return AST_MODULE_LOAD_FAILURE;
11239    }
11240 
11241    ast_custom_function_register(&iaxpeer_function);
11242 
11243    iax_set_output(iax_debug_output);
11244    iax_set_error(iax_error_output);
11245    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11246    
11247 #ifdef HAVE_DAHDI
11248 #ifdef DAHDI_TIMERACK
11249    timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
11250    if (timingfd < 0)
11251 #endif
11252       timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
11253    if (timingfd < 0) 
11254       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11255 #endif
11256 
11257    memset(iaxs, 0, sizeof(iaxs));
11258 
11259    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11260       ast_mutex_init(&iaxsl[x]);
11261    }
11262    
11263    ast_cond_init(&sched_cond, NULL);
11264 
11265    io = io_context_create();
11266    sched = sched_context_create();
11267    
11268    if (!io || !sched) {
11269       ast_log(LOG_ERROR, "Out of memory\n");
11270       return -1;
11271    }
11272 
11273    netsock = ast_netsock_list_alloc();
11274    if (!netsock) {
11275       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11276       return -1;
11277    }
11278    ast_netsock_init(netsock);
11279 
11280    outsock = ast_netsock_list_alloc();
11281    if (!outsock) {
11282       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11283       return -1;
11284    }
11285    ast_netsock_init(outsock);
11286 
11287    ast_mutex_init(&waresl.lock);
11288 
11289    AST_LIST_HEAD_INIT(&iaxq.queue);
11290    
11291    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11292 
11293    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11294    
11295    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11296    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11297 
11298    if(set_config(config, 0) == -1)
11299       return AST_MODULE_LOAD_DECLINE;
11300 
11301    if (ast_channel_register(&iax2_tech)) {
11302       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11303       __unload_module();
11304       return -1;
11305    }
11306 
11307    if (ast_register_switch(&iax2_switch)) 
11308       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11309 
11310    res = start_network_thread();
11311    if (!res) {
11312       if (option_verbose > 1) 
11313          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11314    } else {
11315       ast_log(LOG_ERROR, "Unable to start network thread\n");
11316       ast_netsock_release(netsock);
11317       ast_netsock_release(outsock);
11318    }
11319 
11320    AST_LIST_LOCK(&registrations);
11321    AST_LIST_TRAVERSE(&registrations, reg, entry)
11322       iax2_do_register(reg);
11323    AST_LIST_UNLOCK(&registrations); 
11324 
11325    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11326    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11327 
11328    reload_firmware(0);
11329    iax_provision_reload();
11330    return res;
11331 }
11332 
11333 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11334       .load = load_module,
11335       .unload = unload_module,
11336       .reload = reload,
11337           );

Generated on Wed Feb 11 11:59:49 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7