Tue Jul 14 23:09:42 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: 205471 $")
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 & ~AST_FORMAT_AUDIO_UNDEFINED)
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 } iax2_state;
00236 
00237 struct iax2_context {
00238    char context[AST_MAX_CONTEXT];
00239    struct iax2_context *next;
00240 };
00241 
00242 enum {
00243    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00244    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00245    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00246    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00247    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00248    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00249    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00250    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00251         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00252    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00253    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00254    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00255    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00256    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00257    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00258    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00259    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00260    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00261    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00262    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00263    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00264    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00265    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00266    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00267    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00268    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00269                        response, so that we've achieved a three-way handshake with
00270                        them before sending voice or anything else*/
00271    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00272 } iax2_flags;
00273 
00274 static int global_rtautoclear = 120;
00275 
00276 static int reload_config(void);
00277 static int iax2_reload(int fd, int argc, char *argv[]);
00278 
00279 
00280 struct iax2_user {
00281    AST_DECLARE_STRING_FIELDS(
00282       AST_STRING_FIELD(name);
00283       AST_STRING_FIELD(secret);
00284       AST_STRING_FIELD(dbsecret);
00285       AST_STRING_FIELD(accountcode);
00286       AST_STRING_FIELD(mohinterpret);
00287       AST_STRING_FIELD(mohsuggest);
00288       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00289       AST_STRING_FIELD(language);
00290       AST_STRING_FIELD(cid_num);
00291       AST_STRING_FIELD(cid_name);
00292    );
00293    
00294    int authmethods;
00295    int encmethods;
00296    int amaflags;
00297    int adsi;
00298    unsigned int flags;
00299    int capability;
00300    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00301    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00302    struct ast_codec_pref prefs;
00303    struct ast_ha *ha;
00304    struct iax2_context *contexts;
00305    struct ast_variable *vars;
00306 };
00307 
00308 struct iax2_peer {
00309    AST_DECLARE_STRING_FIELDS(
00310       AST_STRING_FIELD(name);
00311       AST_STRING_FIELD(username);
00312       AST_STRING_FIELD(secret);
00313       AST_STRING_FIELD(dbsecret);
00314       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00315 
00316       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00317       AST_STRING_FIELD(context);      /*!< For transfers only */
00318       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00319       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00320       AST_STRING_FIELD(mohinterpret);
00321       AST_STRING_FIELD(mohsuggest);
00322       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00323       /* Suggested caller id if registering */
00324       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00325       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00326       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00327    );
00328    struct ast_codec_pref prefs;
00329    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00330    struct sockaddr_in addr;
00331    int formats;
00332    int sockfd;             /*!< Socket to use for transmission */
00333    struct in_addr mask;
00334    int adsi;
00335    unsigned int flags;
00336 
00337    /* Dynamic Registration fields */
00338    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00339    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00340    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00341 
00342    int expire;             /*!< Schedule entry for expiry */
00343    int expiry;             /*!< How soon to expire */
00344    int capability;               /*!< Capability */
00345 
00346    /* Qualification */
00347    int callno;             /*!< Call number of POKE request */
00348    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00349    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00350    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00351 
00352    int pokefreqok;               /*!< How often to check if the host is up */
00353    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00354    int historicms;               /*!< How long recent average responses took */
00355    int smoothing;             /*!< Sample over how many units to determine historic ms */
00356    
00357    struct ast_ha *ha;
00358 };
00359 
00360 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00361 
00362 static struct iax2_trunk_peer {
00363    ast_mutex_t lock;
00364    int sockfd;
00365    struct sockaddr_in addr;
00366    struct timeval txtrunktime;      /*!< Transmit trunktime */
00367    struct timeval rxtrunktime;      /*!< Receive trunktime */
00368    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00369    struct timeval trunkact;      /*!< Last trunk activity */
00370    unsigned int lastsent;        /*!< Last sent time */
00371    /* Trunk data and length */
00372    unsigned char *trunkdata;
00373    unsigned int trunkdatalen;
00374    unsigned int trunkdataalloc;
00375    struct iax2_trunk_peer *next;
00376    int trunkerror;
00377    int calls;
00378 } *tpeers = NULL;
00379 
00380 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00381 
00382 struct iax_firmware {
00383    struct iax_firmware *next;
00384    int fd;
00385    int mmaplen;
00386    int dead;
00387    struct ast_iax2_firmware_header *fwh;
00388    unsigned char *buf;
00389 };
00390 
00391 enum iax_reg_state {
00392    REG_STATE_UNREGISTERED = 0,
00393    REG_STATE_REGSENT,
00394    REG_STATE_AUTHSENT,
00395    REG_STATE_REGISTERED,
00396    REG_STATE_REJECTED,
00397    REG_STATE_TIMEOUT,
00398    REG_STATE_NOAUTH
00399 };
00400 
00401 enum iax_transfer_state {
00402    TRANSFER_NONE = 0,
00403    TRANSFER_BEGIN,
00404    TRANSFER_READY,
00405    TRANSFER_RELEASED,
00406    TRANSFER_PASSTHROUGH,
00407    TRANSFER_MBEGIN,
00408    TRANSFER_MREADY,
00409    TRANSFER_MRELEASED,
00410    TRANSFER_MPASSTHROUGH,
00411    TRANSFER_MEDIA,
00412    TRANSFER_MEDIAPASS
00413 };
00414 
00415 struct iax2_registry {
00416    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00417    char username[80];
00418    char secret[80];        /*!< Password or key name in []'s */
00419    char random[80];
00420    int expire;          /*!< Sched ID of expiration */
00421    int refresh;            /*!< How often to refresh */
00422    enum iax_reg_state regstate;
00423    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00424    int callno;          /*!< Associated call number if applicable */
00425    struct sockaddr_in us;        /*!< Who the server thinks we are */
00426    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00427    AST_LIST_ENTRY(iax2_registry) entry;
00428 };
00429 
00430 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00431 
00432 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00433 #define MIN_RETRY_TIME     100
00434 #define MAX_RETRY_TIME     10000
00435 
00436 #define MAX_JITTER_BUFFER  50
00437 #define MIN_JITTER_BUFFER  10
00438 
00439 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00440 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00441 
00442 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00443 
00444 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00445 #define TS_GAP_FOR_JB_RESYNC  5000
00446 
00447 /* used for first_iax_message and last_iax_message.  If this bit is set it was TX, else RX */
00448 #define MARK_IAX_SUBCLASS_TX  0x8000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxdynamicthreadnum = 0;
00454 static int iaxactivethreadcount = 0;
00455 
00456 struct iax_rr {
00457    int jitter;
00458    int losspct;
00459    int losscnt;
00460    int packets;
00461    int delay;
00462    int dropped;
00463    int ooo;
00464 };
00465 
00466 struct chan_iax2_pvt {
00467    /*! Socket to send/receive on for this call */
00468    int sockfd;
00469    /*! Last received voice format */
00470    int voiceformat;
00471    /*! Last received video format */
00472    int videoformat;
00473    /*! Last sent voice format */
00474    int svoiceformat;
00475    /*! Last sent video format */
00476    int svideoformat;
00477    /*! What we are capable of sending */
00478    int capability;
00479    /*! Last received timestamp */
00480    unsigned int last;
00481    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00482    unsigned int lastsent;
00483    /*! Timestamp of the last video frame sent */
00484    unsigned int lastvsent;
00485    /*! Next outgoing timestamp if everything is good */
00486    unsigned int nextpred;
00487    /*! iax frame subclass that began iax2_pvt entry. 0x8000 bit is set on TX */
00488    int first_iax_message;
00489    /*! Last iax frame subclass sent or received for a iax2_pvt. 0x8000 bit is set on TX */
00490    int last_iax_message;
00491    /*! True if the last voice we transmitted was not silence/CNG */
00492    int notsilenttx;
00493    /*! Ping time */
00494    unsigned int pingtime;
00495    /*! Max time for initial response */
00496    int maxtime;
00497    /*! Peer Address */
00498    struct sockaddr_in addr;
00499    /*! Actual used codec preferences */
00500    struct ast_codec_pref prefs;
00501    /*! Requested codec preferences */
00502    struct ast_codec_pref rprefs;
00503    /*! Our call number */
00504    unsigned short callno;
00505    /*! Peer callno */
00506    unsigned short peercallno;
00507    /*! Negotiated format, this is only used to remember what format was
00508        chosen for an unauthenticated call so that the channel can get
00509        created later using the right format */
00510    int chosenformat;
00511    /*! Peer selected format */
00512    int peerformat;
00513    /*! Peer capability */
00514    int peercapability;
00515    /*! timeval that we base our transmission on */
00516    struct timeval offset;
00517    /*! timeval that we base our delivery on */
00518    struct timeval rxcore;
00519    /*! The jitterbuffer */
00520         jitterbuf *jb;
00521    /*! active jb read scheduler id */
00522         int jbid;
00523    /*! LAG */
00524    int lag;
00525    /*! Error, as discovered by the manager */
00526    int error;
00527    /*! Owner if we have one */
00528    struct ast_channel *owner;
00529    /*! What's our state? */
00530    struct ast_flags state;
00531    /*! Expiry (optional) */
00532    int expiry;
00533    /*! Next outgoing sequence number */
00534    unsigned char oseqno;
00535    /*! Next sequence number they have not yet acknowledged */
00536    unsigned char rseqno;
00537    /*! Next incoming sequence number */
00538    unsigned char iseqno;
00539    /*! Last incoming sequence number we have acknowledged */
00540    unsigned char aseqno;
00541 
00542    AST_DECLARE_STRING_FIELDS(
00543       /*! Peer name */
00544       AST_STRING_FIELD(peer);
00545       /*! Default Context */
00546       AST_STRING_FIELD(context);
00547       /*! Caller ID if available */
00548       AST_STRING_FIELD(cid_num);
00549       AST_STRING_FIELD(cid_name);
00550       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00551       AST_STRING_FIELD(ani);
00552       /*! DNID */
00553       AST_STRING_FIELD(dnid);
00554       /*! RDNIS */
00555       AST_STRING_FIELD(rdnis);
00556       /*! Requested Extension */
00557       AST_STRING_FIELD(exten);
00558       /*! Expected Username */
00559       AST_STRING_FIELD(username);
00560       /*! Expected Secret */
00561       AST_STRING_FIELD(secret);
00562       /*! MD5 challenge */
00563       AST_STRING_FIELD(challenge);
00564       /*! Public keys permitted keys for incoming authentication */
00565       AST_STRING_FIELD(inkeys);
00566       /*! Private key for outgoing authentication */
00567       AST_STRING_FIELD(outkey);
00568       /*! Preferred language */
00569       AST_STRING_FIELD(language);
00570       /*! Hostname/peername for naming purposes */
00571       AST_STRING_FIELD(host);
00572 
00573       AST_STRING_FIELD(dproot);
00574       AST_STRING_FIELD(accountcode);
00575       AST_STRING_FIELD(mohinterpret);
00576       AST_STRING_FIELD(mohsuggest);
00577    );
00578    /*! AUTHREJ all AUTHREP frames */
00579    int authrej;
00580    /*! permitted authentication methods */
00581    int authmethods;
00582    /*! permitted encryption methods */
00583    int encmethods;
00584    /*! Encryption AES-128 Key */
00585    aes_encrypt_ctx ecx;
00586    /*! Decryption AES-128 Key corresponding to ecx */
00587    aes_decrypt_ctx mydcx;
00588    /*! Decryption AES-128 Key used to decrypt peer frames */
00589    aes_decrypt_ctx dcx;
00590    /*! 32 bytes of semi-random data */
00591    unsigned char semirand[32];
00592    /*! Associated registry */
00593    struct iax2_registry *reg;
00594    /*! Associated peer for poking */
00595    struct iax2_peer *peerpoke;
00596    /*! IAX_ flags */
00597    unsigned int flags;
00598    int adsi;
00599 
00600    /*! Transferring status */
00601    enum iax_transfer_state transferring;
00602    /*! Transfer identifier */
00603    int transferid;
00604    /*! Who we are IAX transfering to */
00605    struct sockaddr_in transfer;
00606    /*! What's the new call number for the transfer */
00607    unsigned short transfercallno;
00608    /*! Transfer decrypt AES-128 Key */
00609    aes_encrypt_ctx tdcx;
00610 
00611    /*! Status of knowledge of peer ADSI capability */
00612    int peeradsicpe;
00613 
00614    /*! Who we are bridged to */
00615    unsigned short bridgecallno;
00616    
00617    int pingid;       /*!< Transmit PING request */
00618    int lagid;        /*!< Retransmit lag request */
00619    int autoid;       /*!< Auto hangup for Dialplan requestor */
00620    int authid;       /*!< Authentication rejection ID */
00621    int authfail;        /*!< Reason to report failure */
00622    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00623    int calling_ton;
00624    int calling_tns;
00625    int calling_pres;
00626    int amaflags;
00627    struct iax2_dpcache *dpentries;
00628    struct ast_variable *vars;
00629    /*! last received remote rr */
00630    struct iax_rr remote_rr;
00631    /*! Current base time: (just for stats) */
00632    int min;
00633    /*! Dropped frame count: (just for stats) */
00634    int frames_dropped;
00635    /*! received frame count: (just for stats) */
00636    int frames_received;
00637 };
00638 
00639 static struct ast_iax2_queue {
00640    AST_LIST_HEAD(, iax_frame) queue;
00641    int count;
00642 } iaxq;
00643 
00644 /*!
00645  * This module will get much higher performance when doing a lot of
00646  * user and peer lookups if the number of buckets is increased from 1.
00647  * However, to maintain old behavior for Asterisk 1.4, these are set to
00648  * 1 by default.  When using multiple buckets, search order through these
00649  * containers is considered random, so you will not be able to depend on
00650  * the order the entires are specified in iax.conf for matching order. */
00651 #ifdef LOW_MEMORY
00652 #define MAX_PEER_BUCKETS 1
00653 /* #define MAX_PEER_BUCKETS 17 */
00654 #else
00655 #define MAX_PEER_BUCKETS 1
00656 /* #define MAX_PEER_BUCKETS 563 */
00657 #endif
00658 static struct ao2_container *peers;
00659 
00660 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00661 static struct ao2_container *users;
00662 
00663 static struct ast_firmware_list {
00664    struct iax_firmware *wares;
00665    ast_mutex_t lock;
00666 } waresl;
00667 
00668 /*! Extension exists */
00669 #define CACHE_FLAG_EXISTS     (1 << 0)
00670 /*! Extension is nonexistent */
00671 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00672 /*! Extension can exist */
00673 #define CACHE_FLAG_CANEXIST      (1 << 2)
00674 /*! Waiting to hear back response */
00675 #define CACHE_FLAG_PENDING    (1 << 3)
00676 /*! Timed out */
00677 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00678 /*! Request transmitted */
00679 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00680 /*! Timeout */
00681 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00682 /*! Matchmore */
00683 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00684 
00685 static struct iax2_dpcache {
00686    char peercontext[AST_MAX_CONTEXT];
00687    char exten[AST_MAX_EXTENSION];
00688    struct timeval orig;
00689    struct timeval expiry;
00690    int flags;
00691    unsigned short callno;
00692    int waiters[256];
00693    struct iax2_dpcache *next;
00694    struct iax2_dpcache *peer; /*!< For linking in peers */
00695 } *dpcache;
00696 
00697 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00698 
00699 static void reg_source_db(struct iax2_peer *p);
00700 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00701 
00702 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00703 
00704 #define IAX_IOSTATE_IDLE      0
00705 #define IAX_IOSTATE_READY     1
00706 #define IAX_IOSTATE_PROCESSING   2
00707 #define IAX_IOSTATE_SCHEDREADY   3
00708 
00709 #define IAX_TYPE_POOL    1
00710 #define IAX_TYPE_DYNAMIC 2
00711 
00712 struct iax2_pkt_buf {
00713    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00714    size_t len;
00715    unsigned char buf[1];
00716 };
00717 
00718 struct iax2_thread {
00719    AST_LIST_ENTRY(iax2_thread) list;
00720    int type;
00721    int iostate;
00722 #ifdef SCHED_MULTITHREADED
00723    void (*schedfunc)(const void *);
00724    const void *scheddata;
00725 #endif
00726 #ifdef DEBUG_SCHED_MULTITHREAD
00727    char curfunc[80];
00728 #endif   
00729    int actions;
00730    pthread_t threadid;
00731    int threadnum;
00732    struct sockaddr_in iosin;
00733    unsigned char readbuf[4096]; 
00734    unsigned char *buf;
00735    ssize_t buf_len;
00736    size_t buf_size;
00737    int iofd;
00738    time_t checktime;
00739    ast_mutex_t lock;
00740    ast_cond_t cond;
00741    unsigned int ready_for_signal:1;
00742    /*! if this thread is processing a full frame,
00743      some information about that frame will be stored
00744      here, so we can avoid dispatching any more full
00745      frames for that callno to other threads */
00746    struct {
00747       unsigned short callno;
00748       struct sockaddr_in sin;
00749       unsigned char type;
00750       unsigned char csub;
00751    } ffinfo;
00752    /*! Queued up full frames for processing.  If more full frames arrive for
00753     *  a call which this thread is already processing a full frame for, they
00754     *  are queued up here. */
00755    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00756 };
00757 
00758 /* Thread lists */
00759 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00760 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00761 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00762 
00763 static void *iax2_process_thread(void *data);
00764 
00765 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00766 {
00767    ast_mutex_lock(lock);
00768    ast_cond_signal(cond);
00769    ast_mutex_unlock(lock);
00770 }
00771 
00772 static void iax_debug_output(const char *data)
00773 {
00774    if (iaxdebug)
00775       ast_verbose("%s", data);
00776 }
00777 
00778 static void iax_error_output(const char *data)
00779 {
00780    ast_log(LOG_WARNING, "%s", data);
00781 }
00782 
00783 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00784 {
00785    va_list args;
00786    char buf[1024];
00787 
00788    va_start(args, fmt);
00789    vsnprintf(buf, 1024, fmt, args);
00790    va_end(args);
00791 
00792    ast_log(LOG_ERROR, "%s", buf);
00793 }
00794 
00795 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00796 {
00797    va_list args;
00798    char buf[1024];
00799 
00800    va_start(args, fmt);
00801    vsnprintf(buf, 1024, fmt, args);
00802    va_end(args);
00803 
00804    ast_log(LOG_WARNING, "%s", buf);
00805 }
00806 
00807 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00808 {
00809    va_list args;
00810    char buf[1024];
00811 
00812    va_start(args, fmt);
00813    vsnprintf(buf, 1024, fmt, args);
00814    va_end(args);
00815 
00816    ast_verbose("%s", buf);
00817 }
00818 
00819 /* XXX We probably should use a mutex when working with this XXX */
00820 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00821 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00822 static struct timeval lastused[ARRAY_LEN(iaxs)];
00823 
00824 /*!
00825  * \brief Another container of iax2_pvt structures
00826  *
00827  * Active IAX2 pvt structs are also stored in this container, if they are a part
00828  * of an active call where we know the remote side's call number.  The reason
00829  * for this is that incoming media frames do not contain our call number.  So,
00830  * instead of having to iterate the entire iaxs array, we use this container to
00831  * look up calls where the remote side is using a given call number.
00832  */
00833 static struct ao2_container *iax_peercallno_pvts;
00834 
00835 /*!
00836  *  * \brief Another container of iax2_pvt structures
00837  *  
00838  *  Active IAX2 pvt stucts used during transfering a call are stored here.  
00839  */
00840 static struct ao2_container *iax_transfercallno_pvts;
00841 
00842 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00843    but keeps the division between trunked and non-trunked better. */
00844 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00845 
00846 static int maxtrunkcall = TRUNK_CALL_START;
00847 static int maxnontrunkcall = 1;
00848 
00849 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);
00850 static int expire_registry(const void *data);
00851 static int iax2_answer(struct ast_channel *c);
00852 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00853 static int iax2_devicestate(void *data);
00854 static int iax2_digit_begin(struct ast_channel *c, char digit);
00855 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00856 static int iax2_do_register(struct iax2_registry *reg);
00857 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00858 static int iax2_hangup(struct ast_channel *c);
00859 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00860 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00861 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00862 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00863 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00864 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00865 static int iax2_sendtext(struct ast_channel *c, const char *text);
00866 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00867 static int iax2_transfer(struct ast_channel *c, const char *dest);
00868 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00869 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00870 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00871 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00872 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00873 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00874 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00875 static struct ast_frame *iax2_read(struct ast_channel *c);
00876 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00877 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00878 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00879 static void prune_peers(void);
00880 static void prune_users(void);
00881 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00882 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00883 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00884 static void build_rand_pad(unsigned char *buf, ssize_t len);
00885 
00886 static const struct ast_channel_tech iax2_tech = {
00887    .type = "IAX2",
00888    .description = tdesc,
00889    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00890    .properties = AST_CHAN_TP_WANTSJITTER,
00891    .requester = iax2_request,
00892    .devicestate = iax2_devicestate,
00893    .send_digit_begin = iax2_digit_begin,
00894    .send_digit_end = iax2_digit_end,
00895    .send_text = iax2_sendtext,
00896    .send_image = iax2_sendimage,
00897    .send_html = iax2_sendhtml,
00898    .call = iax2_call,
00899    .hangup = iax2_hangup,
00900    .answer = iax2_answer,
00901    .read = iax2_read,
00902    .write = iax2_write,
00903    .write_video = iax2_write,
00904    .indicate = iax2_indicate,
00905    .setoption = iax2_setoption,
00906    .bridge = iax2_bridge,
00907    .transfer = iax2_transfer,
00908    .fixup = iax2_fixup,
00909 };
00910 
00911 /* WARNING: insert_idle_thread should only ever be called within the
00912  * context of an iax2_process_thread() thread.
00913  */
00914 static void insert_idle_thread(struct iax2_thread *thread)
00915 {
00916    if (thread->type == IAX_TYPE_DYNAMIC) {
00917       AST_LIST_LOCK(&dynamic_list);
00918       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00919       AST_LIST_UNLOCK(&dynamic_list);
00920    } else {
00921       AST_LIST_LOCK(&idle_list);
00922       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00923       AST_LIST_UNLOCK(&idle_list);
00924    }
00925 
00926    return;
00927 }
00928 
00929 static struct iax2_thread *find_idle_thread(void)
00930 {
00931    pthread_attr_t attr;
00932    struct iax2_thread *thread = NULL;
00933 
00934    /* Pop the head of the list off */
00935    AST_LIST_LOCK(&idle_list);
00936    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00937    AST_LIST_UNLOCK(&idle_list);
00938 
00939    /* If no idle thread is available from the regular list, try dynamic */
00940    if (thread == NULL) {
00941       AST_LIST_LOCK(&dynamic_list);
00942       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00943       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00944       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00945          /* We need to MAKE a thread! */
00946          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00947             thread->threadnum = iaxdynamicthreadnum++;
00948             thread->type = IAX_TYPE_DYNAMIC;
00949             ast_mutex_init(&thread->lock);
00950             ast_cond_init(&thread->cond, NULL);
00951             pthread_attr_init(&attr);
00952             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00953             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00954                free(thread);
00955                thread = NULL;
00956             } else {
00957                /* All went well and the thread is up, so increment our count */
00958                iaxdynamicthreadcount++;
00959                
00960                /* Wait for the thread to be ready before returning it to the caller */
00961                while (!thread->ready_for_signal)
00962                   usleep(1);
00963             }
00964          }
00965       }
00966       AST_LIST_UNLOCK(&dynamic_list);
00967    }
00968 
00969    /* this thread is not processing a full frame (since it is idle),
00970       so ensure that the field for the full frame call number is empty */
00971    if (thread)
00972       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00973 
00974    return thread;
00975 }
00976 
00977 #ifdef SCHED_MULTITHREADED
00978 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00979 {
00980    struct iax2_thread *thread = NULL;
00981    static time_t lasterror;
00982    static time_t t;
00983 
00984    thread = find_idle_thread();
00985 
00986    if (thread != NULL) {
00987       thread->schedfunc = func;
00988       thread->scheddata = data;
00989       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00990 #ifdef DEBUG_SCHED_MULTITHREAD
00991       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00992 #endif
00993       signal_condition(&thread->lock, &thread->cond);
00994       return 0;
00995    }
00996    time(&t);
00997    if (t != lasterror && option_debug) 
00998       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00999    lasterror = t;
01000 
01001    return -1;
01002 }
01003 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01004 #endif
01005 
01006 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01007 {
01008    int res;
01009 
01010    ast_mutex_lock(&sched_lock);
01011    res = ast_sched_add(con, when, callback, data);
01012    ast_cond_signal(&sched_cond);
01013    ast_mutex_unlock(&sched_lock);
01014 
01015    return res;
01016 }
01017 
01018 static int send_ping(const void *data);
01019 
01020 static void __send_ping(const void *data)
01021 {
01022    int callno = (long) data;
01023 
01024    ast_mutex_lock(&iaxsl[callno]);
01025 
01026    if (iaxs[callno]) {
01027       if (iaxs[callno]->peercallno) {
01028          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01029          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01030       } else {
01031          /* I am the schedule, so I'm allowed to do this */
01032          iaxs[callno]->pingid = -1;
01033       }
01034    } else if (option_debug > 0) {
01035       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);
01036    }
01037 
01038    ast_mutex_unlock(&iaxsl[callno]);
01039 }
01040 
01041 static int send_ping(const void *data)
01042 {
01043 #ifdef SCHED_MULTITHREADED
01044    if (schedule_action(__send_ping, data))
01045 #endif      
01046       __send_ping(data);
01047 
01048    return 0;
01049 }
01050 
01051 static int get_encrypt_methods(const char *s)
01052 {
01053    int e;
01054    if (!strcasecmp(s, "aes128"))
01055       e = IAX_ENCRYPT_AES128;
01056    else if (ast_true(s))
01057       e = IAX_ENCRYPT_AES128;
01058    else
01059       e = 0;
01060    return e;
01061 }
01062 
01063 static int send_lagrq(const void *data);
01064 
01065 static void __send_lagrq(const void *data)
01066 {
01067    int callno = (long) data;
01068 
01069    ast_mutex_lock(&iaxsl[callno]);
01070 
01071    if (iaxs[callno]) {
01072       if (iaxs[callno]->peercallno) {
01073          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01074          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01075       } else {
01076          /* I am the schedule, so I'm allowed to do this */
01077          iaxs[callno]->lagid = -1;
01078       }
01079    } else {
01080       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);
01081    }
01082 
01083    ast_mutex_unlock(&iaxsl[callno]);
01084 }
01085 
01086 static int send_lagrq(const void *data)
01087 {
01088 #ifdef SCHED_MULTITHREADED
01089    if (schedule_action(__send_lagrq, data))
01090 #endif      
01091       __send_lagrq(data);
01092    
01093    return 0;
01094 }
01095 
01096 static unsigned char compress_subclass(int subclass)
01097 {
01098    int x;
01099    int power=-1;
01100    /* If it's 128 or smaller, just return it */
01101    if (subclass < IAX_FLAG_SC_LOG)
01102       return subclass;
01103    /* Otherwise find its power */
01104    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01105       if (subclass & (1 << x)) {
01106          if (power > -1) {
01107             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01108             return 0;
01109          } else
01110             power = x;
01111       }
01112    }
01113    return power | IAX_FLAG_SC_LOG;
01114 }
01115 
01116 static int uncompress_subclass(unsigned char csub)
01117 {
01118    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01119    if (csub & IAX_FLAG_SC_LOG) {
01120       /* special case for 'compressed' -1 */
01121       if (csub == 0xff)
01122          return -1;
01123       else
01124          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01125    }
01126    else
01127       return csub;
01128 }
01129 
01130 /*!
01131  * \note The only member of the peer passed here guaranteed to be set is the name field
01132  */
01133 static int peer_hash_cb(const void *obj, const int flags)
01134 {
01135    const struct iax2_peer *peer = obj;
01136 
01137    return ast_str_hash(peer->name);
01138 }
01139 
01140 /*!
01141  * \note The only member of the peer passed here guaranteed to be set is the name field
01142  */
01143 static int peer_cmp_cb(void *obj, void *arg, int flags)
01144 {
01145    struct iax2_peer *peer = obj, *peer2 = arg;
01146 
01147    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01148 }
01149 
01150 /*!
01151  * \note The only member of the user passed here guaranteed to be set is the name field
01152  */
01153 static int user_hash_cb(const void *obj, const int flags)
01154 {
01155    const struct iax2_user *user = obj;
01156 
01157    return ast_str_hash(user->name);
01158 }
01159 
01160 /*!
01161  * \note The only member of the user passed here guaranteed to be set is the name field
01162  */
01163 static int user_cmp_cb(void *obj, void *arg, int flags)
01164 {
01165    struct iax2_user *user = obj, *user2 = arg;
01166 
01167    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01168 }
01169 
01170 /*!
01171  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01172  *       so do not call it with a pvt lock held.
01173  */
01174 static struct iax2_peer *find_peer(const char *name, int realtime) 
01175 {
01176    struct iax2_peer *peer = NULL;
01177    struct iax2_peer tmp_peer = {
01178       .name = name,
01179    };
01180 
01181    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01182 
01183    /* Now go for realtime if applicable */
01184    if(!peer && realtime)
01185       peer = realtime_peer(name, NULL);
01186 
01187    return peer;
01188 }
01189 
01190 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01191 {
01192    ao2_ref(peer, +1);
01193    return peer;
01194 }
01195 
01196 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01197 {
01198    ao2_ref(peer, -1);
01199    return NULL;
01200 }
01201 
01202 static struct iax2_user *find_user(const char *name)
01203 {
01204    struct iax2_user tmp_user = {
01205       .name = name,
01206    };
01207 
01208    return ao2_find(users, &tmp_user, OBJ_POINTER);
01209 }
01210 
01211 static inline struct iax2_user *user_ref(struct iax2_user *user)
01212 {
01213    ao2_ref(user, +1);
01214    return user;
01215 }
01216 
01217 static inline struct iax2_user *user_unref(struct iax2_user *user)
01218 {
01219    ao2_ref(user, -1);
01220    return NULL;
01221 }
01222 
01223 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01224 {
01225    struct iax2_peer *peer = NULL;
01226    int res = 0;
01227    struct ao2_iterator i;
01228 
01229    i = ao2_iterator_init(peers, 0);
01230    while ((peer = ao2_iterator_next(&i))) {
01231       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01232           (peer->addr.sin_port == sin.sin_port)) {
01233          ast_copy_string(host, peer->name, len);
01234          peer_unref(peer);
01235          res = 1;
01236          break;
01237       }
01238       peer_unref(peer);
01239    }
01240 
01241    if (!peer) {
01242       peer = realtime_peer(NULL, &sin);
01243       if (peer) {
01244          ast_copy_string(host, peer->name, len);
01245          peer_unref(peer);
01246          res = 1;
01247       }
01248    }
01249 
01250    return res;
01251 }
01252 
01253 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01254 {
01255    /* Decrement AUTHREQ count if needed */
01256    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01257       struct iax2_user *user;
01258       struct iax2_user tmp_user = {
01259          .name = pvt->username,
01260       };
01261 
01262       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01263       if (user) {
01264          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01265          user = user_unref(user);       
01266       }
01267 
01268       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01269    }
01270 
01271    /* No more pings or lagrq's */
01272    AST_SCHED_DEL(sched, pvt->pingid);
01273    AST_SCHED_DEL(sched, pvt->lagid);
01274    AST_SCHED_DEL(sched, pvt->autoid);
01275    AST_SCHED_DEL(sched, pvt->authid);
01276    AST_SCHED_DEL(sched, pvt->initid);
01277    AST_SCHED_DEL(sched, pvt->jbid);
01278 }
01279 
01280 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01281 {
01282    if (!pvt->transfercallno) {
01283       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01284       return;
01285    }
01286 
01287    ao2_link(iax_transfercallno_pvts, pvt);
01288 }
01289 
01290 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01291 {
01292    if (!pvt->transfercallno) {
01293       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01294       return;
01295    }
01296 
01297    ao2_unlink(iax_transfercallno_pvts, pvt);
01298 }
01299 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01300 {
01301    if (!pvt->peercallno) {
01302       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01303       return;
01304    }
01305 
01306    ao2_link(iax_peercallno_pvts, pvt);
01307 }
01308 
01309 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01310 {
01311    if (!pvt->peercallno) {
01312       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01313       return;
01314    }
01315 
01316    ao2_unlink(iax_peercallno_pvts, pvt);
01317 }
01318 
01319 static void update_max_trunk(void)
01320 {
01321    int max = TRUNK_CALL_START;
01322    int x;
01323 
01324    /* XXX Prolly don't need locks here XXX */
01325    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01326       if (iaxs[x]) {
01327          max = x + 1;
01328       }
01329    }
01330 
01331    maxtrunkcall = max;
01332    if (option_debug && iaxdebug)
01333       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01334 }
01335 
01336 static void iax2_frame_free(struct iax_frame *fr)
01337 {
01338    AST_SCHED_DEL(sched, fr->retrans);
01339    iax_frame_free(fr);
01340 }
01341 
01342 static void iax2_destroy(int callno)
01343 {
01344    struct chan_iax2_pvt *pvt;
01345    struct ast_channel *owner;
01346 
01347 retry:
01348    pvt = iaxs[callno];
01349    gettimeofday(&lastused[callno], NULL);
01350    
01351    owner = pvt ? pvt->owner : NULL;
01352 
01353    if (owner) {
01354       if (ast_mutex_trylock(&owner->lock)) {
01355          if (option_debug > 2)
01356             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01357          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01358          goto retry;
01359       }
01360    }
01361 
01362    /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we
01363     * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee
01364     * the pvt stays around, a ref count is added to it. */
01365    if (!owner && pvt) {
01366       ao2_ref(pvt, +1);
01367       AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01368       AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01369       ao2_ref(pvt, -1);
01370       if (iaxs[callno]) {
01371          iaxs[callno] = NULL;
01372       } else {
01373          pvt = NULL;
01374       }
01375    }
01376 
01377    if (pvt) {
01378       if (!owner) {
01379          pvt->owner = NULL;
01380       } else {
01381          /* If there's an owner, prod it to give up */
01382          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01383           * because we already hold the owner channel lock. */
01384          ast_queue_hangup(owner);
01385       }
01386 
01387       if (pvt->peercallno) {
01388          remove_by_peercallno(pvt);
01389       }
01390 
01391       if (pvt->transfercallno) {
01392          remove_by_transfercallno(pvt);
01393       }
01394 
01395       if (!owner) {
01396          ao2_ref(pvt, -1);
01397          pvt = NULL;
01398       }
01399    }
01400 
01401    if (owner) {
01402       ast_mutex_unlock(&owner->lock);
01403    }
01404 
01405    if (callno & 0x4000) {
01406       update_max_trunk();
01407    }
01408 }
01409 
01410 static int scheduled_destroy(const void *vid)
01411 {
01412    short callno = PTR_TO_CALLNO(vid);
01413    ast_mutex_lock(&iaxsl[callno]);
01414    if (iaxs[callno]) {
01415       if (option_debug) {
01416          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01417       }
01418       iax2_destroy(callno);
01419    }
01420    ast_mutex_unlock(&iaxsl[callno]);
01421    return 0;
01422 }
01423 
01424 static void pvt_destructor(void *obj)
01425 {
01426    struct chan_iax2_pvt *pvt = obj;
01427    struct iax_frame *cur = NULL;
01428 
01429    iax2_destroy_helper(pvt);
01430 
01431    /* Already gone */
01432    ast_set_flag(pvt, IAX_ALREADYGONE); 
01433 
01434    AST_LIST_LOCK(&iaxq.queue);
01435    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01436       /* Cancel any pending transmissions */
01437       if (cur->callno == pvt->callno) { 
01438          cur->retries = -1;
01439       }
01440    }
01441    AST_LIST_UNLOCK(&iaxq.queue);
01442 
01443    if (pvt->reg) {
01444       pvt->reg->callno = 0;
01445    }
01446 
01447    if (!pvt->owner) {
01448       jb_frame frame;
01449       if (pvt->vars) {
01450           ast_variables_destroy(pvt->vars);
01451           pvt->vars = NULL;
01452       }
01453 
01454       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01455          iax2_frame_free(frame.data);
01456       }
01457 
01458       jb_destroy(pvt->jb);
01459       ast_string_field_free_memory(pvt);
01460    }
01461 }
01462 
01463 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01464 {
01465    struct chan_iax2_pvt *tmp;
01466    jb_conf jbconf;
01467 
01468    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01469       return NULL;
01470    }
01471 
01472    if (ast_string_field_init(tmp, 32)) {
01473       ao2_ref(tmp, -1);
01474       tmp = NULL;
01475       return NULL;
01476    }
01477       
01478    tmp->prefs = prefs;
01479    tmp->callno = 0;
01480    tmp->peercallno = 0;
01481    tmp->transfercallno = 0;
01482    tmp->bridgecallno = 0;
01483    tmp->pingid = -1;
01484    tmp->lagid = -1;
01485    tmp->autoid = -1;
01486    tmp->authid = -1;
01487    tmp->initid = -1;
01488 
01489    ast_string_field_set(tmp,exten, "s");
01490    ast_string_field_set(tmp,host, host);
01491 
01492    tmp->jb = jb_new();
01493    tmp->jbid = -1;
01494    jbconf.max_jitterbuf = maxjitterbuffer;
01495    jbconf.resync_threshold = resyncthreshold;
01496    jbconf.max_contig_interp = maxjitterinterps;
01497    jb_setconf(tmp->jb,&jbconf);
01498 
01499    return tmp;
01500 }
01501 
01502 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01503 {
01504    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01505    if (new) {
01506       size_t afdatalen = new->afdatalen;
01507       memcpy(new, fr, sizeof(*new));
01508       iax_frame_wrap(new, &fr->af);
01509       new->afdatalen = afdatalen;
01510       new->data = NULL;
01511       new->datalen = 0;
01512       new->direction = DIRECTION_INGRESS;
01513       new->retrans = -1;
01514    }
01515    return new;
01516 }
01517 
01518 #define NEW_PREVENT  0
01519 #define NEW_ALLOW    1
01520 #define NEW_FORCE    2
01521 
01522 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01523 {
01524    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01525       (cur->addr.sin_port == sin->sin_port)) {
01526       /* This is the main host */
01527       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01528           (check_dcallno ? dcallno == cur->callno : 1) ) {
01529          /* That's us.  Be sure we keep track of the peer call number */
01530          return 1;
01531       }
01532    }
01533    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01534        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01535       /* We're transferring */
01536       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01537          return 1;
01538    }
01539    return 0;
01540 }
01541 
01542 static void update_max_nontrunk(void)
01543 {
01544    int max = 1;
01545    int x;
01546    /* XXX Prolly don't need locks here XXX */
01547    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01548       if (iaxs[x])
01549          max = x + 1;
01550    }
01551    maxnontrunkcall = max;
01552    if (option_debug && iaxdebug)
01553       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01554 }
01555 
01556 static int make_trunk(unsigned short callno, int locked)
01557 {
01558    int x;
01559    int res= 0;
01560    struct timeval now;
01561    if (iaxs[callno]->oseqno) {
01562       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01563       return -1;
01564    }
01565    if (callno & TRUNK_CALL_START) {
01566       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01567       return -1;
01568    }
01569    gettimeofday(&now, NULL);
01570    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01571       ast_mutex_lock(&iaxsl[x]);
01572       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01573          /* Update the two timers that should have been started */
01574          /*!
01575           * \note We delete these before switching the slot, because if
01576           * they fire in the meantime, they will generate a warning.
01577           */
01578          AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01579          AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01580          iaxs[x] = iaxs[callno];
01581          iaxs[x]->callno = x;
01582          iaxs[callno] = NULL;
01583          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01584          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01585          if (locked)
01586             ast_mutex_unlock(&iaxsl[callno]);
01587          res = x;
01588          if (!locked)
01589             ast_mutex_unlock(&iaxsl[x]);
01590          break;
01591       }
01592       ast_mutex_unlock(&iaxsl[x]);
01593    }
01594    if (x >= ARRAY_LEN(iaxs) - 1) {
01595       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01596       return -1;
01597    }
01598    if (option_debug)
01599       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01600    /* We move this call from a non-trunked to a trunked call */
01601    update_max_trunk();
01602    update_max_nontrunk();
01603    return res;
01604 }
01605 
01606 /*!
01607  * \note Calling this function while holding another pvt lock can cause a deadlock.
01608  */
01609 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01610 {
01611    int res = 0;
01612    int x;
01613    struct timeval now;
01614    char host[80];
01615 
01616    if (new <= NEW_ALLOW) {
01617       if (callno) {
01618          struct chan_iax2_pvt *pvt;
01619          struct chan_iax2_pvt tmp_pvt = {
01620             .callno = dcallno,
01621             .peercallno = callno,
01622             .transfercallno = callno,
01623             /* hack!! */
01624             .frames_received = check_dcallno,
01625          };
01626 
01627          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01628          /* this works for finding normal call numbers not involving transfering */ 
01629          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01630             if (return_locked) {
01631                ast_mutex_lock(&iaxsl[pvt->callno]);
01632             }
01633             res = pvt->callno;
01634             ao2_ref(pvt, -1);
01635             pvt = NULL;
01636             return res;
01637          }
01638          /* this searches for transfer call numbers that might not get caught otherwise */
01639          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01640          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01641          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01642             if (return_locked) {
01643                ast_mutex_lock(&iaxsl[pvt->callno]);
01644             }
01645             res = pvt->callno;
01646             ao2_ref(pvt, -1);
01647             pvt = NULL;
01648             return res;
01649          }
01650       }
01651       /* This will occur on the first response to a message that we initiated,
01652        * such as a PING. */
01653       if (dcallno) {
01654          ast_mutex_lock(&iaxsl[dcallno]);
01655       }
01656       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01657          iaxs[dcallno]->peercallno = callno;
01658          res = dcallno;
01659          store_by_peercallno(iaxs[dcallno]);
01660          if (!res || !return_locked) {
01661             ast_mutex_unlock(&iaxsl[dcallno]);
01662          }
01663          return res;
01664       }
01665       if (dcallno) {
01666          ast_mutex_unlock(&iaxsl[dcallno]);
01667       }
01668 #ifdef IAX_OLD_FIND
01669       /* If we get here, we SHOULD NOT find a call structure for this
01670          callno; if we do, it means that there is a call structure that
01671          has a peer callno but did NOT get entered into the hash table,
01672          which is bad.
01673 
01674          If we find a call structure using this old, slow method, output a log
01675          message so we'll know about it. After a few months of leaving this in
01676          place, if we don't hear about people seeing these messages, we can
01677          remove this code for good.
01678       */
01679 
01680       for (x = 1; !res && x < maxnontrunkcall; x++) {
01681          ast_mutex_lock(&iaxsl[x]);
01682          if (iaxs[x]) {
01683             /* Look for an exact match */
01684             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01685                res = x;
01686             }
01687          }
01688          if (!res || !return_locked)
01689             ast_mutex_unlock(&iaxsl[x]);
01690       }
01691 
01692       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01693          ast_mutex_lock(&iaxsl[x]);
01694          if (iaxs[x]) {
01695             /* Look for an exact match */
01696             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01697                res = x;
01698             }
01699          }
01700          if (!res || !return_locked)
01701             ast_mutex_unlock(&iaxsl[x]);
01702       }
01703 
01704       if (res) {
01705          ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
01706       }
01707 #endif
01708    }
01709    if (!res && (new >= NEW_ALLOW)) {
01710       int start, found = 0;
01711 
01712       /* It may seem odd that we look through the peer list for a name for
01713        * this *incoming* call.  Well, it is weird.  However, users don't
01714        * have an IP address/port number that we can match against.  So,
01715        * this is just checking for a peer that has that IP/port and
01716        * assuming that we have a user of the same name.  This isn't always
01717        * correct, but it will be changed if needed after authentication. */
01718       if (!iax2_getpeername(*sin, host, sizeof(host)))
01719          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01720 
01721       now = ast_tvnow();
01722       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01723       for (x = start; 1; x++) {
01724          if (x == TRUNK_CALL_START) {
01725             x = 1;
01726             continue;
01727          }
01728 
01729          /* Find first unused call number that hasn't been used in a while */
01730          ast_mutex_lock(&iaxsl[x]);
01731          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01732             found = 1;
01733             break;
01734          }
01735          ast_mutex_unlock(&iaxsl[x]);
01736          
01737          if (x == start - 1) {
01738             break;
01739          }
01740       }
01741       /* We've still got lock held if we found a spot */
01742       if (x == start - 1 && !found) {
01743          ast_log(LOG_WARNING, "No more space\n");
01744          return 0;
01745       }
01746       iaxs[x] = new_iax(sin, host);
01747       update_max_nontrunk();
01748       if (iaxs[x]) {
01749          if (option_debug && iaxdebug)
01750             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01751          iaxs[x]->sockfd = sockfd;
01752          iaxs[x]->addr.sin_port = sin->sin_port;
01753          iaxs[x]->addr.sin_family = sin->sin_family;
01754          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01755          iaxs[x]->peercallno = callno;
01756          iaxs[x]->callno = x;
01757          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01758          iaxs[x]->expiry = min_reg_expire;
01759          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01760          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01761          iaxs[x]->amaflags = amaflags;
01762          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01763          
01764          ast_string_field_set(iaxs[x], accountcode, accountcode);
01765          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01766          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01767 
01768          if (iaxs[x]->peercallno) {
01769             store_by_peercallno(iaxs[x]);
01770          }
01771       } else {
01772          ast_log(LOG_WARNING, "Out of resources\n");
01773          ast_mutex_unlock(&iaxsl[x]);
01774          return 0;
01775       }
01776       if (!return_locked)
01777          ast_mutex_unlock(&iaxsl[x]);
01778       res = x;
01779    }
01780    return res;
01781 }
01782 
01783 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01784 
01785    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01786 }
01787 
01788 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01789 
01790    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01791 }
01792 
01793 /*!
01794  * \brief Queue a frame to a call's owning asterisk channel
01795  *
01796  * \pre This function assumes that iaxsl[callno] is locked when called.
01797  *
01798  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01799  * was valid before calling it, it may no longer be valid after calling it.
01800  * This function may unlock and lock the mutex associated with this callno,
01801  * meaning that another thread may grab it and destroy the call.
01802  */
01803 static int iax2_queue_frame(int callno, struct ast_frame *f)
01804 {
01805    for (;;) {
01806       if (iaxs[callno] && iaxs[callno]->owner) {
01807          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01808             /* Avoid deadlock by pausing and trying again */
01809             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01810          } else {
01811             ast_queue_frame(iaxs[callno]->owner, f);
01812             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01813             break;
01814          }
01815       } else
01816          break;
01817    }
01818    return 0;
01819 }
01820 
01821 /*!
01822  * \brief Queue a hangup frame on the ast_channel owner
01823  *
01824  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01825  * is active for the given call number.
01826  *
01827  * \pre Assumes lock for callno is already held.
01828  *
01829  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01830  * was valid before calling it, it may no longer be valid after calling it.
01831  * This function may unlock and lock the mutex associated with this callno,
01832  * meaning that another thread may grab it and destroy the call.
01833  */
01834 static int iax2_queue_hangup(int callno)
01835 {
01836    for (;;) {
01837       if (iaxs[callno] && iaxs[callno]->owner) {
01838          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01839             /* Avoid deadlock by pausing and trying again */
01840             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01841          } else {
01842             ast_queue_hangup(iaxs[callno]->owner);
01843             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01844             break;
01845          }
01846       } else
01847          break;
01848    }
01849    return 0;
01850 }
01851 
01852 /*!
01853  * \brief Queue a control frame on the ast_channel owner
01854  *
01855  * This function queues a control frame on the owner of the IAX2 pvt struct that
01856  * is active for the given call number.
01857  *
01858  * \pre Assumes lock for callno is already held.
01859  *
01860  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01861  * was valid before calling it, it may no longer be valid after calling it.
01862  * This function may unlock and lock the mutex associated with this callno,
01863  * meaning that another thread may grab it and destroy the call.
01864  */
01865 static int iax2_queue_control_data(int callno, 
01866    enum ast_control_frame_type control, const void *data, size_t datalen)
01867 {
01868    for (;;) {
01869       if (iaxs[callno] && iaxs[callno]->owner) {
01870          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01871             /* Avoid deadlock by pausing and trying again */
01872             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01873          } else {
01874             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01875             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01876             break;
01877          }
01878       } else
01879          break;
01880    }
01881    return 0;
01882 }
01883 static void destroy_firmware(struct iax_firmware *cur)
01884 {
01885    /* Close firmware */
01886    if (cur->fwh) {
01887       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01888    }
01889    close(cur->fd);
01890    free(cur);
01891 }
01892 
01893 static int try_firmware(char *s)
01894 {
01895    struct stat stbuf;
01896    struct iax_firmware *cur;
01897    int ifd;
01898    int fd;
01899    int res;
01900    
01901    struct ast_iax2_firmware_header *fwh, fwh2;
01902    struct MD5Context md5;
01903    unsigned char sum[16];
01904    unsigned char buf[1024];
01905    int len, chunk;
01906    char *s2;
01907    char *last;
01908    s2 = alloca(strlen(s) + 100);
01909    if (!s2) {
01910       ast_log(LOG_WARNING, "Alloca failed!\n");
01911       return -1;
01912    }
01913    last = strrchr(s, '/');
01914    if (last)
01915       last++;
01916    else
01917       last = s;
01918    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01919    res = stat(s, &stbuf);
01920    if (res < 0) {
01921       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01922       return -1;
01923    }
01924    /* Make sure it's not a directory */
01925    if (S_ISDIR(stbuf.st_mode))
01926       return -1;
01927    ifd = open(s, O_RDONLY);
01928    if (ifd < 0) {
01929       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01930       return -1;
01931    }
01932    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01933    if (fd < 0) {
01934       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01935       close(ifd);
01936       return -1;
01937    }
01938    /* Unlink our newly created file */
01939    unlink(s2);
01940    
01941    /* Now copy the firmware into it */
01942    len = stbuf.st_size;
01943    while(len) {
01944       chunk = len;
01945       if (chunk > sizeof(buf))
01946          chunk = sizeof(buf);
01947       res = read(ifd, buf, chunk);
01948       if (res != chunk) {
01949          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01950          close(ifd);
01951          close(fd);
01952          return -1;
01953       }
01954       res = write(fd, buf, chunk);
01955       if (res != chunk) {
01956          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01957          close(ifd);
01958          close(fd);
01959          return -1;
01960       }
01961       len -= chunk;
01962    }
01963    close(ifd);
01964    /* Return to the beginning */
01965    lseek(fd, 0, SEEK_SET);
01966    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01967       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01968       close(fd);
01969       return -1;
01970    }
01971    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01972       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01973       close(fd);
01974       return -1;
01975    }
01976    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01977       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01978       close(fd);
01979       return -1;
01980    }
01981    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01982       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01983       close(fd);
01984       return -1;
01985    }
01986    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01987    if (fwh == MAP_FAILED) {
01988       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01989       close(fd);
01990       return -1;
01991    }
01992    MD5Init(&md5);
01993    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01994    MD5Final(sum, &md5);
01995    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01996       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01997       munmap((void*)fwh, stbuf.st_size);
01998       close(fd);
01999       return -1;
02000    }
02001    cur = waresl.wares;
02002    while(cur) {
02003       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02004          /* Found a candidate */
02005          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02006             /* The version we have on loaded is older, load this one instead */
02007             break;
02008          /* This version is no newer than what we have.  Don't worry about it.
02009             We'll consider it a proper load anyhow though */
02010          munmap((void*)fwh, stbuf.st_size);
02011          close(fd);
02012          return 0;
02013       }
02014       cur = cur->next;
02015    }
02016    if (!cur) {
02017       /* Allocate a new one and link it */
02018       if ((cur = ast_calloc(1, sizeof(*cur)))) {
02019          cur->fd = -1;
02020          cur->next = waresl.wares;
02021          waresl.wares = cur;
02022       }
02023    }
02024    if (cur) {
02025       if (cur->fwh) {
02026          munmap((void*)cur->fwh, cur->mmaplen);
02027       }
02028       if (cur->fd > -1)
02029          close(cur->fd);
02030       cur->fwh = fwh;
02031       cur->fd = fd;
02032       cur->mmaplen = stbuf.st_size;
02033       cur->dead = 0;
02034    }
02035    return 0;
02036 }
02037 
02038 static int iax_check_version(char *dev)
02039 {
02040    int res = 0;
02041    struct iax_firmware *cur;
02042    if (!ast_strlen_zero(dev)) {
02043       ast_mutex_lock(&waresl.lock);
02044       cur = waresl.wares;
02045       while(cur) {
02046          if (!strcmp(dev, (char *)cur->fwh->devname)) {
02047             res = ntohs(cur->fwh->version);
02048             break;
02049          }
02050          cur = cur->next;
02051       }
02052       ast_mutex_unlock(&waresl.lock);
02053    }
02054    return res;
02055 }
02056 
02057 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02058 {
02059    int res = -1;
02060    unsigned int bs = desc & 0xff;
02061    unsigned int start = (desc >> 8) & 0xffffff;
02062    unsigned int bytes;
02063    struct iax_firmware *cur;
02064    if (!ast_strlen_zero((char *)dev) && bs) {
02065       start *= bs;
02066       ast_mutex_lock(&waresl.lock);
02067       cur = waresl.wares;
02068       while(cur) {
02069          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
02070             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02071             if (start < ntohl(cur->fwh->datalen)) {
02072                bytes = ntohl(cur->fwh->datalen) - start;
02073                if (bytes > bs)
02074                   bytes = bs;
02075                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02076             } else {
02077                bytes = 0;
02078                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02079             }
02080             if (bytes == bs)
02081                res = 0;
02082             else
02083                res = 1;
02084             break;
02085          }
02086          cur = cur->next;
02087       }
02088       ast_mutex_unlock(&waresl.lock);
02089    }
02090    return res;
02091 }
02092 
02093 
02094 static void reload_firmware(int unload)
02095 {
02096    struct iax_firmware *cur, *curl, *curp;
02097    DIR *fwd;
02098    struct dirent *de;
02099    char dir[256];
02100    char fn[256];
02101    /* Mark all as dead */
02102    ast_mutex_lock(&waresl.lock);
02103    cur = waresl.wares;
02104    while(cur) {
02105       cur->dead = 1;
02106       cur = cur->next;
02107    }
02108 
02109    /* Now that we've freed them, load the new ones */
02110    if (!unload) {
02111       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02112       fwd = opendir(dir);
02113       if (fwd) {
02114          while((de = readdir(fwd))) {
02115             if (de->d_name[0] != '.') {
02116                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02117                if (!try_firmware(fn)) {
02118                   if (option_verbose > 1)
02119                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02120                }
02121             }
02122          }
02123          closedir(fwd);
02124       } else 
02125          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02126    }
02127 
02128    /* Clean up leftovers */
02129    cur = waresl.wares;
02130    curp = NULL;
02131    while(cur) {
02132       curl = cur;
02133       cur = cur->next;
02134       if (curl->dead) {
02135          if (curp) {
02136             curp->next = cur;
02137          } else {
02138             waresl.wares = cur;
02139          }
02140          destroy_firmware(curl);
02141       } else {
02142          curp = cur;
02143       }
02144    }
02145    ast_mutex_unlock(&waresl.lock);
02146 }
02147 
02148 /*!
02149  * \note This function assumes that iaxsl[callno] is locked when called.
02150  *
02151  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02152  * was valid before calling it, it may no longer be valid after calling it.
02153  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02154  * associated with this callno, meaning that another thread may grab it and destroy the call.
02155  */
02156 static int __do_deliver(void *data)
02157 {
02158    /* Just deliver the packet by using queueing.  This is called by
02159      the IAX thread with the iaxsl lock held. */
02160    struct iax_frame *fr = data;
02161    fr->retrans = -1;
02162    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02163    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02164       iax2_queue_frame(fr->callno, &fr->af);
02165    /* Free our iax frame */
02166    iax2_frame_free(fr);
02167    /* And don't run again */
02168    return 0;
02169 }
02170 
02171 static int handle_error(void)
02172 {
02173    /* XXX Ideally we should figure out why an error occured and then abort those
02174       rather than continuing to try.  Unfortunately, the published interface does
02175       not seem to work XXX */
02176 #if 0
02177    struct sockaddr_in *sin;
02178    int res;
02179    struct msghdr m;
02180    struct sock_extended_err e;
02181    m.msg_name = NULL;
02182    m.msg_namelen = 0;
02183    m.msg_iov = NULL;
02184    m.msg_control = &e;
02185    m.msg_controllen = sizeof(e);
02186    m.msg_flags = 0;
02187    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02188    if (res < 0)
02189       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02190    else {
02191       if (m.msg_controllen) {
02192          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02193          if (sin) 
02194             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02195          else
02196             ast_log(LOG_WARNING, "No address detected??\n");
02197       } else {
02198          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02199       }
02200    }
02201 #endif
02202    return 0;
02203 }
02204 
02205 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02206 {
02207    int res;
02208    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02209                sizeof(*sin));
02210    if (res < 0) {
02211       if (option_debug)
02212          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02213       handle_error();
02214    } else
02215       res = 0;
02216    return res;
02217 }
02218 
02219 static int send_packet(struct iax_frame *f)
02220 {
02221    int res;
02222    int callno = f->callno;
02223 
02224    /* Don't send if there was an error, but return error instead */
02225    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02226        return -1;
02227    
02228    /* Called with iaxsl held */
02229    if (option_debug > 2 && iaxdebug)
02230       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));
02231    if (f->transfer) {
02232       if (iaxdebug)
02233          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02234       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02235                sizeof(iaxs[callno]->transfer));
02236    } else {
02237       if (iaxdebug)
02238          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02239       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02240                sizeof(iaxs[callno]->addr));
02241    }
02242    if (res < 0) {
02243       if (option_debug && iaxdebug)
02244          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02245       handle_error();
02246    } else
02247       res = 0;
02248    return res;
02249 }
02250 
02251 /*!
02252  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02253  *       for the given call number may disappear during its execution.
02254  */
02255 static int iax2_predestroy(int callno)
02256 {
02257    struct ast_channel *c;
02258    struct chan_iax2_pvt *pvt = iaxs[callno];
02259 
02260    if (!pvt)
02261       return -1;
02262    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02263       iax2_destroy_helper(pvt);
02264       ast_set_flag(pvt, IAX_ALREADYGONE); 
02265    }
02266    c = pvt->owner;
02267    if (c) {
02268       c->tech_pvt = NULL;
02269       iax2_queue_hangup(callno);
02270       pvt->owner = NULL;
02271       ast_module_unref(ast_module_info->self);
02272    }
02273    return 0;
02274 }
02275 
02276 static int update_packet(struct iax_frame *f)
02277 {
02278    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02279    struct ast_iax2_full_hdr *fh = f->data;
02280    struct ast_frame af;
02281 
02282    /* if frame is encrypted. decrypt before updating it. */
02283    if (f->encmethods) {
02284       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02285    }
02286    /* Mark this as a retransmission */
02287    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02288    /* Update iseqno */
02289    f->iseqno = iaxs[f->callno]->iseqno;
02290    fh->iseqno = f->iseqno;
02291 
02292    /* Now re-encrypt the frame */
02293    if (f->encmethods) {
02294    /* since this is a retransmit frame, create a new random padding
02295     * before re-encrypting. */
02296       build_rand_pad(f->semirand, sizeof(f->semirand));
02297       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02298    }
02299    return 0;
02300 }
02301 
02302 static int attempt_transmit(const void *data);
02303 static void __attempt_transmit(const void *data)
02304 {
02305    /* Attempt to transmit the frame to the remote peer...
02306       Called without iaxsl held. */
02307    struct iax_frame *f = (struct iax_frame *)data;
02308    int freeme=0;
02309    int callno = f->callno;
02310    /* Make sure this call is still active */
02311    if (callno) 
02312       ast_mutex_lock(&iaxsl[callno]);
02313    if (callno && iaxs[callno]) {
02314       if ((f->retries < 0) /* Already ACK'd */ ||
02315           (f->retries >= max_retries) /* Too many attempts */) {
02316             /* Record an error if we've transmitted too many times */
02317             if (f->retries >= max_retries) {
02318                if (f->transfer) {
02319                   /* Transfer timeout */
02320                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02321                } else if (f->final) {
02322                   if (f->final) 
02323                      iax2_destroy(callno);
02324                } else {
02325                   if (iaxs[callno]->owner)
02326                      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);
02327                   iaxs[callno]->error = ETIMEDOUT;
02328                   if (iaxs[callno]->owner) {
02329                      struct ast_frame fr = { 0, };
02330                      /* Hangup the fd */
02331                      fr.frametype = AST_FRAME_CONTROL;
02332                      fr.subclass = AST_CONTROL_HANGUP;
02333                      iax2_queue_frame(callno, &fr); // XXX
02334                      /* Remember, owner could disappear */
02335                      if (iaxs[callno] && iaxs[callno]->owner)
02336                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02337                   } else {
02338                      if (iaxs[callno]->reg) {
02339                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02340                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02341                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02342                      }
02343                      iax2_destroy(callno);
02344                   }
02345                }
02346 
02347             }
02348             freeme++;
02349       } else {
02350          /* Update it if it needs it */
02351          update_packet(f);
02352          /* Attempt transmission */
02353          send_packet(f);
02354          f->retries++;
02355          /* Try again later after 10 times as long */
02356          f->retrytime *= 10;
02357          if (f->retrytime > MAX_RETRY_TIME)
02358             f->retrytime = MAX_RETRY_TIME;
02359          /* Transfer messages max out at one second */
02360          if (f->transfer && (f->retrytime > 1000))
02361             f->retrytime = 1000;
02362          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02363       }
02364    } else {
02365       /* Make sure it gets freed */
02366       f->retries = -1;
02367       freeme++;
02368    }
02369    if (callno)
02370       ast_mutex_unlock(&iaxsl[callno]);
02371    /* Do not try again */
02372    if (freeme) {
02373       /* Don't attempt delivery, just remove it from the queue */
02374       AST_LIST_LOCK(&iaxq.queue);
02375       AST_LIST_REMOVE(&iaxq.queue, f, list);
02376       iaxq.count--;
02377       AST_LIST_UNLOCK(&iaxq.queue);
02378       f->retrans = -1;
02379       /* Free the IAX frame */
02380       iax2_frame_free(f);
02381    }
02382 }
02383 
02384 static int attempt_transmit(const void *data)
02385 {
02386 #ifdef SCHED_MULTITHREADED
02387    if (schedule_action(__attempt_transmit, data))
02388 #endif      
02389       __attempt_transmit(data);
02390    return 0;
02391 }
02392 
02393 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02394 {
02395    struct iax2_peer *peer = NULL;
02396    struct iax2_user *user = NULL;
02397 
02398    if (argc != 4)
02399         return RESULT_SHOWUSAGE;
02400    if (!strcmp(argv[3],"all")) {
02401       prune_users();
02402       prune_peers();
02403       ast_cli(fd, "OK cache is flushed.\n");
02404       return RESULT_SUCCESS;
02405    }
02406    peer = find_peer(argv[3], 0);
02407    user = find_user(argv[3]);
02408    if (peer || user) {
02409       if (peer) {
02410          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02411             ast_set_flag(peer, IAX_RTAUTOCLEAR);
02412             expire_registry(peer_ref(peer));
02413             ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
02414          } else {
02415             ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
02416          }
02417          peer_unref(peer);
02418       }
02419       if (user) {
02420          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02421             ast_set_flag(user, IAX_RTAUTOCLEAR);
02422             ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
02423          } else {
02424             ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
02425          }
02426          ao2_unlink(users,user);
02427          user_unref(user);
02428       }
02429    } else {
02430       ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
02431    }
02432 
02433    return RESULT_SUCCESS;
02434 }
02435 
02436 static int iax2_test_losspct(int fd, int argc, char *argv[])
02437 {
02438        if (argc != 4)
02439                return RESULT_SHOWUSAGE;
02440 
02441        test_losspct = atoi(argv[3]);
02442 
02443        return RESULT_SUCCESS;
02444 }
02445 
02446 #ifdef IAXTESTS
02447 static int iax2_test_late(int fd, int argc, char *argv[])
02448 {
02449    if (argc != 4)
02450       return RESULT_SHOWUSAGE;
02451 
02452    test_late = atoi(argv[3]);
02453 
02454    return RESULT_SUCCESS;
02455 }
02456 
02457 static int iax2_test_resync(int fd, int argc, char *argv[])
02458 {
02459    if (argc != 4)
02460       return RESULT_SHOWUSAGE;
02461 
02462    test_resync = atoi(argv[3]);
02463 
02464    return RESULT_SUCCESS;
02465 }
02466 
02467 static int iax2_test_jitter(int fd, int argc, char *argv[])
02468 {
02469    if (argc < 4 || argc > 5)
02470       return RESULT_SHOWUSAGE;
02471 
02472    test_jit = atoi(argv[3]);
02473    if (argc == 5) 
02474       test_jitpct = atoi(argv[4]);
02475 
02476    return RESULT_SUCCESS;
02477 }
02478 #endif /* IAXTESTS */
02479 
02480 /*! \brief  peer_status: Report Peer status in character string */
02481 /*    returns 1 if peer is online, -1 if unmonitored */
02482 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02483 {
02484    int res = 0;
02485    if (peer->maxms) {
02486       if (peer->lastms < 0) {
02487          ast_copy_string(status, "UNREACHABLE", statuslen);
02488       } else if (peer->lastms > peer->maxms) {
02489          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02490          res = 1;
02491       } else if (peer->lastms) {
02492          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02493          res = 1;
02494       } else {
02495          ast_copy_string(status, "UNKNOWN", statuslen);
02496       }
02497    } else { 
02498       ast_copy_string(status, "Unmonitored", statuslen);
02499       res = -1;
02500    }
02501    return res;
02502 }
02503 
02504 /*! \brief Show one peer in detail */
02505 static int iax2_show_peer(int fd, int argc, char *argv[])
02506 {
02507    char status[30];
02508    char cbuf[256];
02509    struct iax2_peer *peer;
02510    char codec_buf[512];
02511    int x = 0, codec = 0, load_realtime = 0;
02512 
02513    if (argc < 4)
02514       return RESULT_SHOWUSAGE;
02515 
02516    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02517 
02518    peer = find_peer(argv[3], load_realtime);
02519    if (peer) {
02520       ast_cli(fd,"\n\n");
02521       ast_cli(fd, "  * Name       : %s\n", peer->name);
02522       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02523       ast_cli(fd, "  Context      : %s\n", peer->context);
02524       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02525       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02526       ast_cli(fd, "  Trunk        : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
02527       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02528       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02529       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02530       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));
02531       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02532       ast_cli(fd, "  Username     : %s\n", peer->username);
02533       ast_cli(fd, "  Codecs       : ");
02534       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02535       ast_cli(fd, "%s\n", codec_buf);
02536 
02537       ast_cli(fd, "  Codec Order  : (");
02538       for(x = 0; x < 32 ; x++) {
02539          codec = ast_codec_pref_index(&peer->prefs,x);
02540          if(!codec)
02541             break;
02542          ast_cli(fd, "%s", ast_getformatname(codec));
02543          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02544             ast_cli(fd, "|");
02545       }
02546 
02547       if (!x)
02548          ast_cli(fd, "none");
02549       ast_cli(fd, ")\n");
02550 
02551       ast_cli(fd, "  Status       : ");
02552       peer_status(peer, status, sizeof(status));   
02553       ast_cli(fd, "%s\n",status);
02554       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02555       ast_cli(fd,"\n");
02556       peer_unref(peer);
02557    } else {
02558       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02559       ast_cli(fd,"\n");
02560    }
02561 
02562    return RESULT_SUCCESS;
02563 }
02564 
02565 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02566 {
02567    int which = 0;
02568    struct iax2_peer *peer;
02569    char *res = NULL;
02570    int wordlen = strlen(word);
02571    struct ao2_iterator i;
02572 
02573    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02574    if (pos != 3)
02575       return NULL;
02576 
02577    i = ao2_iterator_init(peers, 0);
02578    while ((peer = ao2_iterator_next(&i))) {
02579       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02580          res = ast_strdup(peer->name);
02581          peer_unref(peer);
02582          break;
02583       }
02584       peer_unref(peer);
02585    }
02586 
02587    return res;
02588 }
02589 
02590 static int iax2_show_stats(int fd, int argc, char *argv[])
02591 {
02592    struct iax_frame *cur;
02593    int cnt = 0, dead=0, final=0;
02594 
02595    if (argc != 3)
02596       return RESULT_SHOWUSAGE;
02597 
02598    AST_LIST_LOCK(&iaxq.queue);
02599    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02600       if (cur->retries < 0)
02601          dead++;
02602       if (cur->final)
02603          final++;
02604       cnt++;
02605    }
02606    AST_LIST_UNLOCK(&iaxq.queue);
02607 
02608    ast_cli(fd, "    IAX Statistics\n");
02609    ast_cli(fd, "---------------------\n");
02610    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02611    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02612    
02613    return RESULT_SUCCESS;
02614 }
02615 
02616 static int iax2_show_cache(int fd, int argc, char *argv[])
02617 {
02618    struct iax2_dpcache *dp;
02619    char tmp[1024], *pc;
02620    int s;
02621    int x,y;
02622    struct timeval tv;
02623    gettimeofday(&tv, NULL);
02624    ast_mutex_lock(&dpcache_lock);
02625    dp = dpcache;
02626    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02627    while(dp) {
02628       s = dp->expiry.tv_sec - tv.tv_sec;
02629       tmp[0] = '\0';
02630       if (dp->flags & CACHE_FLAG_EXISTS)
02631          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02632       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02633          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02634       if (dp->flags & CACHE_FLAG_CANEXIST)
02635          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02636       if (dp->flags & CACHE_FLAG_PENDING)
02637          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02638       if (dp->flags & CACHE_FLAG_TIMEOUT)
02639          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02640       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02641          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02642       if (dp->flags & CACHE_FLAG_MATCHMORE)
02643          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02644       if (dp->flags & CACHE_FLAG_UNKNOWN)
02645          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02646       /* Trim trailing pipe */
02647       if (!ast_strlen_zero(tmp))
02648          tmp[strlen(tmp) - 1] = '\0';
02649       else
02650          ast_copy_string(tmp, "(none)", sizeof(tmp));
02651       y=0;
02652       pc = strchr(dp->peercontext, '@');
02653       if (!pc)
02654          pc = dp->peercontext;
02655       else
02656          pc++;
02657       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02658          if (dp->waiters[x] > -1)
02659             y++;
02660       if (s > 0)
02661          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02662       else
02663          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02664       dp = dp->next;
02665    }
02666    ast_mutex_unlock(&dpcache_lock);
02667    return RESULT_SUCCESS;
02668 }
02669 
02670 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02671 
02672 static void unwrap_timestamp(struct iax_frame *fr)
02673 {
02674    /* Video mini frames only encode the lower 15 bits of the session
02675     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
02676    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02677    const int lower_mask = (1 << ts_shift) - 1;
02678    const int upper_mask = ~lower_mask;
02679    const int last_upper = iaxs[fr->callno]->last & upper_mask;
02680 
02681    if ( (fr->ts & upper_mask) == last_upper ) {
02682       const int x = fr->ts - iaxs[fr->callno]->last;
02683       const int threshold = (ts_shift == 15) ? 25000 : 50000;
02684 
02685       if (x < -threshold) {
02686          /* Sudden big jump backwards in timestamp:
02687             What likely happened here is that miniframe timestamp has circled but we haven't
02688             gotten the update from the main packet.  We'll just pretend that we did, and
02689             update the timestamp appropriately. */
02690          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02691          if (option_debug && iaxdebug)
02692             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02693       } else if (x > threshold) {
02694          /* Sudden apparent big jump forwards in timestamp:
02695             What's likely happened is this is an old miniframe belonging to the previous
02696             top 15 or 16-bit timestamp that has turned up out of order.
02697             Adjust the timestamp appropriately. */
02698          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02699          if (option_debug && iaxdebug)
02700             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02701       }
02702    }
02703 }
02704 
02705 static int get_from_jb(const void *p);
02706 
02707 static void update_jbsched(struct chan_iax2_pvt *pvt)
02708 {
02709    int when;
02710    
02711    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02712    
02713    when = jb_next(pvt->jb) - when;
02714 
02715    AST_SCHED_DEL(sched, pvt->jbid);
02716 
02717    if(when <= 0) {
02718       /* XXX should really just empty until when > 0.. */
02719       when = 1;
02720    }
02721    
02722    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02723 }
02724 
02725 static void __get_from_jb(const void *p) 
02726 {
02727    int callno = PTR_TO_CALLNO(p);
02728    struct chan_iax2_pvt *pvt = NULL;
02729    struct iax_frame *fr;
02730    jb_frame frame;
02731    int ret;
02732    long now;
02733    long next;
02734    struct timeval tv;
02735    
02736    /* Make sure we have a valid private structure before going on */
02737    ast_mutex_lock(&iaxsl[callno]);
02738    pvt = iaxs[callno];
02739    if (!pvt) {
02740       /* No go! */
02741       ast_mutex_unlock(&iaxsl[callno]);
02742       return;
02743    }
02744 
02745    pvt->jbid = -1;
02746    
02747    gettimeofday(&tv,NULL);
02748    /* round up a millisecond since ast_sched_runq does; */
02749    /* prevents us from spinning while waiting for our now */
02750    /* to catch up with runq's now */
02751    tv.tv_usec += 1000;
02752    
02753    now = ast_tvdiff_ms(tv, pvt->rxcore);
02754    
02755    if(now >= (next = jb_next(pvt->jb))) {
02756       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02757       switch(ret) {
02758       case JB_OK:
02759          fr = frame.data;
02760          __do_deliver(fr);
02761          /* __do_deliver() can cause the call to disappear */
02762          pvt = iaxs[callno];
02763          break;
02764       case JB_INTERP:
02765       {
02766          struct ast_frame af = { 0, };
02767          
02768          /* create an interpolation frame */
02769          af.frametype = AST_FRAME_VOICE;
02770          af.subclass = pvt->voiceformat;
02771          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
02772          af.src  = "IAX2 JB interpolation";
02773          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02774          af.offset = AST_FRIENDLY_OFFSET;
02775          
02776          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02777           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02778          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02779             iax2_queue_frame(callno, &af);
02780             /* iax2_queue_frame() could cause the call to disappear */
02781             pvt = iaxs[callno];
02782          }
02783       }
02784          break;
02785       case JB_DROP:
02786          iax2_frame_free(frame.data);
02787          break;
02788       case JB_NOFRAME:
02789       case JB_EMPTY:
02790          /* do nothing */
02791          break;
02792       default:
02793          /* shouldn't happen */
02794          break;
02795       }
02796    }
02797    if (pvt)
02798       update_jbsched(pvt);
02799    ast_mutex_unlock(&iaxsl[callno]);
02800 }
02801 
02802 static int get_from_jb(const void *data)
02803 {
02804 #ifdef SCHED_MULTITHREADED
02805    if (schedule_action(__get_from_jb, data))
02806 #endif      
02807       __get_from_jb(data);
02808    return 0;
02809 }
02810 
02811 /*!
02812  * \note This function assumes fr->callno is locked
02813  *
02814  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02815  * was valid before calling it, it may no longer be valid after calling it.
02816  */
02817 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02818 {
02819    int type, len;
02820    int ret;
02821    int needfree = 0;
02822    struct ast_channel *owner = NULL;
02823    struct ast_channel *bridge = NULL;
02824    
02825    /* Attempt to recover wrapped timestamps */
02826    unwrap_timestamp(fr);
02827 
02828    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02829    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02830       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02831    else {
02832 #if 0
02833       if (option_debug)
02834          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02835 #endif
02836       fr->af.delivery = ast_tv(0,0);
02837    }
02838 
02839    type = JB_TYPE_CONTROL;
02840    len = 0;
02841 
02842    if(fr->af.frametype == AST_FRAME_VOICE) {
02843       type = JB_TYPE_VOICE;
02844       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
02845    } else if(fr->af.frametype == AST_FRAME_CNG) {
02846       type = JB_TYPE_SILENCE;
02847    }
02848 
02849    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02850       if (tsout)
02851          *tsout = fr->ts;
02852       __do_deliver(fr);
02853       return -1;
02854    }
02855 
02856    if ((owner = iaxs[fr->callno]->owner))
02857       bridge = ast_bridged_channel(owner);
02858 
02859    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02860     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02861    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02862       jb_frame frame;
02863 
02864       /* deliver any frames in the jb */
02865       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02866          __do_deliver(frame.data);
02867          /* __do_deliver() can make the call disappear */
02868          if (!iaxs[fr->callno])
02869             return -1;
02870       }
02871 
02872       jb_reset(iaxs[fr->callno]->jb);
02873 
02874       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02875 
02876       /* deliver this frame now */
02877       if (tsout)
02878          *tsout = fr->ts;
02879       __do_deliver(fr);
02880       return -1;
02881    }
02882 
02883    /* insert into jitterbuffer */
02884    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02885    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02886          calc_rxstamp(iaxs[fr->callno],fr->ts));
02887    if (ret == JB_DROP) {
02888       needfree++;
02889    } else if (ret == JB_SCHED) {
02890       update_jbsched(iaxs[fr->callno]);
02891    }
02892    if (tsout)
02893       *tsout = fr->ts;
02894    if (needfree) {
02895       /* Free our iax frame */
02896       iax2_frame_free(fr);
02897       return -1;
02898    }
02899    return 0;
02900 }
02901 
02902 static int iax2_transmit(struct iax_frame *fr)
02903 {
02904    /* Lock the queue and place this packet at the end */
02905    /* By setting this to 0, the network thread will send it for us, and
02906       queue retransmission if necessary */
02907    fr->sentyet = 0;
02908    AST_LIST_LOCK(&iaxq.queue);
02909    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02910    iaxq.count++;
02911    AST_LIST_UNLOCK(&iaxq.queue);
02912    /* Wake up the network and scheduler thread */
02913    if (netthreadid != AST_PTHREADT_NULL)
02914       pthread_kill(netthreadid, SIGURG);
02915    signal_condition(&sched_lock, &sched_cond);
02916    return 0;
02917 }
02918 
02919 
02920 
02921 static int iax2_digit_begin(struct ast_channel *c, char digit)
02922 {
02923    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02924 }
02925 
02926 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02927 {
02928    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02929 }
02930 
02931 static int iax2_sendtext(struct ast_channel *c, const char *text)
02932 {
02933    
02934    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02935       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02936 }
02937 
02938 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02939 {
02940    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02941 }
02942 
02943 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02944 {
02945    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02946 }
02947 
02948 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02949 {
02950    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02951    ast_mutex_lock(&iaxsl[callno]);
02952    if (iaxs[callno])
02953       iaxs[callno]->owner = newchan;
02954    else
02955       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02956    ast_mutex_unlock(&iaxsl[callno]);
02957    return 0;
02958 }
02959 
02960 /*!
02961  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02962  *       so do not call this with a pvt lock held.
02963  */
02964 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02965 {
02966    struct ast_variable *var = NULL;
02967    struct ast_variable *tmp;
02968    struct iax2_peer *peer=NULL;
02969    time_t regseconds = 0, nowtime;
02970    int dynamic=0;
02971 
02972    if (peername) {
02973       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02974       if (!var && sin)
02975          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02976    } else if (sin) {
02977       char porta[25];
02978       sprintf(porta, "%d", ntohs(sin->sin_port));
02979       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02980       if (var) {
02981          /* We'll need the peer name in order to build the structure! */
02982          for (tmp = var; tmp; tmp = tmp->next) {
02983             if (!strcasecmp(tmp->name, "name"))
02984                peername = tmp->value;
02985          }
02986       }
02987    }
02988    if (!var && peername) { /* Last ditch effort */
02989       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02990       /*!\note
02991        * If this one loaded something, then we need to ensure that the host
02992        * field matched.  The only reason why we can't have this as a criteria
02993        * is because we only have the IP address and the host field might be
02994        * set as a name (and the reverse PTR might not match).
02995        */
02996       if (var && sin) {
02997          for (tmp = var; tmp; tmp = tmp->next) {
02998             if (!strcasecmp(tmp->name, "host")) {
02999                struct ast_hostent ahp;
03000                struct hostent *hp;
03001                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03002                   /* No match */
03003                   ast_variables_destroy(var);
03004                   var = NULL;
03005                }
03006                break;
03007             }
03008          }
03009       }
03010    }
03011    if (!var)
03012       return NULL;
03013 
03014    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03015    
03016    if (!peer) {
03017       ast_variables_destroy(var);
03018       return NULL;
03019    }
03020 
03021    for (tmp = var; tmp; tmp = tmp->next) {
03022       /* Make sure it's not a user only... */
03023       if (!strcasecmp(tmp->name, "type")) {
03024          if (strcasecmp(tmp->value, "friend") &&
03025              strcasecmp(tmp->value, "peer")) {
03026             /* Whoops, we weren't supposed to exist! */
03027             peer = peer_unref(peer);
03028             break;
03029          } 
03030       } else if (!strcasecmp(tmp->name, "regseconds")) {
03031          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
03032       } else if (!strcasecmp(tmp->name, "ipaddr")) {
03033          inet_aton(tmp->value, &(peer->addr.sin_addr));
03034       } else if (!strcasecmp(tmp->name, "port")) {
03035          peer->addr.sin_port = htons(atoi(tmp->value));
03036       } else if (!strcasecmp(tmp->name, "host")) {
03037          if (!strcasecmp(tmp->value, "dynamic"))
03038             dynamic = 1;
03039       }
03040    }
03041 
03042    ast_variables_destroy(var);
03043 
03044    if (!peer)
03045       return NULL;
03046 
03047    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03048       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03049       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03050          if (peer->expire > -1) {
03051             if (!ast_sched_del(sched, peer->expire)) {
03052                peer->expire = -1;
03053                peer_unref(peer);
03054             }
03055          }
03056          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03057          if (peer->expire == -1)
03058             peer_unref(peer);
03059       }
03060       ao2_link(peers, peer);
03061       if (ast_test_flag(peer, IAX_DYNAMIC))
03062          reg_source_db(peer);
03063    } else {
03064       ast_set_flag(peer, IAX_TEMPONLY);   
03065    }
03066 
03067    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03068       time(&nowtime);
03069       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03070          memset(&peer->addr, 0, sizeof(peer->addr));
03071          realtime_update_peer(peer->name, &peer->addr, 0);
03072          if (option_debug)
03073             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03074                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03075       }
03076       else {
03077          if (option_debug)
03078             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03079                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03080       }
03081    }
03082 
03083    return peer;
03084 }
03085 
03086 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03087 {
03088    struct ast_variable *var;
03089    struct ast_variable *tmp;
03090    struct iax2_user *user=NULL;
03091 
03092    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03093    if (!var)
03094       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03095    if (!var && sin) {
03096       char porta[6];
03097       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03098       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03099       if (!var)
03100          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03101    }
03102    if (!var) { /* Last ditch effort */
03103       var = ast_load_realtime("iaxusers", "name", username, NULL);
03104       /*!\note
03105        * If this one loaded something, then we need to ensure that the host
03106        * field matched.  The only reason why we can't have this as a criteria
03107        * is because we only have the IP address and the host field might be
03108        * set as a name (and the reverse PTR might not match).
03109        */
03110       if (var) {
03111          for (tmp = var; tmp; tmp = tmp->next) {
03112             if (!strcasecmp(tmp->name, "host")) {
03113                struct ast_hostent ahp;
03114                struct hostent *hp;
03115                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03116                   /* No match */
03117                   ast_variables_destroy(var);
03118                   var = NULL;
03119                }
03120                break;
03121             }
03122          }
03123       }
03124    }
03125    if (!var)
03126       return NULL;
03127 
03128    tmp = var;
03129    while(tmp) {
03130       /* Make sure it's not a peer only... */
03131       if (!strcasecmp(tmp->name, "type")) {
03132          if (strcasecmp(tmp->value, "friend") &&
03133              strcasecmp(tmp->value, "user")) {
03134             return NULL;
03135          } 
03136       }
03137       tmp = tmp->next;
03138    }
03139 
03140    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03141 
03142    ast_variables_destroy(var);
03143 
03144    if (!user)
03145       return NULL;
03146 
03147    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03148       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03149       ao2_link(users, user);
03150    } else {
03151       ast_set_flag(user, IAX_TEMPONLY);   
03152    }
03153 
03154    return user;
03155 }
03156 
03157 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03158 {
03159    char port[10];
03160    char regseconds[20];
03161    
03162    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03163    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03164    ast_update_realtime("iaxpeers", "name", peername, 
03165       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03166       "regseconds", regseconds, NULL);
03167 }
03168 
03169 struct create_addr_info {
03170    int capability;
03171    unsigned int flags;
03172    int maxtime;
03173    int encmethods;
03174    int found;
03175    int sockfd;
03176    int adsi;
03177    char username[80];
03178    char secret[80];
03179    char outkey[80];
03180    char timezone[80];
03181    char prefs[32];
03182    char context[AST_MAX_CONTEXT];
03183    char peercontext[AST_MAX_CONTEXT];
03184    char mohinterpret[MAX_MUSICCLASS];
03185    char mohsuggest[MAX_MUSICCLASS];
03186 };
03187 
03188 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03189 {
03190    struct ast_hostent ahp;
03191    struct hostent *hp;
03192    struct iax2_peer *peer;
03193    int res = -1;
03194    struct ast_codec_pref ourprefs;
03195 
03196    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03197    cai->sockfd = defaultsockfd;
03198    cai->maxtime = 0;
03199    sin->sin_family = AF_INET;
03200 
03201    if (!(peer = find_peer(peername, 1))) {
03202       cai->found = 0;
03203 
03204       hp = ast_gethostbyname(peername, &ahp);
03205       if (hp) {
03206          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03207          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03208          /* use global iax prefs for unknown peer/user */
03209          /* But move the calling channel's native codec to the top of the preference list */
03210          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03211          if (c)
03212             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03213          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03214          return 0;
03215       } else {
03216          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03217          return -1;
03218       }
03219    }
03220 
03221    cai->found = 1;
03222    
03223    /* if the peer has no address (current or default), return failure */
03224    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03225       goto return_unref;
03226 
03227    /* if the peer is being monitored and is currently unreachable, return failure */
03228    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03229       goto return_unref;
03230 
03231    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03232    cai->maxtime = peer->maxms;
03233    cai->capability = peer->capability;
03234    cai->encmethods = peer->encmethods;
03235    cai->sockfd = peer->sockfd;
03236    cai->adsi = peer->adsi;
03237    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03238    /* Move the calling channel's native codec to the top of the preference list */
03239    if (c) {
03240       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03241       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03242    }
03243    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03244    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03245    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03246    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03247    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03248    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03249    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03250    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03251    if (ast_strlen_zero(peer->dbsecret)) {
03252       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03253    } else {
03254       char *family;
03255       char *key = NULL;
03256 
03257       family = ast_strdupa(peer->dbsecret);
03258       key = strchr(family, '/');
03259       if (key)
03260          *key++ = '\0';
03261       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03262          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03263          goto return_unref;
03264       }
03265    }
03266 
03267    if (peer->addr.sin_addr.s_addr) {
03268       sin->sin_addr = peer->addr.sin_addr;
03269       sin->sin_port = peer->addr.sin_port;
03270    } else {
03271       sin->sin_addr = peer->defaddr.sin_addr;
03272       sin->sin_port = peer->defaddr.sin_port;
03273    }
03274 
03275    res = 0;
03276 
03277 return_unref:
03278    peer_unref(peer);
03279 
03280    return res;
03281 }
03282 
03283 static void __auto_congest(const void *nothing)
03284 {
03285    int callno = PTR_TO_CALLNO(nothing);
03286    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03287    ast_mutex_lock(&iaxsl[callno]);
03288    if (iaxs[callno]) {
03289       iaxs[callno]->initid = -1;
03290       iax2_queue_frame(callno, &f);
03291       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03292    }
03293    ast_mutex_unlock(&iaxsl[callno]);
03294 }
03295 
03296 static int auto_congest(const void *data)
03297 {
03298 #ifdef SCHED_MULTITHREADED
03299    if (schedule_action(__auto_congest, data))
03300 #endif      
03301       __auto_congest(data);
03302    return 0;
03303 }
03304 
03305 static unsigned int iax2_datetime(const char *tz)
03306 {
03307    time_t t;
03308    struct tm tm;
03309    unsigned int tmp;
03310    time(&t);
03311    if (!ast_strlen_zero(tz))
03312       ast_localtime(&t, &tm, tz);
03313    else
03314       ast_localtime(&t, &tm, NULL);
03315    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03316    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03317    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03318    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03319    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03320    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03321    return tmp;
03322 }
03323 
03324 struct parsed_dial_string {
03325    char *username;
03326    char *password;
03327    char *key;
03328    char *peer;
03329    char *port;
03330    char *exten;
03331    char *context;
03332    char *options;
03333 };
03334 
03335 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03336 {
03337    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03338       .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03339       .csub = compress_subclass(command) };
03340 
03341    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03342 }
03343 
03344 /*!
03345  * \brief Parses an IAX dial string into its component parts.
03346  * \param data the string to be parsed
03347  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03348  * \return nothing
03349  *
03350  * This function parses the string and fills the structure
03351  * with pointers to its component parts. The input string
03352  * will be modified.
03353  *
03354  * \note This function supports both plaintext passwords and RSA
03355  * key names; if the password string is formatted as '[keyname]',
03356  * then the keyname will be placed into the key field, and the
03357  * password field will be set to NULL.
03358  *
03359  * \note The dial string format is:
03360  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03361  */
03362 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03363 {
03364    if (ast_strlen_zero(data))
03365       return;
03366 
03367    pds->peer = strsep(&data, "/");
03368    pds->exten = strsep(&data, "/");
03369    pds->options = data;
03370 
03371    if (pds->exten) {
03372       data = pds->exten;
03373       pds->exten = strsep(&data, "@");
03374       pds->context = data;
03375    }
03376 
03377    if (strchr(pds->peer, '@')) {
03378       data = pds->peer;
03379       pds->username = strsep(&data, "@");
03380       pds->peer = data;
03381    }
03382 
03383    if (pds->username) {
03384       data = pds->username;
03385       pds->username = strsep(&data, ":");
03386       pds->password = data;
03387    }
03388 
03389    data = pds->peer;
03390    pds->peer = strsep(&data, ":");
03391    pds->port = data;
03392 
03393    /* check for a key name wrapped in [] in the secret position, if found,
03394       move it to the key field instead
03395    */
03396    if (pds->password && (pds->password[0] == '[')) {
03397       pds->key = ast_strip_quoted(pds->password, "[", "]");
03398       pds->password = NULL;
03399    }
03400 }
03401 
03402 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03403 {
03404    struct sockaddr_in sin;
03405    char *l=NULL, *n=NULL, *tmpstr;
03406    struct iax_ie_data ied;
03407    char *defaultrdest = "s";
03408    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03409    struct parsed_dial_string pds;
03410    struct create_addr_info cai;
03411 
03412    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03413       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03414       return -1;
03415    }
03416 
03417    memset(&cai, 0, sizeof(cai));
03418    cai.encmethods = iax2_encryption;
03419 
03420    memset(&pds, 0, sizeof(pds));
03421    tmpstr = ast_strdupa(dest);
03422    parse_dial_string(tmpstr, &pds);
03423 
03424    if (ast_strlen_zero(pds.peer)) {
03425       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03426       return -1;
03427    }
03428 
03429    if (!pds.exten) {
03430       pds.exten = defaultrdest;
03431    }
03432 
03433    if (create_addr(pds.peer, c, &sin, &cai)) {
03434       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03435       return -1;
03436    }
03437 
03438    if (!pds.username && !ast_strlen_zero(cai.username))
03439       pds.username = cai.username;
03440    if (!pds.password && !ast_strlen_zero(cai.secret))
03441       pds.password = cai.secret;
03442    if (!pds.key && !ast_strlen_zero(cai.outkey))
03443       pds.key = cai.outkey;
03444    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03445       pds.context = cai.peercontext;
03446 
03447    /* Keep track of the context for outgoing calls too */
03448    ast_copy_string(c->context, cai.context, sizeof(c->context));
03449 
03450    if (pds.port)
03451       sin.sin_port = htons(atoi(pds.port));
03452 
03453    l = c->cid.cid_num;
03454    n = c->cid.cid_name;
03455 
03456    /* Now build request */ 
03457    memset(&ied, 0, sizeof(ied));
03458 
03459    /* On new call, first IE MUST be IAX version of caller */
03460    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03461    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03462    if (pds.options && strchr(pds.options, 'a')) {
03463       /* Request auto answer */
03464       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03465    }
03466 
03467    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03468 
03469    if (l) {
03470       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03471       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03472    } else {
03473       if (n)
03474          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03475       else
03476          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03477    }
03478 
03479    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03480    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03481 
03482    if (n)
03483       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03484    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03485       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03486 
03487    if (!ast_strlen_zero(c->language))
03488       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03489    if (!ast_strlen_zero(c->cid.cid_dnid))
03490       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03491    if (!ast_strlen_zero(c->cid.cid_rdnis))
03492       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03493 
03494    if (pds.context)
03495       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03496 
03497    if (pds.username)
03498       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03499 
03500    if (cai.encmethods)
03501       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03502 
03503    ast_mutex_lock(&iaxsl[callno]);
03504 
03505    if (!ast_strlen_zero(c->context))
03506       ast_string_field_set(iaxs[callno], context, c->context);
03507 
03508    if (pds.username)
03509       ast_string_field_set(iaxs[callno], username, pds.username);
03510 
03511    iaxs[callno]->encmethods = cai.encmethods;
03512 
03513    iaxs[callno]->adsi = cai.adsi;
03514    
03515    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03516    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03517 
03518    if (pds.key)
03519       ast_string_field_set(iaxs[callno], outkey, pds.key);
03520    if (pds.password)
03521       ast_string_field_set(iaxs[callno], secret, pds.password);
03522 
03523    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03524    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03525    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03526    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03527 
03528    if (iaxs[callno]->maxtime) {
03529       /* Initialize pingtime and auto-congest time */
03530       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03531       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03532    } else if (autokill) {
03533       iaxs[callno]->pingtime = autokill / 2;
03534       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03535    }
03536 
03537    /* send the command using the appropriate socket for this peer */
03538    iaxs[callno]->sockfd = cai.sockfd;
03539 
03540    /* Transmit the string in a "NEW" request */
03541    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03542 
03543    ast_mutex_unlock(&iaxsl[callno]);
03544    ast_setstate(c, AST_STATE_RINGING);
03545    
03546    return 0;
03547 }
03548 
03549 static int iax2_hangup(struct ast_channel *c) 
03550 {
03551    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03552    struct iax_ie_data ied;
03553    int alreadygone;
03554    memset(&ied, 0, sizeof(ied));
03555    ast_mutex_lock(&iaxsl[callno]);
03556    if (callno && iaxs[callno]) {
03557       if (option_debug)
03558          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03559       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03560       /* Send the hangup unless we have had a transmission error or are already gone */
03561       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03562       if (!iaxs[callno]->error && !alreadygone) {
03563          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03564             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03565          }
03566          if (!iaxs[callno]) {
03567             ast_mutex_unlock(&iaxsl[callno]);
03568             return 0;
03569          }
03570       }
03571       /* Explicitly predestroy it */
03572       iax2_predestroy(callno);
03573       /* If we were already gone to begin with, destroy us now */
03574       if (iaxs[callno] && alreadygone) {
03575          if (option_debug)
03576             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03577          iax2_destroy(callno);
03578       } else if (iaxs[callno]) {
03579          iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
03580       }
03581    } else if (c->tech_pvt) {
03582       /* If this call no longer exists, but the channel still
03583        * references it we need to set the channel's tech_pvt to null
03584        * to avoid ast_channel_free() trying to free it.
03585        */
03586       c->tech_pvt = NULL;
03587    }
03588    ast_mutex_unlock(&iaxsl[callno]);
03589    if (option_verbose > 2) 
03590       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03591    return 0;
03592 }
03593 
03594 /*!
03595  * \note expects the pvt to be locked
03596  */
03597 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03598 {
03599    unsigned short callno = pvt->callno;
03600 
03601    if (!pvt->peercallno) {
03602       /* We don't know the remote side's call number, yet.  :( */
03603       int count = 10;
03604       while (count-- && pvt && !pvt->peercallno) {
03605          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03606          pvt = iaxs[callno];
03607       }
03608       if (!pvt->peercallno) {
03609          return -1;
03610       }
03611    }
03612 
03613    return 0;
03614 }
03615 
03616 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03617 {
03618    struct ast_option_header *h;
03619    int res;
03620 
03621    switch (option) {
03622    case AST_OPTION_TXGAIN:
03623    case AST_OPTION_RXGAIN:
03624       /* these two cannot be sent, because they require a result */
03625       errno = ENOSYS;
03626       return -1;
03627    default:
03628    {
03629       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03630       struct chan_iax2_pvt *pvt;
03631 
03632       ast_mutex_lock(&iaxsl[callno]);
03633       pvt = iaxs[callno];
03634 
03635       if (wait_for_peercallno(pvt)) {
03636          ast_mutex_unlock(&iaxsl[callno]);
03637          return -1;
03638       }
03639 
03640       ast_mutex_unlock(&iaxsl[callno]);
03641 
03642       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03643          return -1;
03644       }
03645 
03646       h->flag = AST_OPTION_FLAG_REQUEST;
03647       h->option = htons(option);
03648       memcpy(h->data, data, datalen);
03649       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03650                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03651                  datalen + sizeof(*h), -1);
03652       free(h);
03653       return res;
03654    }
03655    }
03656 }
03657 
03658 static struct ast_frame *iax2_read(struct ast_channel *c) 
03659 {
03660    ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
03661    return NULL;
03662 }
03663 
03664 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03665 {
03666    int res;
03667    struct iax_ie_data ied0;
03668    struct iax_ie_data ied1;
03669    unsigned int transferid = (unsigned int)ast_random();
03670    memset(&ied0, 0, sizeof(ied0));
03671    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03672    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03673    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03674 
03675    memset(&ied1, 0, sizeof(ied1));
03676    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03677    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03678    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03679    
03680    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03681    if (res)
03682       return -1;
03683    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03684    if (res)
03685       return -1;
03686    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03687    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03688    return 0;
03689 }
03690 
03691 static void lock_both(unsigned short callno0, unsigned short callno1)
03692 {
03693    ast_mutex_lock(&iaxsl[callno0]);
03694    while (ast_mutex_trylock(&iaxsl[callno1])) {
03695       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03696    }
03697 }
03698 
03699 static void unlock_both(unsigned short callno0, unsigned short callno1)
03700 {
03701    ast_mutex_unlock(&iaxsl[callno1]);
03702    ast_mutex_unlock(&iaxsl[callno0]);
03703 }
03704 
03705 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)
03706 {
03707    struct ast_channel *cs[3];
03708    struct ast_channel *who, *other;
03709    int to = -1;
03710    int res = -1;
03711    int transferstarted=0;
03712    struct ast_frame *f;
03713    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03714    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03715    struct timeval waittimer = {0, 0}, tv;
03716 
03717    lock_both(callno0, callno1);
03718    if (!iaxs[callno0] || !iaxs[callno1]) {
03719       unlock_both(callno0, callno1);
03720       return AST_BRIDGE_FAILED;
03721    }
03722    /* Put them in native bridge mode */
03723    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03724       iaxs[callno0]->bridgecallno = callno1;
03725       iaxs[callno1]->bridgecallno = callno0;
03726    }
03727    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
03728    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
03729       transferstarted = 1;
03730    }
03731    unlock_both(callno0, callno1);
03732 
03733    /* If not, try to bridge until we can execute a transfer, if we can */
03734    cs[0] = c0;
03735    cs[1] = c1;
03736    for (/* ever */;;) {
03737       /* Check in case we got masqueraded into */
03738       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03739          if (option_verbose > 2)
03740             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03741          /* Remove from native mode */
03742          if (c0->tech == &iax2_tech) {
03743             ast_mutex_lock(&iaxsl[callno0]);
03744             iaxs[callno0]->bridgecallno = 0;
03745             ast_mutex_unlock(&iaxsl[callno0]);
03746          }
03747          if (c1->tech == &iax2_tech) {
03748             ast_mutex_lock(&iaxsl[callno1]);
03749             iaxs[callno1]->bridgecallno = 0;
03750             ast_mutex_unlock(&iaxsl[callno1]);
03751          }
03752          return AST_BRIDGE_FAILED_NOWARN;
03753       }
03754       if (c0->nativeformats != c1->nativeformats) {
03755          if (option_verbose > 2) {
03756             char buf0[255];
03757             char buf1[255];
03758             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03759             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03760             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03761          }
03762          /* Remove from native mode */
03763          lock_both(callno0, callno1);
03764          if (iaxs[callno0])
03765             iaxs[callno0]->bridgecallno = 0;
03766          if (iaxs[callno1])
03767             iaxs[callno1]->bridgecallno = 0;
03768          unlock_both(callno0, callno1);
03769          return AST_BRIDGE_FAILED_NOWARN;
03770       }
03771       /* check if transfered and if we really want native bridging */
03772       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03773          /* Try the transfer */
03774          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03775                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03776             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03777          transferstarted = 1;
03778       }
03779       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03780          /* Call has been transferred.  We're no longer involved */
03781          gettimeofday(&tv, NULL);
03782          if (ast_tvzero(waittimer)) {
03783             waittimer = tv;
03784          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03785             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03786             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03787             *fo = NULL;
03788             *rc = c0;
03789             res = AST_BRIDGE_COMPLETE;
03790             break;
03791          }
03792       }
03793       to = 1000;
03794       who = ast_waitfor_n(cs, 2, &to);
03795       if (timeoutms > -1) {
03796          timeoutms -= (1000 - to);
03797          if (timeoutms < 0)
03798             timeoutms = 0;
03799       }
03800       if (!who) {
03801          if (!timeoutms) {
03802             res = AST_BRIDGE_RETRY;
03803             break;
03804          }
03805          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03806             res = AST_BRIDGE_FAILED;
03807             break;
03808          }
03809          continue;
03810       }
03811       f = ast_read(who);
03812       if (!f) {
03813          *fo = NULL;
03814          *rc = who;
03815          res = AST_BRIDGE_COMPLETE;
03816          break;
03817       }
03818       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
03819          *fo = f;
03820          *rc = who;
03821          res =  AST_BRIDGE_COMPLETE;
03822          break;
03823       }
03824       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03825       if ((f->frametype == AST_FRAME_VOICE) ||
03826          (f->frametype == AST_FRAME_TEXT) ||
03827          (f->frametype == AST_FRAME_VIDEO) || 
03828          (f->frametype == AST_FRAME_IMAGE) ||
03829          (f->frametype == AST_FRAME_DTMF) ||
03830          (f->frametype == AST_FRAME_CONTROL)) {
03831          /* monitored dtmf take out of the bridge.
03832           * check if we monitor the specific source.
03833           */
03834          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03835          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03836             *rc = who;
03837             *fo = f;
03838             res = AST_BRIDGE_COMPLETE;
03839             /* Remove from native mode */
03840             break;
03841          }
03842          /* everything else goes to the other side */
03843          ast_write(other, f);
03844       }
03845       ast_frfree(f);
03846       /* Swap who gets priority */
03847       cs[2] = cs[0];
03848       cs[0] = cs[1];
03849       cs[1] = cs[2];
03850    }
03851    lock_both(callno0, callno1);
03852    if(iaxs[callno0])
03853       iaxs[callno0]->bridgecallno = 0;
03854    if(iaxs[callno1])
03855       iaxs[callno1]->bridgecallno = 0;
03856    unlock_both(callno0, callno1);
03857    return res;
03858 }
03859 
03860 static int iax2_answer(struct ast_channel *c)
03861 {
03862    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03863    if (option_debug)
03864       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03865    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03866 }
03867 
03868 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03869 {
03870    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03871    struct chan_iax2_pvt *pvt;
03872    int res = 0;
03873 
03874    if (option_debug && iaxdebug)
03875       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03876 
03877    ast_mutex_lock(&iaxsl[callno]);
03878    pvt = iaxs[callno];
03879 
03880    if (wait_for_peercallno(pvt)) {
03881       res = -1;
03882       goto done;
03883    }
03884 
03885    switch (condition) {
03886    case AST_CONTROL_HOLD:
03887       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03888          ast_moh_start(c, data, pvt->mohinterpret);
03889          goto done;
03890       }
03891       break;
03892    case AST_CONTROL_UNHOLD:
03893       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03894          ast_moh_stop(c);
03895          goto done;
03896       }
03897    }
03898 
03899    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03900 
03901 done:
03902    ast_mutex_unlock(&iaxsl[callno]);
03903 
03904    return res;
03905 }
03906    
03907 static int iax2_transfer(struct ast_channel *c, const char *dest)
03908 {
03909    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03910    struct iax_ie_data ied;
03911    char tmp[256], *context;
03912    ast_copy_string(tmp, dest, sizeof(tmp));
03913    context = strchr(tmp, '@');
03914    if (context) {
03915       *context = '\0';
03916       context++;
03917    }
03918    memset(&ied, 0, sizeof(ied));
03919    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03920    if (context)
03921       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03922    if (option_debug)
03923       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03924    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03925 }
03926    
03927 static int iax2_getpeertrunk(struct sockaddr_in sin)
03928 {
03929    struct iax2_peer *peer;
03930    int res = 0;
03931    struct ao2_iterator i;
03932 
03933    i = ao2_iterator_init(peers, 0);
03934    while ((peer = ao2_iterator_next(&i))) {
03935       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03936           (peer->addr.sin_port == sin.sin_port)) {
03937          res = ast_test_flag(peer, IAX_TRUNK);
03938          peer_unref(peer);
03939          break;
03940       }
03941       peer_unref(peer);
03942    }
03943 
03944    return res;
03945 }
03946 
03947 /*! \brief  Create new call, interface with the PBX core */
03948 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03949 {
03950    struct ast_channel *tmp;
03951    struct chan_iax2_pvt *i;
03952    struct ast_variable *v = NULL;
03953 
03954    if (!(i = iaxs[callno])) {
03955       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03956       return NULL;
03957    }
03958 
03959    /* Don't hold call lock */
03960    ast_mutex_unlock(&iaxsl[callno]);
03961    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);
03962    ast_mutex_lock(&iaxsl[callno]);
03963    if (i != iaxs[callno]) {
03964       if (tmp) {
03965          /* unlock and relock iaxsl[callno] to preserve locking order */
03966          ast_mutex_unlock(&iaxsl[callno]);
03967          ast_channel_free(tmp);
03968          ast_mutex_lock(&iaxsl[callno]);
03969       }
03970       return NULL;
03971    }
03972 
03973    if (!tmp)
03974       return NULL;
03975    tmp->tech = &iax2_tech;
03976    /* We can support any format by default, until we get restricted */
03977    tmp->nativeformats = capability;
03978    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
03979    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
03980    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03981 
03982    /* Don't use ast_set_callerid() here because it will
03983     * generate a NewCallerID event before the NewChannel event */
03984    if (!ast_strlen_zero(i->ani))
03985       tmp->cid.cid_ani = ast_strdup(i->ani);
03986    else
03987       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03988    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03989    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03990    tmp->cid.cid_pres = i->calling_pres;
03991    tmp->cid.cid_ton = i->calling_ton;
03992    tmp->cid.cid_tns = i->calling_tns;
03993    if (!ast_strlen_zero(i->language))
03994       ast_string_field_set(tmp, language, i->language);
03995    if (!ast_strlen_zero(i->accountcode))
03996       ast_string_field_set(tmp, accountcode, i->accountcode);
03997    if (i->amaflags)
03998       tmp->amaflags = i->amaflags;
03999    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04000    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04001    if (i->adsi)
04002       tmp->adsicpe = i->peeradsicpe;
04003    else
04004       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04005    i->owner = tmp;
04006    i->capability = capability;
04007 
04008    for (v = i->vars ; v ; v = v->next)
04009       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04010 
04011    if (state != AST_STATE_DOWN) {
04012       if (ast_pbx_start(tmp)) {
04013          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04014          ast_hangup(tmp);
04015          i->owner = NULL;
04016          return NULL;
04017       }
04018    }
04019 
04020    ast_module_ref(ast_module_info->self);
04021    
04022    return tmp;
04023 }
04024 
04025 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
04026 {
04027    unsigned long int mssincetx; /* unsigned to handle overflows */
04028    long int ms, pred;
04029 
04030    tpeer->trunkact = *tv;
04031    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
04032    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04033       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
04034       tpeer->txtrunktime = *tv;
04035       tpeer->lastsent = 999999;
04036    }
04037    /* Update last transmit time now */
04038    tpeer->lasttxtime = *tv;
04039    
04040    /* Calculate ms offset */
04041    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04042    /* Predict from last value */
04043    pred = tpeer->lastsent + sampms;
04044    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04045       ms = pred;
04046    
04047    /* We never send the same timestamp twice, so fudge a little if we must */
04048    if (ms == tpeer->lastsent)
04049       ms = tpeer->lastsent + 1;
04050    tpeer->lastsent = ms;
04051    return ms;
04052 }
04053 
04054 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
04055 {
04056    long ms; /* NOT unsigned */
04057    if (ast_tvzero(iaxs[callno]->rxcore)) {
04058       /* Initialize rxcore time if appropriate */
04059       gettimeofday(&iaxs[callno]->rxcore, NULL);
04060       /* Round to nearest 20ms so traces look pretty */
04061       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04062    }
04063    /* Calculate difference between trunk and channel */
04064    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04065    /* Return as the sum of trunk time and the difference between trunk and real time */
04066    return ms + ts;
04067 }
04068 
04069 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04070 {
04071    int ms;
04072    int voice = 0;
04073    int genuine = 0;
04074    int adjust;
04075    int rate = ast_format_rate(f->subclass) / 1000;
04076    struct timeval *delivery = NULL;
04077 
04078 
04079    /* What sort of frame do we have?: voice is self-explanatory
04080       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
04081       non-genuine frames are CONTROL frames [ringing etc], DTMF
04082       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
04083       the others need a timestamp slaved to the voice frames so that they go in sequence
04084    */
04085    if (f) {
04086       if (f->frametype == AST_FRAME_VOICE) {
04087          voice = 1;
04088          delivery = &f->delivery;
04089       } else if (f->frametype == AST_FRAME_IAX) {
04090          genuine = 1;
04091       } else if (f->frametype == AST_FRAME_CNG) {
04092          p->notsilenttx = 0;  
04093       }
04094    }
04095    if (ast_tvzero(p->offset)) {
04096       gettimeofday(&p->offset, NULL);
04097       /* Round to nearest 20ms for nice looking traces */
04098       p->offset.tv_usec -= p->offset.tv_usec % 20000;
04099    }
04100    /* If the timestamp is specified, just send it as is */
04101    if (ts)
04102       return ts;
04103    /* If we have a time that the frame arrived, always use it to make our timestamp */
04104    if (delivery && !ast_tvzero(*delivery)) {
04105       ms = ast_tvdiff_ms(*delivery, p->offset);
04106       if (ms < 0) {
04107          ms = 0;
04108       }
04109       if (option_debug > 2 && iaxdebug)
04110          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04111    } else {
04112       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04113       if (ms < 0)
04114          ms = 0;
04115       if (voice) {
04116          /* On a voice frame, use predicted values if appropriate */
04117          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04118             /* Adjust our txcore, keeping voice and non-voice synchronized */
04119             /* AN EXPLANATION:
04120                When we send voice, we usually send "calculated" timestamps worked out
04121                on the basis of the number of samples sent. When we send other frames,
04122                we usually send timestamps worked out from the real clock.
04123                The problem is that they can tend to drift out of step because the 
04124                   source channel's clock and our clock may not be exactly at the same rate.
04125                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
04126                for this call.  Moving it adjusts timestamps for non-voice frames.
04127                We make the adjustment in the style of a moving average.  Each time we
04128                adjust p->offset by 10% of the difference between our clock-derived
04129                timestamp and the predicted timestamp.  That's why you see "10000"
04130                below even though IAX2 timestamps are in milliseconds.
04131                The use of a moving average avoids offset moving too radically.
04132                Generally, "adjust" roams back and forth around 0, with offset hardly
04133                changing at all.  But if a consistent different starts to develop it
04134                will be eliminated over the course of 10 frames (200-300msecs) 
04135             */
04136             adjust = (ms - p->nextpred);
04137             if (adjust < 0)
04138                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04139             else if (adjust > 0)
04140                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04141 
04142             if (!p->nextpred) {
04143                p->nextpred = ms; /*f->samples / rate;*/
04144                if (p->nextpred <= p->lastsent)
04145                   p->nextpred = p->lastsent + 3;
04146             }
04147             ms = p->nextpred;
04148          } else {
04149                 /* in this case, just use the actual
04150             * time, since we're either way off
04151             * (shouldn't happen), or we're  ending a
04152             * silent period -- and seed the next
04153             * predicted time.  Also, round ms to the
04154             * next multiple of frame size (so our
04155             * silent periods are multiples of
04156             * frame size too) */
04157 
04158             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04159                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04160                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04161 
04162             if (f->samples >= rate) /* check to make sure we dont core dump */
04163             {
04164                int diff = ms % (f->samples / rate);
04165                if (diff)
04166                    ms += f->samples/rate - diff;
04167             }
04168 
04169             p->nextpred = ms;
04170             p->notsilenttx = 1;
04171          }
04172       } else if ( f->frametype == AST_FRAME_VIDEO ) {
04173          /*
04174          * IAX2 draft 03 says that timestamps MUST be in order.
04175          * It does not say anything about several frames having the same timestamp
04176          * When transporting video, we can have a frame that spans multiple iax packets
04177          * (so called slices), so it would make sense to use the same timestamp for all of
04178          * them
04179          * We do want to make sure that frames don't go backwards though
04180          */
04181          if ( (unsigned int)ms < p->lastsent )
04182             ms = p->lastsent;
04183       } else {
04184          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
04185             it's a genuine frame */
04186          if (genuine) {
04187             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
04188             if (ms <= p->lastsent)
04189                ms = p->lastsent + 3;
04190          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04191             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
04192             ms = p->lastsent + 3;
04193          }
04194       }
04195    }
04196    p->lastsent = ms;
04197    if (voice)
04198       p->nextpred = p->nextpred + f->samples / rate;
04199    return ms;
04200 }
04201 
04202 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04203 {
04204    /* Returns where in "receive time" we are.  That is, how many ms
04205       since we received (or would have received) the frame with timestamp 0 */
04206    int ms;
04207 #ifdef IAXTESTS
04208    int jit;
04209 #endif /* IAXTESTS */
04210    /* Setup rxcore if necessary */
04211    if (ast_tvzero(p->rxcore)) {
04212       p->rxcore = ast_tvnow();
04213       if (option_debug && iaxdebug)
04214          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04215                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04216       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04217 #if 1
04218       if (option_debug && iaxdebug)
04219          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04220                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04221 #endif
04222    }
04223 
04224    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04225 #ifdef IAXTESTS
04226    if (test_jit) {
04227       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04228          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04229          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04230             jit = -jit;
04231          ms += jit;
04232       }
04233    }
04234    if (test_late) {
04235       ms += test_late;
04236       test_late = 0;
04237    }
04238 #endif /* IAXTESTS */
04239    return ms;
04240 }
04241 
04242 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04243 {
04244    struct iax2_trunk_peer *tpeer;
04245    
04246    /* Finds and locks trunk peer */
04247    ast_mutex_lock(&tpeerlock);
04248    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04249       /* We don't lock here because tpeer->addr *never* changes */
04250       if (!inaddrcmp(&tpeer->addr, sin)) {
04251          ast_mutex_lock(&tpeer->lock);
04252          break;
04253       }
04254    }
04255    if (!tpeer) {
04256       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04257          ast_mutex_init(&tpeer->lock);
04258          tpeer->lastsent = 9999;
04259          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04260          tpeer->trunkact = ast_tvnow();
04261          ast_mutex_lock(&tpeer->lock);
04262          tpeer->next = tpeers;
04263          tpeer->sockfd = fd;
04264          tpeers = tpeer;
04265 #ifdef SO_NO_CHECK
04266          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04267 #endif
04268          if (option_debug)
04269             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04270       }
04271    }
04272    ast_mutex_unlock(&tpeerlock);
04273    return tpeer;
04274 }
04275 
04276 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04277 {
04278    struct ast_frame *f;
04279    struct iax2_trunk_peer *tpeer;
04280    void *tmp, *ptr;
04281    struct ast_iax2_meta_trunk_entry *met;
04282    struct ast_iax2_meta_trunk_mini *mtm;
04283 
04284    f = &fr->af;
04285    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04286    if (tpeer) {
04287       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04288          /* Need to reallocate space */
04289          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04290             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04291                ast_mutex_unlock(&tpeer->lock);
04292                return -1;
04293             }
04294             
04295             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04296             tpeer->trunkdata = tmp;
04297             if (option_debug)
04298                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);
04299          } else {
04300             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));
04301             ast_mutex_unlock(&tpeer->lock);
04302             return -1;
04303          }
04304       }
04305 
04306       /* Append to meta frame */
04307       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04308       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04309          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04310          mtm->len = htons(f->datalen);
04311          mtm->mini.callno = htons(pvt->callno);
04312          mtm->mini.ts = htons(0xffff & fr->ts);
04313          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04314          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04315       } else {
04316          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04317          /* Store call number and length in meta header */
04318          met->callno = htons(pvt->callno);
04319          met->len = htons(f->datalen);
04320          /* Advance pointers/decrease length past trunk entry header */
04321          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04322          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04323       }
04324       /* Copy actual trunk data */
04325       memcpy(ptr, f->data, f->datalen);
04326       tpeer->trunkdatalen += f->datalen;
04327 
04328       tpeer->calls++;
04329       ast_mutex_unlock(&tpeer->lock);
04330    }
04331    return 0;
04332 }
04333 
04334 /* IAX2 encryption requires 16 to 32 bytes of random padding to be present
04335  * before the encryption data.  This function randomizes that data. */
04336 static void build_rand_pad(unsigned char *buf, ssize_t len)
04337 {
04338    long tmp;
04339    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
04340       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
04341       buf += sizeof(tmp);
04342       len -= sizeof(tmp);
04343    }
04344 }
04345 
04346 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04347 {
04348    build_ecx_key(digest, pvt);
04349    aes_decrypt_key128(digest, &pvt->dcx);
04350 }
04351   
04352 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04353 {
04354    /* it is required to hold the corresponding decrypt key to our encrypt key
04355     * in the pvt struct because queued frames occasionally need to be decrypted and
04356     * re-encrypted when updated for a retransmission */
04357    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
04358    aes_encrypt_key128(digest, &pvt->ecx);
04359    aes_decrypt_key128(digest, &pvt->mydcx);
04360 }
04361 
04362 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04363 {
04364 #if 0
04365    /* Debug with "fake encryption" */
04366    int x;
04367    if (len % 16)
04368       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04369    for (x=0;x<len;x++)
04370       dst[x] = src[x] ^ 0xff;
04371 #else 
04372    unsigned char lastblock[16] = { 0 };
04373    int x;
04374    while(len > 0) {
04375       aes_decrypt(src, dst, dcx);
04376       for (x=0;x<16;x++)
04377          dst[x] ^= lastblock[x];
04378       memcpy(lastblock, src, sizeof(lastblock));
04379       dst += 16;
04380       src += 16;
04381       len -= 16;
04382    }
04383 #endif
04384 }
04385 
04386 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04387 {
04388 #if 0
04389    /* Debug with "fake encryption" */
04390    int x;
04391    if (len % 16)
04392       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04393    for (x=0;x<len;x++)
04394       dst[x] = src[x] ^ 0xff;
04395 #else
04396    unsigned char curblock[16] = { 0 };
04397    int x;
04398    while(len > 0) {
04399       for (x=0;x<16;x++)
04400          curblock[x] ^= src[x];
04401       aes_encrypt(curblock, dst, ecx);
04402       memcpy(curblock, dst, sizeof(curblock)); 
04403       dst += 16;
04404       src += 16;
04405       len -= 16;
04406    }
04407 #endif
04408 }
04409 
04410 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04411 {
04412    int padding;
04413    unsigned char *workspace;
04414 
04415    workspace = alloca(*datalen);
04416    memset(f, 0, sizeof(*f));
04417    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04418       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04419       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04420          return -1;
04421       /* Decrypt */
04422       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04423 
04424       padding = 16 + (workspace[15] & 0x0f);
04425       if (option_debug && iaxdebug)
04426          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04427       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04428          return -1;
04429 
04430       *datalen -= padding;
04431       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04432       f->frametype = fh->type;
04433       if (f->frametype == AST_FRAME_VIDEO) {
04434          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04435       } else {
04436          f->subclass = uncompress_subclass(fh->csub);
04437       }
04438    } else {
04439       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04440       if (option_debug && iaxdebug)
04441          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04442       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04443          return -1;
04444       /* Decrypt */
04445       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04446       padding = 16 + (workspace[15] & 0x0f);
04447       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04448          return -1;
04449       *datalen -= padding;
04450       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04451    }
04452    return 0;
04453 }
04454 
04455 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04456 {
04457    int padding;
04458    unsigned char *workspace;
04459    workspace = alloca(*datalen + 32);
04460    if (!workspace)
04461       return -1;
04462    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04463       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04464       if (option_debug && iaxdebug)
04465          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04466       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04467       padding = 16 + (padding & 0xf);
04468       memcpy(workspace, poo, padding);
04469       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04470       workspace[15] &= 0xf0;
04471       workspace[15] |= (padding & 0xf);
04472       if (option_debug && iaxdebug)
04473          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]);
04474       *datalen += padding;
04475       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04476       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04477          memcpy(poo, workspace + *datalen - 32, 32);
04478    } else {
04479       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04480       if (option_debug && iaxdebug)
04481          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04482       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04483       padding = 16 + (padding & 0xf);
04484       memcpy(workspace, poo, padding);
04485       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04486       workspace[15] &= 0xf0;
04487       workspace[15] |= (padding & 0x0f);
04488       *datalen += padding;
04489       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04490       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04491          memcpy(poo, workspace + *datalen - 32, 32);
04492    }
04493    return 0;
04494 }
04495 
04496 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04497 {
04498    int res=-1;
04499    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04500       /* Search for possible keys, given secrets */
04501       struct MD5Context md5;
04502       unsigned char digest[16];
04503       char *tmppw, *stringp;
04504       
04505       tmppw = ast_strdupa(iaxs[callno]->secret);
04506       stringp = tmppw;
04507       while ((tmppw = strsep(&stringp, ";"))) {
04508          MD5Init(&md5);
04509          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04510          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04511          MD5Final(digest, &md5);
04512          build_encryption_keys(digest, iaxs[callno]);
04513          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04514          if (!res) {
04515             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04516             break;
04517          }
04518       }
04519    } else 
04520       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04521    return res;
04522 }
04523 
04524 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04525 {
04526    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04527       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04528       or delayed, with retransmission */
04529    struct ast_iax2_full_hdr *fh;
04530    struct ast_iax2_mini_hdr *mh;
04531    struct ast_iax2_video_hdr *vh;
04532    struct {
04533       struct iax_frame fr2;
04534       unsigned char buffer[4096];
04535    } frb;
04536    struct iax_frame *fr;
04537    int res;
04538    int sendmini=0;
04539    unsigned int lastsent;
04540    unsigned int fts;
04541 
04542    frb.fr2.afdatalen = sizeof(frb.buffer);
04543 
04544    if (!pvt) {
04545       ast_log(LOG_WARNING, "No private structure for packet?\n");
04546       return -1;
04547    }
04548    
04549    lastsent = pvt->lastsent;
04550 
04551    /* Calculate actual timestamp */
04552    fts = calc_timestamp(pvt, ts, f);
04553 
04554    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04555     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04556     * increment the "predicted timestamps" for voice, if we're predecting */
04557    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04558        return 0;
04559 
04560 
04561    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04562          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04563          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04564       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04565        (f->frametype == AST_FRAME_VOICE) 
04566       /* is a voice frame */ &&
04567       (f->subclass == pvt->svoiceformat) 
04568       /* is the same type */ ) {
04569          /* Force immediate rather than delayed transmission */
04570          now = 1;
04571          /* Mark that mini-style frame is appropriate */
04572          sendmini = 1;
04573    }
04574    if ( f->frametype == AST_FRAME_VIDEO ) {
04575       /*
04576        * If the lower 15 bits of the timestamp roll over, or if
04577        * the video format changed then send a full frame.
04578        * Otherwise send a mini video frame
04579        */
04580       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04581           ((f->subclass & ~0x1) == pvt->svideoformat)
04582          ) {
04583          now = 1;
04584          sendmini = 1;
04585       } else {
04586          now = 0;
04587          sendmini = 0;
04588       }
04589       pvt->lastvsent = fts;
04590    }
04591    if (f->frametype == AST_FRAME_IAX) {
04592       /* 0x8000 marks this message as TX:, this bit will be stripped later */
04593       pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
04594       if (!pvt->first_iax_message) {
04595          pvt->first_iax_message = pvt->last_iax_message;
04596       }
04597    }
04598    /* Allocate an iax_frame */
04599    if (now) {
04600       fr = &frb.fr2;
04601    } else
04602       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));
04603    if (!fr) {
04604       ast_log(LOG_WARNING, "Out of memory\n");
04605       return -1;
04606    }
04607    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04608    iax_frame_wrap(fr, f);
04609 
04610    fr->ts = fts;
04611    fr->callno = pvt->callno;
04612    fr->transfer = transfer;
04613    fr->final = final;
04614    fr->encmethods = 0;
04615    if (!sendmini) {
04616       /* We need a full frame */
04617       if (seqno > -1)
04618          fr->oseqno = seqno;
04619       else
04620          fr->oseqno = pvt->oseqno++;
04621       fr->iseqno = pvt->iseqno;
04622       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04623       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04624       fh->ts = htonl(fr->ts);
04625       fh->oseqno = fr->oseqno;
04626       if (transfer) {
04627          fh->iseqno = 0;
04628       } else
04629          fh->iseqno = fr->iseqno;
04630       /* Keep track of the last thing we've acknowledged */
04631       if (!transfer)
04632          pvt->aseqno = fr->iseqno;
04633       fh->type = fr->af.frametype & 0xFF;
04634       if (fr->af.frametype == AST_FRAME_VIDEO)
04635          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04636       else
04637          fh->csub = compress_subclass(fr->af.subclass);
04638       if (transfer) {
04639          fr->dcallno = pvt->transfercallno;
04640       } else
04641          fr->dcallno = pvt->peercallno;
04642       fh->dcallno = htons(fr->dcallno);
04643       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04644       fr->data = fh;
04645       fr->retries = 0;
04646       /* Retry after 2x the ping time has passed */
04647       fr->retrytime = pvt->pingtime * 2;
04648       if (fr->retrytime < MIN_RETRY_TIME)
04649          fr->retrytime = MIN_RETRY_TIME;
04650       if (fr->retrytime > MAX_RETRY_TIME)
04651          fr->retrytime = MAX_RETRY_TIME;
04652       /* Acks' don't get retried */
04653       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04654          fr->retries = -1;
04655       else if (f->frametype == AST_FRAME_VOICE)
04656          pvt->svoiceformat = f->subclass;
04657       else if (f->frametype == AST_FRAME_VIDEO)
04658          pvt->svideoformat = f->subclass & ~0x1;
04659       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04660          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04661             if (iaxdebug) {
04662                if (fr->transfer)
04663                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04664                else
04665                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04666             }
04667             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04668             fr->encmethods = pvt->encmethods;
04669             fr->ecx = pvt->ecx;
04670             fr->mydcx = pvt->mydcx;
04671             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
04672          } else
04673             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04674       }
04675 
04676       if (now) {
04677          res = send_packet(fr);
04678       } else
04679          res = iax2_transmit(fr);
04680    } else {
04681       if (ast_test_flag(pvt, IAX_TRUNK)) {
04682          iax2_trunk_queue(pvt, fr);
04683          res = 0;
04684       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04685          /* Video frame have no sequence number */
04686          fr->oseqno = -1;
04687          fr->iseqno = -1;
04688          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04689          vh->zeros = 0;
04690          vh->callno = htons(0x8000 | fr->callno);
04691          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04692          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04693          fr->data = vh;
04694          fr->retries = -1;
04695          res = send_packet(fr);        
04696       } else {
04697          /* Mini-frames have no sequence number */
04698          fr->oseqno = -1;
04699          fr->iseqno = -1;
04700          /* Mini frame will do */
04701          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04702          mh->callno = htons(fr->callno);
04703          mh->ts = htons(fr->ts & 0xFFFF);
04704          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04705          fr->data = mh;
04706          fr->retries = -1;
04707          if (pvt->transferring == TRANSFER_MEDIAPASS)
04708             fr->transfer = 1;
04709          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04710             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04711                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04712             } else
04713                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04714          }
04715          res = send_packet(fr);
04716       }
04717    }
04718    return res;
04719 }
04720 
04721 static int iax2_show_users(int fd, int argc, char *argv[])
04722 {
04723    regex_t regexbuf;
04724    int havepattern = 0;
04725 
04726 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04727 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04728 
04729    struct iax2_user *user = NULL;
04730    char auth[90];
04731    char *pstr = "";
04732    struct ao2_iterator i;
04733 
04734    switch (argc) {
04735    case 5:
04736       if (!strcasecmp(argv[3], "like")) {
04737          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04738             return RESULT_SHOWUSAGE;
04739          havepattern = 1;
04740       } else
04741          return RESULT_SHOWUSAGE;
04742    case 3:
04743       break;
04744    default:
04745       return RESULT_SHOWUSAGE;
04746    }
04747 
04748    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04749    i = ao2_iterator_init(users, 0);
04750    for (user = ao2_iterator_next(&i); user; 
04751       user_unref(user), user = ao2_iterator_next(&i)) {
04752       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04753          continue;
04754       
04755       if (!ast_strlen_zero(user->secret)) {
04756          ast_copy_string(auth,user->secret,sizeof(auth));
04757       } else if (!ast_strlen_zero(user->inkeys)) {
04758          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04759       } else
04760          ast_copy_string(auth, "-no secret-", sizeof(auth));
04761       
04762       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04763          pstr = "REQ Only";
04764       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04765          pstr = "Disabled";
04766       else
04767          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04768       
04769       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04770          user->contexts ? user->contexts->context : context,
04771          user->ha ? "Yes" : "No", pstr);
04772    }
04773 
04774    if (havepattern)
04775       regfree(&regexbuf);
04776 
04777    return RESULT_SUCCESS;
04778 #undef FORMAT
04779 #undef FORMAT2
04780 }
04781 
04782 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04783 {
04784    regex_t regexbuf;
04785    int havepattern = 0;
04786    int total_peers = 0;
04787    int online_peers = 0;
04788    int offline_peers = 0;
04789    int unmonitored_peers = 0;
04790    struct ao2_iterator i;
04791 
04792 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04793 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04794 
04795    struct iax2_peer *peer = NULL;
04796    char name[256];
04797    int registeredonly=0;
04798    char *term = manager ? "\r\n" : "\n";
04799 
04800    switch (argc) {
04801    case 6:
04802       if (!strcasecmp(argv[3], "registered"))
04803          registeredonly = 1;
04804       else
04805          return RESULT_SHOWUSAGE;
04806       if (!strcasecmp(argv[4], "like")) {
04807          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04808             return RESULT_SHOWUSAGE;
04809          havepattern = 1;
04810       } else
04811          return RESULT_SHOWUSAGE;
04812       break;
04813    case 5:
04814       if (!strcasecmp(argv[3], "like")) {
04815          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04816             return RESULT_SHOWUSAGE;
04817          havepattern = 1;
04818       } else
04819          return RESULT_SHOWUSAGE;
04820       break;
04821    case 4:
04822       if (!strcasecmp(argv[3], "registered"))
04823          registeredonly = 1;
04824       else
04825          return RESULT_SHOWUSAGE;
04826       break;
04827    case 3:
04828       break;
04829    default:
04830       return RESULT_SHOWUSAGE;
04831    }
04832 
04833 
04834    if (s)
04835       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04836    else
04837       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04838 
04839    i = ao2_iterator_init(peers, 0);
04840    for (peer = ao2_iterator_next(&i); peer; 
04841       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04842       char nm[20];
04843       char status[20];
04844       char srch[2000];
04845       int retstatus;
04846 
04847       if (registeredonly && !peer->addr.sin_addr.s_addr)
04848          continue;
04849       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04850          continue;
04851 
04852       if (!ast_strlen_zero(peer->username))
04853          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04854       else
04855          ast_copy_string(name, peer->name, sizeof(name));
04856       
04857       retstatus = peer_status(peer, status, sizeof(status));
04858       if (retstatus > 0)
04859          online_peers++;
04860       else if (!retstatus)
04861          offline_peers++;
04862       else
04863          unmonitored_peers++;
04864       
04865       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04866       
04867       snprintf(srch, sizeof(srch), FORMAT, name, 
04868           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04869           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04870           nm,
04871           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04872           peer->encmethods ? "(E)" : "   ", status, term);
04873       
04874       if (s)
04875          astman_append(s, FORMAT, name, 
04876                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04877                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04878                   nm,
04879                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04880                   peer->encmethods ? "(E)" : "   ", status, term);
04881       else
04882          ast_cli(fd, FORMAT, name, 
04883             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04884             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04885             nm,
04886             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04887             peer->encmethods ? "(E)" : "   ", status, term);
04888       total_peers++;
04889    }
04890 
04891    if (s)
04892       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04893    else
04894       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04895 
04896    if (havepattern)
04897       regfree(&regexbuf);
04898 
04899    return RESULT_SUCCESS;
04900 #undef FORMAT
04901 #undef FORMAT2
04902 }
04903 
04904 static int iax2_show_threads(int fd, int argc, char *argv[])
04905 {
04906    struct iax2_thread *thread = NULL;
04907    time_t t;
04908    int threadcount = 0, dynamiccount = 0;
04909    char type;
04910 
04911    if (argc != 3)
04912       return RESULT_SHOWUSAGE;
04913       
04914    ast_cli(fd, "IAX2 Thread Information\n");
04915    time(&t);
04916    ast_cli(fd, "Idle Threads:\n");
04917    AST_LIST_LOCK(&idle_list);
04918    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04919 #ifdef DEBUG_SCHED_MULTITHREAD
04920       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04921          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04922 #else
04923       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04924          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04925 #endif
04926       threadcount++;
04927    }
04928    AST_LIST_UNLOCK(&idle_list);
04929    ast_cli(fd, "Active Threads:\n");
04930    AST_LIST_LOCK(&active_list);
04931    AST_LIST_TRAVERSE(&active_list, thread, list) {
04932       if (thread->type == IAX_TYPE_DYNAMIC)
04933          type = 'D';
04934       else
04935          type = 'P';
04936 #ifdef DEBUG_SCHED_MULTITHREAD
04937       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04938          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04939 #else
04940       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04941          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04942 #endif
04943       threadcount++;
04944    }
04945    AST_LIST_UNLOCK(&active_list);
04946    ast_cli(fd, "Dynamic Threads:\n");
04947         AST_LIST_LOCK(&dynamic_list);
04948         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04949 #ifdef DEBUG_SCHED_MULTITHREAD
04950                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04951                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04952 #else
04953                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04954                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04955 #endif
04956       dynamiccount++;
04957         }
04958         AST_LIST_UNLOCK(&dynamic_list);
04959    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04960    return RESULT_SUCCESS;
04961 }
04962 
04963 static int iax2_show_peers(int fd, int argc, char *argv[])
04964 {
04965    return __iax2_show_peers(0, fd, NULL, argc, argv);
04966 }
04967 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04968 {
04969    ast_cli_netstats(s, -1, 0);
04970    astman_append(s, "\r\n");
04971    return RESULT_SUCCESS;
04972 }
04973 
04974 static int iax2_show_firmware(int fd, int argc, char *argv[])
04975 {
04976 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04977 #if !defined(__FreeBSD__)
04978 #define FORMAT "%-15.15s  %-15d %-15d\n"
04979 #else /* __FreeBSD__ */
04980 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04981 #endif /* __FreeBSD__ */
04982    struct iax_firmware *cur;
04983    if ((argc != 3) && (argc != 4))
04984       return RESULT_SHOWUSAGE;
04985    ast_mutex_lock(&waresl.lock);
04986    
04987    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04988    for (cur = waresl.wares;cur;cur = cur->next) {
04989       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04990          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04991             (int)ntohl(cur->fwh->datalen));
04992    }
04993    ast_mutex_unlock(&waresl.lock);
04994    return RESULT_SUCCESS;
04995 #undef FORMAT
04996 #undef FORMAT2
04997 }
04998 
04999 /* JDG: callback to display iax peers in manager */
05000 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05001 {
05002    char *a[] = { "iax2", "show", "users" };
05003    int ret;
05004    const char *id = astman_get_header(m,"ActionID");
05005 
05006    if (!ast_strlen_zero(id))
05007       astman_append(s, "ActionID: %s\r\n",id);
05008    ret = __iax2_show_peers(1, -1, s, 3, a );
05009    astman_append(s, "\r\n\r\n" );
05010    return ret;
05011 } /* /JDG */
05012 
05013 static char *regstate2str(int regstate)
05014 {
05015    switch(regstate) {
05016    case REG_STATE_UNREGISTERED:
05017       return "Unregistered";
05018    case REG_STATE_REGSENT:
05019       return "Request Sent";
05020    case REG_STATE_AUTHSENT:
05021       return "Auth. Sent";
05022    case REG_STATE_REGISTERED:
05023       return "Registered";
05024    case REG_STATE_REJECTED:
05025       return "Rejected";
05026    case REG_STATE_TIMEOUT:
05027       return "Timeout";
05028    case REG_STATE_NOAUTH:
05029       return "No Authentication";
05030    default:
05031       return "Unknown";
05032    }
05033 }
05034 
05035 static int iax2_show_registry(int fd, int argc, char *argv[])
05036 {
05037 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
05038 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
05039    struct iax2_registry *reg = NULL;
05040 
05041    char host[80];
05042    char perceived[80];
05043    if (argc != 3)
05044       return RESULT_SHOWUSAGE;
05045    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05046    AST_LIST_LOCK(&registrations);
05047    AST_LIST_TRAVERSE(&registrations, reg, entry) {
05048       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05049       if (reg->us.sin_addr.s_addr) 
05050          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05051       else
05052          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05053       ast_cli(fd, FORMAT, host, 
05054                (reg->dnsmgr) ? "Y" : "N", 
05055                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05056    }
05057    AST_LIST_UNLOCK(&registrations);
05058    return RESULT_SUCCESS;
05059 #undef FORMAT
05060 #undef FORMAT2
05061 }
05062 
05063 static int iax2_show_channels(int fd, int argc, char *argv[])
05064 {
05065 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
05066 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
05067 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
05068    int x;
05069    int numchans = 0;
05070    int usedchans = 0;
05071    char first_message[10] = { 0, };
05072    char last_message[10] = { 0, };
05073 
05074    if (argc != 3)
05075       return RESULT_SHOWUSAGE;
05076    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
05077    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05078       ast_mutex_lock(&iaxsl[x]);
05079       if (iaxs[x]) {
05080          int lag, jitter, localdelay;
05081          jb_info jbinfo;
05082          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05083             jb_getinfo(iaxs[x]->jb, &jbinfo);
05084             jitter = jbinfo.jitter;
05085             localdelay = jbinfo.current - jbinfo.min;
05086          } else {
05087             jitter = -1;
05088             localdelay = 0;
05089          }
05090 
05091          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05092          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05093          lag = iaxs[x]->remote_rr.delay;
05094          ast_cli(fd, FORMAT,
05095             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05096             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
05097             S_OR(iaxs[x]->username, "(None)"),
05098             iaxs[x]->callno, iaxs[x]->peercallno,
05099             iaxs[x]->oseqno, iaxs[x]->iseqno,
05100             lag,
05101             jitter,
05102             localdelay,
05103             ast_getformatname(iaxs[x]->voiceformat),
05104             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05105             first_message,
05106             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05107             last_message);
05108          numchans++;
05109          if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */
05110             usedchans++;
05111          }  
05112       }
05113       ast_mutex_unlock(&iaxsl[x]);
05114    }
05115    ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
05116    ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
05117    return RESULT_SUCCESS;
05118 #undef FORMAT
05119 #undef FORMAT2
05120 #undef FORMATB
05121 }
05122 
05123 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05124 {
05125    int x;
05126    int numchans = 0;
05127    char first_message[10] = { 0, };
05128    char last_message[10] = { 0, };
05129    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05130       ast_mutex_lock(&iaxsl[x]);
05131       if (iaxs[x]) {
05132          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05133          char *fmt;
05134          jb_info jbinfo;
05135 
05136          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05137             jb_getinfo(iaxs[x]->jb, &jbinfo);
05138             localjitter = jbinfo.jitter;
05139             localdelay = jbinfo.current - jbinfo.min;
05140             locallost = jbinfo.frames_lost;
05141             locallosspct = jbinfo.losspct/1000;
05142             localdropped = jbinfo.frames_dropped;
05143             localooo = jbinfo.frames_ooo;
05144          } else {
05145             localjitter = -1;
05146             localdelay = 0;
05147             locallost = -1;
05148             locallosspct = -1;
05149             localdropped = 0;
05150             localooo = -1;
05151          }
05152          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05153          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05154          if (limit_fmt)
05155             fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n";
05156          else
05157             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n";
05158          if (s)
05159 
05160             astman_append(s, fmt,
05161                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05162                      iaxs[x]->pingtime,
05163                      localjitter,
05164                      localdelay,
05165                      locallost,
05166                      locallosspct,
05167                      localdropped,
05168                      localooo,
05169                      iaxs[x]->frames_received/1000,
05170                      iaxs[x]->remote_rr.jitter,
05171                      iaxs[x]->remote_rr.delay,
05172                      iaxs[x]->remote_rr.losscnt,
05173                      iaxs[x]->remote_rr.losspct,
05174                      iaxs[x]->remote_rr.dropped,
05175                      iaxs[x]->remote_rr.ooo,
05176                      iaxs[x]->remote_rr.packets/1000,
05177                           (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05178                     first_message,
05179                     (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05180                     last_message);
05181          else
05182             ast_cli(fd, fmt,
05183                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05184                iaxs[x]->pingtime,
05185                localjitter,
05186                localdelay,
05187                locallost,
05188                locallosspct,
05189                localdropped,
05190                localooo,
05191                iaxs[x]->frames_received/1000,
05192                iaxs[x]->remote_rr.jitter,
05193                iaxs[x]->remote_rr.delay,
05194                iaxs[x]->remote_rr.losscnt,
05195                iaxs[x]->remote_rr.losspct,
05196                iaxs[x]->remote_rr.dropped,
05197                iaxs[x]->remote_rr.ooo,
05198                iaxs[x]->remote_rr.packets/1000,
05199                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05200                first_message,
05201                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05202                last_message);
05203          numchans++;
05204       }
05205       ast_mutex_unlock(&iaxsl[x]);
05206    }
05207    return numchans;
05208 }
05209 
05210 static int iax2_show_netstats(int fd, int argc, char *argv[])
05211 {
05212    int numchans = 0;
05213    if (argc != 3)
05214       return RESULT_SHOWUSAGE;
05215    ast_cli(fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
05216    ast_cli(fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
05217    numchans = ast_cli_netstats(NULL, fd, 1);
05218    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05219    return RESULT_SUCCESS;
05220 }
05221 
05222 static int iax2_do_debug(int fd, int argc, char *argv[])
05223 {
05224    if (argc < 2 || argc > 3)
05225       return RESULT_SHOWUSAGE;
05226    iaxdebug = 1;
05227    ast_cli(fd, "IAX2 Debugging Enabled\n");
05228    return RESULT_SUCCESS;
05229 }
05230 
05231 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
05232 {
05233    if (argc < 3 || argc > 4)
05234       return RESULT_SHOWUSAGE;
05235    iaxtrunkdebug = 1;
05236    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
05237    return RESULT_SUCCESS;
05238 }
05239 
05240 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
05241 {
05242    if (argc < 3 || argc > 4)
05243       return RESULT_SHOWUSAGE;
05244    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05245    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05246    return RESULT_SUCCESS;
05247 }
05248 
05249 static int iax2_no_debug(int fd, int argc, char *argv[])
05250 {
05251    if (argc < 3 || argc > 4)
05252       return RESULT_SHOWUSAGE;
05253    iaxdebug = 0;
05254    ast_cli(fd, "IAX2 Debugging Disabled\n");
05255    return RESULT_SUCCESS;
05256 }
05257 
05258 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05259 {
05260    if (argc < 4 || argc > 5)
05261       return RESULT_SHOWUSAGE;
05262    iaxtrunkdebug = 0;
05263    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05264    return RESULT_SUCCESS;
05265 }
05266 
05267 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05268 {
05269    if (argc < 4 || argc > 5)
05270       return RESULT_SHOWUSAGE;
05271    jb_setoutput(jb_error_output, jb_warning_output, NULL);
05272    jb_debug_output("\n");
05273    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05274    return RESULT_SUCCESS;
05275 }
05276 
05277 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05278 {
05279    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05280    int res = -1;
05281    ast_mutex_lock(&iaxsl[callno]);
05282    if (iaxs[callno]) {
05283    /* If there's an outstanding error, return failure now */
05284       if (!iaxs[callno]->error) {
05285          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05286             res = 0;
05287             /* Don't waste bandwidth sending null frames */
05288          else if (f->frametype == AST_FRAME_NULL)
05289             res = 0;
05290          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05291             res = 0;
05292          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05293             res = 0;
05294          else
05295          /* Simple, just queue for transmission */
05296             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05297       } else {
05298          if (option_debug)
05299             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05300       }
05301    }
05302    /* If it's already gone, just return */
05303    ast_mutex_unlock(&iaxsl[callno]);
05304    return res;
05305 }
05306 
05307 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05308       int now, int transfer, int final)
05309 {
05310    struct ast_frame f = { 0, };
05311 
05312    f.frametype = type;
05313    f.subclass = command;
05314    f.datalen = datalen;
05315    f.src = __FUNCTION__;
05316    f.data = (void *) data;
05317 
05318    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05319 }
05320 
05321 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05322 {
05323    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05324 }
05325 
05326 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05327 {
05328    int res;
05329    ast_mutex_lock(&iaxsl[callno]);
05330    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05331    ast_mutex_unlock(&iaxsl[callno]);
05332    return res;
05333 }
05334 
05335 /*!
05336  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05337  *       the pvt struct for the given call number may disappear during its 
05338  *       execution.
05339  */
05340 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)
05341 {
05342    int call_num = i->callno;
05343    /* It is assumed that the callno has already been locked */
05344    iax2_predestroy(i->callno);
05345    if (!iaxs[call_num])
05346       return -1;
05347    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05348 }
05349 
05350 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)
05351 {
05352    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05353 }
05354 
05355 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05356 {
05357    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05358 }
05359 
05360 static int apply_context(struct iax2_context *con, const char *context)
05361 {
05362    while(con) {
05363       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05364          return -1;
05365       con = con->next;
05366    }
05367    return 0;
05368 }
05369 
05370 
05371 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05372 {
05373    /* Start pessimistic */
05374    int res = -1;
05375    int version = 2;
05376    struct iax2_user *user = NULL, *best = NULL;
05377    int bestscore = 0;
05378    int gotcapability = 0;
05379    struct ast_variable *v = NULL, *tmpvar = NULL;
05380    struct ao2_iterator i;
05381 
05382    if (!iaxs[callno])
05383       return res;
05384    if (ies->called_number)
05385       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05386    if (ies->calling_number) {
05387       ast_shrink_phone_number(ies->calling_number);
05388       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05389    }
05390    if (ies->calling_name)
05391       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05392    if (ies->calling_ani)
05393       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05394    if (ies->dnid)
05395       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05396    if (ies->rdnis)
05397       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05398    if (ies->called_context)
05399       ast_string_field_set(iaxs[callno], context, ies->called_context);
05400    if (ies->language)
05401       ast_string_field_set(iaxs[callno], language, ies->language);
05402    if (ies->username)
05403       ast_string_field_set(iaxs[callno], username, ies->username);
05404    if (ies->calling_ton > -1)
05405       iaxs[callno]->calling_ton = ies->calling_ton;
05406    if (ies->calling_tns > -1)
05407       iaxs[callno]->calling_tns = ies->calling_tns;
05408    if (ies->calling_pres > -1)
05409       iaxs[callno]->calling_pres = ies->calling_pres;
05410    if (ies->format)
05411       iaxs[callno]->peerformat = ies->format;
05412    if (ies->adsicpe)
05413       iaxs[callno]->peeradsicpe = ies->adsicpe;
05414    if (ies->capability) {
05415       gotcapability = 1;
05416       iaxs[callno]->peercapability = ies->capability;
05417    } 
05418    if (ies->version)
05419       version = ies->version;
05420 
05421    /* Use provided preferences until told otherwise for actual preferences */
05422    if(ies->codec_prefs) {
05423       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05424       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05425    }
05426 
05427    if (!gotcapability) 
05428       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05429    if (version > IAX_PROTO_VERSION) {
05430       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05431          ast_inet_ntoa(sin->sin_addr), version);
05432       return res;
05433    }
05434    /* Search the userlist for a compatible entry, and fill in the rest */
05435    i = ao2_iterator_init(users, 0);
05436    while ((user = ao2_iterator_next(&i))) {
05437       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05438          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05439          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05440          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05441               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05442          if (!ast_strlen_zero(iaxs[callno]->username)) {
05443             /* Exact match, stop right now. */
05444             if (best)
05445                user_unref(best);
05446             best = user;
05447             break;
05448          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05449             /* No required authentication */
05450             if (user->ha) {
05451                /* There was host authentication and we passed, bonus! */
05452                if (bestscore < 4) {
05453                   bestscore = 4;
05454                   if (best)
05455                      user_unref(best);
05456                   best = user;
05457                   continue;
05458                }
05459             } else {
05460                /* No host access, but no secret, either, not bad */
05461                if (bestscore < 3) {
05462                   bestscore = 3;
05463                   if (best)
05464                      user_unref(best);
05465                   best = user;
05466                   continue;
05467                }
05468             }
05469          } else {
05470             if (user->ha) {
05471                /* Authentication, but host access too, eh, it's something.. */
05472                if (bestscore < 2) {
05473                   bestscore = 2;
05474                   if (best)
05475                      user_unref(best);
05476                   best = user;
05477                   continue;
05478                }
05479             } else {
05480                /* Authentication and no host access...  This is our baseline */
05481                if (bestscore < 1) {
05482                   bestscore = 1;
05483                   if (best)
05484                      user_unref(best);
05485                   best = user;
05486                   continue;
05487                }
05488             }
05489          }
05490       }
05491       user_unref(user);
05492    }
05493    user = best;
05494    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05495       user = realtime_user(iaxs[callno]->username, sin);
05496       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05497           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05498          user = user_unref(user);
05499       }
05500    }
05501    if (user) {
05502       /* We found our match (use the first) */
05503       /* copy vars */
05504       for (v = user->vars ; v ; v = v->next) {
05505          if((tmpvar = ast_variable_new(v->name, v->value))) {
05506             tmpvar->next = iaxs[callno]->vars; 
05507             iaxs[callno]->vars = tmpvar;
05508          }
05509       }
05510       /* If a max AUTHREQ restriction is in place, activate it */
05511       if (user->maxauthreq > 0)
05512          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05513       iaxs[callno]->prefs = user->prefs;
05514       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05515       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05516       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05517       iaxs[callno]->encmethods = user->encmethods;
05518       /* Store the requested username if not specified */
05519       if (ast_strlen_zero(iaxs[callno]->username))
05520          ast_string_field_set(iaxs[callno], username, user->name);
05521       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05522       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05523       iaxs[callno]->capability = user->capability;
05524       /* And use the default context */
05525       if (ast_strlen_zero(iaxs[callno]->context)) {
05526          if (user->contexts)
05527             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05528          else
05529             ast_string_field_set(iaxs[callno], context, context);
05530       }
05531       /* And any input keys */
05532       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05533       /* And the permitted authentication methods */
05534       iaxs[callno]->authmethods = user->authmethods;
05535       iaxs[callno]->adsi = user->adsi;
05536       /* If the user has callerid, override the remote caller id. */
05537       if (ast_test_flag(user, IAX_HASCALLERID)) {
05538          iaxs[callno]->calling_tns = 0;
05539          iaxs[callno]->calling_ton = 0;
05540          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05541          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05542          ast_string_field_set(iaxs[callno], ani, user->cid_num);
05543          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05544       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
05545          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05546       } /* else user is allowed to set their own CID settings */
05547       if (!ast_strlen_zero(user->accountcode))
05548          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05549       if (!ast_strlen_zero(user->mohinterpret))
05550          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05551       if (!ast_strlen_zero(user->mohsuggest))
05552          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05553       if (user->amaflags)
05554          iaxs[callno]->amaflags = user->amaflags;
05555       if (!ast_strlen_zero(user->language))
05556          ast_string_field_set(iaxs[callno], language, user->language);
05557       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05558       /* Keep this check last */
05559       if (!ast_strlen_zero(user->dbsecret)) {
05560          char *family, *key=NULL;
05561          char buf[80];
05562          family = ast_strdupa(user->dbsecret);
05563          key = strchr(family, '/');
05564          if (key) {
05565             *key = '\0';
05566             key++;
05567          }
05568          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05569             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05570          else
05571             ast_string_field_set(iaxs[callno], secret, buf);
05572       } else
05573          ast_string_field_set(iaxs[callno], secret, user->secret);
05574       res = 0;
05575       user = user_unref(user);
05576    } else {
05577        /* user was not found, but we should still fake an AUTHREQ.
05578         * Set authmethods to the last known authmethod used by the system
05579         * Set a fake secret, it's not looked at, just required to attempt authentication.
05580         * Set authrej so the AUTHREP is rejected without even looking at its contents */
05581       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
05582       ast_string_field_set(iaxs[callno], secret, "badsecret");
05583       iaxs[callno]->authrej = 1;
05584       if (!ast_strlen_zero(iaxs[callno]->username)) {
05585          /* only send the AUTHREQ if a username was specified. */
05586          res = 0;
05587       }
05588    }
05589    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05590    return res;
05591 }
05592 
05593 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05594 {
05595    struct ast_iax2_full_hdr fh;
05596    fh.scallno = htons(src | IAX_FLAG_FULL);
05597    fh.dcallno = htons(dst);
05598    fh.ts = 0;
05599    fh.oseqno = 0;
05600    fh.iseqno = 0;
05601    fh.type = AST_FRAME_IAX;
05602    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05603    if (iaxdebug)
05604        iax_showframe(NULL, &fh, 0, sin, 0);
05605    if (option_debug)
05606       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05607          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05608    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05609 }
05610 
05611 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05612 {
05613    /* Select exactly one common encryption if there are any */
05614    p->encmethods &= enc;
05615    if (p->encmethods) {
05616       if (p->encmethods & IAX_ENCRYPT_AES128)
05617          p->encmethods = IAX_ENCRYPT_AES128;
05618       else
05619          p->encmethods = 0;
05620    }
05621 }
05622 
05623 /*!
05624  * \pre iaxsl[call_num] is locked
05625  *
05626  * \note Since this function calls send_command_final(), the pvt struct for the given
05627  *       call number may disappear while executing this function.
05628  */
05629 static int authenticate_request(int call_num)
05630 {
05631    struct iax_ie_data ied;
05632    int res = -1, authreq_restrict = 0;
05633    char challenge[10];
05634    struct chan_iax2_pvt *p = iaxs[call_num];
05635 
05636    memset(&ied, 0, sizeof(ied));
05637 
05638    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05639    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05640       struct iax2_user *user, tmp_user = {
05641          .name = p->username, 
05642       };
05643 
05644       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05645       if (user) {
05646          if (user->curauthreq == user->maxauthreq)
05647             authreq_restrict = 1;
05648          else
05649             user->curauthreq++;
05650          user = user_unref(user);
05651       }
05652    }
05653 
05654    /* If the AUTHREQ limit test failed, send back an error */
05655    if (authreq_restrict) {
05656       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05657       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05658       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05659       return 0;
05660    }
05661 
05662    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05663    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05664       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05665       ast_string_field_set(p, challenge, challenge);
05666       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05667       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05668    }
05669    if (p->encmethods)
05670       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05671 
05672    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05673 
05674    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05675 
05676    if (p->encmethods)
05677       ast_set_flag(p, IAX_ENCRYPTED);
05678 
05679    return res;
05680 }
05681 
05682 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05683 {
05684    char requeststr[256];
05685    char md5secret[256] = "";
05686    char secret[256] = "";
05687    char rsasecret[256] = "";
05688    int res = -1; 
05689    int x;
05690    struct iax2_user *user, tmp_user = {
05691       .name = p->username, 
05692    };
05693 
05694    if (p->authrej) {
05695       return res;
05696    }
05697    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05698    if (user) {
05699       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05700          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05701          ast_clear_flag(p, IAX_MAXAUTHREQ);
05702       }
05703       ast_string_field_set(p, host, user->name);
05704       user = user_unref(user);
05705    }
05706 
05707    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05708       return res;
05709    if (ies->password)
05710       ast_copy_string(secret, ies->password, sizeof(secret));
05711    if (ies->md5_result)
05712       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05713    if (ies->rsa_result)
05714       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05715    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05716       struct ast_key *key;
05717       char *keyn;
05718       char tmpkey[256];
05719       char *stringp=NULL;
05720       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05721       stringp=tmpkey;
05722       keyn = strsep(&stringp, ":");
05723       while(keyn) {
05724          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05725          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05726             res = 0;
05727             break;
05728          } else if (!key)
05729             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05730          keyn = strsep(&stringp, ":");
05731       }
05732    } else if (p->authmethods & IAX_AUTH_MD5) {
05733       struct MD5Context md5;
05734       unsigned char digest[16];
05735       char *tmppw, *stringp;
05736       
05737       tmppw = ast_strdupa(p->secret);
05738       stringp = tmppw;
05739       while((tmppw = strsep(&stringp, ";"))) {
05740          MD5Init(&md5);
05741          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05742          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05743          MD5Final(digest, &md5);
05744          /* If they support md5, authenticate with it.  */
05745          for (x=0;x<16;x++)
05746             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05747          if (!strcasecmp(requeststr, md5secret)) {
05748             res = 0;
05749             break;
05750          }
05751       }
05752    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05753       if (!strcmp(secret, p->secret))
05754          res = 0;
05755    }
05756    return res;
05757 }
05758 
05759 /*! \brief Verify inbound registration */
05760 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05761 {
05762    char requeststr[256] = "";
05763    char peer[256] = "";
05764    char md5secret[256] = "";
05765    char rsasecret[256] = "";
05766    char secret[256] = "";
05767    struct iax2_peer *p = NULL;
05768    struct ast_key *key;
05769    char *keyn;
05770    int x;
05771    int expire = 0;
05772    int res = -1;
05773 
05774    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05775    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05776    if (ies->username)
05777       ast_copy_string(peer, ies->username, sizeof(peer));
05778    if (ies->password)
05779       ast_copy_string(secret, ies->password, sizeof(secret));
05780    if (ies->md5_result)
05781       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05782    if (ies->rsa_result)
05783       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05784    if (ies->refresh)
05785       expire = ies->refresh;
05786 
05787    if (ast_strlen_zero(peer)) {
05788       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05789       return -1;
05790    }
05791 
05792    /* SLD: first call to lookup peer during registration */
05793    ast_mutex_unlock(&iaxsl[callno]);
05794    p = find_peer(peer, 1);
05795    ast_mutex_lock(&iaxsl[callno]);
05796    if (!p || !iaxs[callno]) {
05797       if (iaxs[callno]) {
05798          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
05799 
05800          ast_string_field_set(iaxs[callno], secret, "badsecret");
05801 
05802          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
05803           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
05804           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
05805           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
05806           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
05807           *
05808           * If none of these cases exist, res will be returned as 0 without authentication indicating
05809           * an AUTHREQ needs to be sent out. */
05810 
05811          if (ast_strlen_zero(iaxs[callno]->challenge) &&
05812             !(!ast_strlen_zero(secret) && plaintext)) {
05813             /* by setting res to 0, an REGAUTH will be sent */
05814             res = 0;
05815          }
05816       }
05817       if (authdebug && !p)
05818          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05819 
05820       goto return_unref;
05821    }
05822 
05823    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05824       if (authdebug)
05825          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05826       goto return_unref;
05827    }
05828 
05829    if (!ast_apply_ha(p->ha, sin)) {
05830       if (authdebug)
05831          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05832       goto return_unref;
05833    }
05834    ast_string_field_set(iaxs[callno], secret, p->secret);
05835    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05836    /* Check secret against what we have on file */
05837    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05838       if (!ast_strlen_zero(p->inkeys)) {
05839          char tmpkeys[256];
05840          char *stringp=NULL;
05841          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05842          stringp=tmpkeys;
05843          keyn = strsep(&stringp, ":");
05844          while(keyn) {
05845             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05846             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05847                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05848                break;
05849             } else if (!key)
05850                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05851             keyn = strsep(&stringp, ":");
05852          }
05853          if (!keyn) {
05854             if (authdebug)
05855                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05856             goto return_unref;
05857          }
05858       } else {
05859          if (authdebug)
05860             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05861          goto return_unref;
05862       }
05863    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05864       struct MD5Context md5;
05865       unsigned char digest[16];
05866       char *tmppw, *stringp;
05867 
05868       tmppw = ast_strdupa(p->secret);
05869       stringp = tmppw;
05870       while((tmppw = strsep(&stringp, ";"))) {
05871          MD5Init(&md5);
05872          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05873          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05874          MD5Final(digest, &md5);
05875          for (x=0;x<16;x++)
05876             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05877          if (!strcasecmp(requeststr, md5secret))
05878             break;
05879       }
05880       if (tmppw) {
05881          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05882       } else {
05883          if (authdebug)
05884             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05885          goto return_unref;
05886       }
05887    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05888       /* They've provided a plain text password and we support that */
05889       if (strcmp(secret, p->secret)) {
05890          if (authdebug)
05891             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05892          goto return_unref;
05893       } else
05894          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05895    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
05896       /* if challenge has been sent, but no challenge response if given, reject. */
05897       goto return_unref;
05898    }
05899    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05900 
05901    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
05902    res = 0;
05903 return_unref:
05904 
05905    if (iaxs[callno]) {
05906       ast_string_field_set(iaxs[callno], peer, peer);
05907 
05908       /* Choose lowest expiry number */
05909       if (expire && (expire < iaxs[callno]->expiry)) {
05910          iaxs[callno]->expiry = expire;
05911       }
05912    }
05913 
05914    if (p) {
05915       peer_unref(p);
05916    }
05917    return res;
05918 }
05919 
05920 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
05921 {
05922    int res = -1;
05923    int x;
05924    if (!ast_strlen_zero(keyn)) {
05925       if (!(authmethods & IAX_AUTH_RSA)) {
05926          if (ast_strlen_zero(secret)) 
05927             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));
05928       } else if (ast_strlen_zero(challenge)) {
05929          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05930       } else {
05931          char sig[256];
05932          struct ast_key *key;
05933          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05934          if (!key) {
05935             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05936          } else {
05937             if (ast_sign(key, (char*)challenge, sig)) {
05938                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05939                res = -1;
05940             } else {
05941                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05942                res = 0;
05943             }
05944          }
05945       }
05946    } 
05947    /* Fall back */
05948    if (res && !ast_strlen_zero(secret)) {
05949       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05950          struct MD5Context md5;
05951          unsigned char digest[16];
05952          char digres[128];
05953          MD5Init(&md5);
05954          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05955          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05956          MD5Final(digest, &md5);
05957          /* If they support md5, authenticate with it.  */
05958          for (x=0;x<16;x++)
05959             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05960          if (pvt) {
05961             build_encryption_keys(digest, pvt);
05962          }
05963          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05964          res = 0;
05965       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05966          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05967          res = 0;
05968       } else
05969          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05970    }
05971    return res;
05972 }
05973 
05974 /*!
05975  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05976  *       so do not call this function with a pvt lock held.
05977  */
05978 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05979 {
05980    struct iax2_peer *peer = NULL;
05981    /* Start pessimistic */
05982    int res = -1;
05983    int authmethods = 0;
05984    struct iax_ie_data ied;
05985    uint16_t callno = p->callno;
05986 
05987    memset(&ied, 0, sizeof(ied));
05988    
05989    if (ies->username)
05990       ast_string_field_set(p, username, ies->username);
05991    if (ies->challenge)
05992       ast_string_field_set(p, challenge, ies->challenge);
05993    if (ies->authmethods)
05994       authmethods = ies->authmethods;
05995    if (authmethods & IAX_AUTH_MD5)
05996       merge_encryption(p, ies->encmethods);
05997    else
05998       p->encmethods = 0;
05999 
06000    /* Check for override RSA authentication first */
06001    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06002       /* Normal password authentication */
06003       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06004    } else {
06005       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06006       while ((peer = ao2_iterator_next(&i))) {
06007          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
06008              /* No peer specified at our end, or this is the peer */
06009              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06010              /* No username specified in peer rule, or this is the right username */
06011              && (!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)))
06012              /* No specified host, or this is our host */
06013             ) {
06014             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06015             if (!res) {
06016                peer_unref(peer);
06017                break;
06018             }
06019          }
06020          peer_unref(peer);
06021       }
06022       if (!peer) {
06023          /* We checked our list and didn't find one.  It's unlikely, but possible, 
06024             that we're trying to authenticate *to* a realtime peer */
06025          const char *peer_name = ast_strdupa(p->peer);
06026          ast_mutex_unlock(&iaxsl[callno]);
06027          if ((peer = realtime_peer(peer_name, NULL))) {
06028             ast_mutex_lock(&iaxsl[callno]);
06029             if (!(p = iaxs[callno])) {
06030                peer_unref(peer);
06031                return -1;
06032             }
06033             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06034             peer_unref(peer);
06035          }
06036          if (!peer) {
06037             ast_mutex_lock(&iaxsl[callno]);
06038             if (!(p = iaxs[callno]))
06039                return -1;
06040          }
06041       }
06042    }
06043    if (ies->encmethods)
06044       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06045    if (!res)
06046       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06047    return res;
06048 }
06049 
06050 static int iax2_do_register(struct iax2_registry *reg);
06051 
06052 static void __iax2_do_register_s(const void *data)
06053 {
06054    struct iax2_registry *reg = (struct iax2_registry *)data;
06055    reg->expire = -1;
06056    iax2_do_register(reg);
06057 }
06058 
06059 static int iax2_do_register_s(const void *data)
06060 {
06061 #ifdef SCHED_MULTITHREADED
06062    if (schedule_action(__iax2_do_register_s, data))
06063 #endif      
06064       __iax2_do_register_s(data);
06065    return 0;
06066 }
06067 
06068 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06069 {
06070    int newcall = 0;
06071    char newip[256];
06072    struct iax_ie_data ied;
06073    struct sockaddr_in new;
06074    
06075    
06076    memset(&ied, 0, sizeof(ied));
06077    if (ies->apparent_addr)
06078       bcopy(ies->apparent_addr, &new, sizeof(new));
06079    if (ies->callno)
06080       newcall = ies->callno;
06081    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
06082       ast_log(LOG_WARNING, "Invalid transfer request\n");
06083       return -1;
06084    }
06085    pvt->transfercallno = newcall;
06086    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
06087    inet_aton(newip, &pvt->transfer.sin_addr);
06088    pvt->transfer.sin_family = AF_INET;
06089    pvt->transferring = TRANSFER_BEGIN;
06090    pvt->transferid = ies->transferid;
06091    store_by_transfercallno(pvt);
06092    if (ies->transferid)
06093       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
06094    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
06095    return 0;
06096 }
06097 
06098 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06099 {
06100    char exten[256] = "";
06101    int status = CACHE_FLAG_UNKNOWN;
06102    int expiry = iaxdefaultdpcache;
06103    int x;
06104    int matchmore = 0;
06105    struct iax2_dpcache *dp, *prev;
06106    
06107    if (ies->called_number)
06108       ast_copy_string(exten, ies->called_number, sizeof(exten));
06109 
06110    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
06111       status = CACHE_FLAG_EXISTS;
06112    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
06113       status = CACHE_FLAG_CANEXIST;
06114    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
06115       status = CACHE_FLAG_NONEXISTENT;
06116 
06117    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
06118       /* Don't really do anything with this */
06119    }
06120    if (ies->refresh)
06121       expiry = ies->refresh;
06122    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
06123       matchmore = CACHE_FLAG_MATCHMORE;
06124    ast_mutex_lock(&dpcache_lock);
06125    prev = NULL;
06126    dp = pvt->dpentries;
06127    while(dp) {
06128       if (!strcmp(dp->exten, exten)) {
06129          /* Let them go */
06130          if (prev)
06131             prev->peer = dp->peer;
06132          else
06133             pvt->dpentries = dp->peer;
06134          dp->peer = NULL;
06135          dp->callno = 0;
06136          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06137          if (dp->flags & CACHE_FLAG_PENDING) {
06138             dp->flags &= ~CACHE_FLAG_PENDING;
06139             dp->flags |= status;
06140             dp->flags |= matchmore;
06141          }
06142          /* Wake up waiters */
06143          for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06144             if (dp->waiters[x] > -1) {
06145                if (write(dp->waiters[x], "asdf", 4) < 0) {
06146                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06147                }
06148             }
06149          }
06150       }
06151       prev = dp;
06152       dp = dp->peer;
06153    }
06154    ast_mutex_unlock(&dpcache_lock);
06155    return 0;
06156 }
06157 
06158 static int complete_transfer(int callno, struct iax_ies *ies)
06159 {
06160    int peercallno = 0;
06161    struct chan_iax2_pvt *pvt = iaxs[callno];
06162    struct iax_frame *cur;
06163    jb_frame frame;
06164 
06165    if (ies->callno)
06166       peercallno = ies->callno;
06167 
06168    if (peercallno < 1) {
06169       ast_log(LOG_WARNING, "Invalid transfer request\n");
06170       return -1;
06171    }
06172    remove_by_transfercallno(pvt);
06173    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06174    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06175    /* Reset sequence numbers */
06176    pvt->oseqno = 0;
06177    pvt->rseqno = 0;
06178    pvt->iseqno = 0;
06179    pvt->aseqno = 0;
06180 
06181    if (pvt->peercallno) {
06182       remove_by_peercallno(pvt);
06183    }
06184    pvt->peercallno = peercallno;
06185    /*this is where the transfering call swiches hash tables */
06186    store_by_peercallno(pvt);
06187    pvt->transferring = TRANSFER_NONE;
06188    pvt->svoiceformat = -1;
06189    pvt->voiceformat = 0;
06190    pvt->svideoformat = -1;
06191    pvt->videoformat = 0;
06192    pvt->transfercallno = -1;
06193    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06194    memset(&pvt->offset, 0, sizeof(pvt->offset));
06195    /* reset jitterbuffer */
06196    while(jb_getall(pvt->jb,&frame) == JB_OK)
06197       iax2_frame_free(frame.data);
06198    jb_reset(pvt->jb);
06199    pvt->lag = 0;
06200    pvt->last = 0;
06201    pvt->lastsent = 0;
06202    pvt->nextpred = 0;
06203    pvt->pingtime = DEFAULT_RETRY_TIME;
06204    AST_LIST_LOCK(&iaxq.queue);
06205    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06206       /* We must cancel any packets that would have been transmitted
06207          because now we're talking to someone new.  It's okay, they
06208          were transmitted to someone that didn't care anyway. */
06209       if (callno == cur->callno) 
06210          cur->retries = -1;
06211    }
06212    AST_LIST_UNLOCK(&iaxq.queue);
06213    return 0; 
06214 }
06215 
06216 /*! \brief Acknowledgment received for OUR registration */
06217 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06218 {
06219    struct iax2_registry *reg;
06220    /* Start pessimistic */
06221    char peer[256] = "";
06222    char msgstatus[60];
06223    int refresh = 60;
06224    char ourip[256] = "<Unspecified>";
06225    struct sockaddr_in oldus;
06226    struct sockaddr_in us;
06227    int oldmsgs;
06228 
06229    memset(&us, 0, sizeof(us));
06230    if (ies->apparent_addr)
06231       bcopy(ies->apparent_addr, &us, sizeof(us));
06232    if (ies->username)
06233       ast_copy_string(peer, ies->username, sizeof(peer));
06234    if (ies->refresh)
06235       refresh = ies->refresh;
06236    if (ies->calling_number) {
06237       /* We don't do anything with it really, but maybe we should */
06238    }
06239    reg = iaxs[callno]->reg;
06240    if (!reg) {
06241       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06242       return -1;
06243    }
06244    memcpy(&oldus, &reg->us, sizeof(oldus));
06245    oldmsgs = reg->messages;
06246    if (inaddrcmp(&reg->addr, sin)) {
06247       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06248       return -1;
06249    }
06250    memcpy(&reg->us, &us, sizeof(reg->us));
06251    if (ies->msgcount >= 0)
06252       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
06253    /* always refresh the registration at the interval requested by the server
06254       we are registering to
06255    */
06256    reg->refresh = refresh;
06257    AST_SCHED_DEL(sched, reg->expire);
06258    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06259    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
06260       if (option_verbose > 2) {
06261          if (reg->messages > 255)
06262             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06263          else if (reg->messages > 1)
06264             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06265          else if (reg->messages > 0)
06266             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
06267          else
06268             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
06269          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06270          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06271       }
06272       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06273    }
06274    reg->regstate = REG_STATE_REGISTERED;
06275    return 0;
06276 }
06277 
06278 static int iax2_register(char *value, int lineno)
06279 {
06280    struct iax2_registry *reg;
06281    char copy[256];
06282    char *username, *hostname, *secret;
06283    char *porta;
06284    char *stringp=NULL;
06285    
06286    if (!value)
06287       return -1;
06288    ast_copy_string(copy, value, sizeof(copy));
06289    stringp=copy;
06290    username = strsep(&stringp, "@");
06291    hostname = strsep(&stringp, "@");
06292    if (!hostname) {
06293       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06294       return -1;
06295    }
06296    stringp=username;
06297    username = strsep(&stringp, ":");
06298    secret = strsep(&stringp, ":");
06299    stringp=hostname;
06300    hostname = strsep(&stringp, ":");
06301    porta = strsep(&stringp, ":");
06302    
06303    if (porta && !atoi(porta)) {
06304       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06305       return -1;
06306    }
06307    if (!(reg = ast_calloc(1, sizeof(*reg))))
06308       return -1;
06309    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06310       free(reg);
06311       return -1;
06312    }
06313    ast_copy_string(reg->username, username, sizeof(reg->username));
06314    if (secret)
06315       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06316    reg->expire = -1;
06317    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06318    reg->addr.sin_family = AF_INET;
06319    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06320    AST_LIST_LOCK(&registrations);
06321    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06322    AST_LIST_UNLOCK(&registrations);
06323    
06324    return 0;
06325 }
06326 
06327 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06328 {
06329    char multi[256];
06330    char *stringp, *ext;
06331    if (!ast_strlen_zero(regcontext)) {
06332       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06333       stringp = multi;
06334       while((ext = strsep(&stringp, "&"))) {
06335          if (onoff) {
06336             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06337                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06338                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
06339          } else
06340             ast_context_remove_extension(regcontext, ext, 1, NULL);
06341       }
06342    }
06343 }
06344 static void prune_peers(void);
06345 
06346 static void unlink_peer(struct iax2_peer *peer)
06347 {
06348    if (peer->expire > -1) {
06349       if (!ast_sched_del(sched, peer->expire)) {
06350          peer->expire = -1;
06351          peer_unref(peer);
06352       }
06353    }
06354 
06355    if (peer->pokeexpire > -1) {
06356       if (!ast_sched_del(sched, peer->pokeexpire)) {
06357          peer->pokeexpire = -1;
06358          peer_unref(peer);
06359       }
06360    }
06361 
06362    ao2_unlink(peers, peer);
06363 }
06364 
06365 static void __expire_registry(const void *data)
06366 {
06367    struct iax2_peer *peer = (struct iax2_peer *) data;
06368 
06369    if (!peer)
06370       return;
06371 
06372    peer->expire = -1;
06373 
06374    if (option_debug)
06375       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06376    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06377       realtime_update_peer(peer->name, &peer->addr, 0);
06378    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06379    /* Reset the address */
06380    memset(&peer->addr, 0, sizeof(peer->addr));
06381    /* Reset expiry value */
06382    peer->expiry = min_reg_expire;
06383    if (!ast_test_flag(peer, IAX_TEMPONLY))
06384       ast_db_del("IAX/Registry", peer->name);
06385    register_peer_exten(peer, 0);
06386    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06387    if (iax2_regfunk)
06388       iax2_regfunk(peer->name, 0);
06389 
06390    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06391       unlink_peer(peer);
06392 
06393    peer_unref(peer);
06394 }
06395 
06396 static int expire_registry(const void *data)
06397 {
06398 #ifdef SCHED_MULTITHREADED
06399    if (schedule_action(__expire_registry, data))
06400 #endif      
06401       __expire_registry(data);
06402    return 0;
06403 }
06404 
06405 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06406 
06407 static void reg_source_db(struct iax2_peer *p)
06408 {
06409    char data[80];
06410    struct in_addr in;
06411    char *c, *d;
06412    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06413       c = strchr(data, ':');
06414       if (c) {
06415          *c = '\0';
06416          c++;
06417          if (inet_aton(data, &in)) {
06418             d = strchr(c, ':');
06419             if (d) {
06420                *d = '\0';
06421                d++;
06422                if (option_verbose > 2)
06423                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06424                   ast_inet_ntoa(in), atoi(c), atoi(d));
06425                iax2_poke_peer(p, 0);
06426                p->expiry = atoi(d);
06427                memset(&p->addr, 0, sizeof(p->addr));
06428                p->addr.sin_family = AF_INET;
06429                p->addr.sin_addr = in;
06430                p->addr.sin_port = htons(atoi(c));
06431                if (p->expire > -1) {
06432                   if (!ast_sched_del(sched, p->expire)) {
06433                      p->expire = -1;
06434                      peer_unref(p);
06435                   }
06436                }
06437                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06438                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06439                if (p->expire == -1)
06440                   peer_unref(p);
06441                if (iax2_regfunk)
06442                   iax2_regfunk(p->name, 1);
06443                register_peer_exten(p, 1);
06444             }              
06445                
06446          }
06447       }
06448    }
06449 }
06450 
06451 /*!
06452  * \pre iaxsl[callno] is locked
06453  *
06454  * \note Since this function calls send_command_final(), the pvt struct for
06455  *       the given call number may disappear while executing this function.
06456  */
06457 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06458 {
06459    /* Called from IAX thread only, with proper iaxsl lock */
06460    struct iax_ie_data ied;
06461    struct iax2_peer *p;
06462    int msgcount;
06463    char data[80];
06464    int version;
06465    const char *peer_name;
06466    int res = -1;
06467 
06468    memset(&ied, 0, sizeof(ied));
06469 
06470    peer_name = ast_strdupa(iaxs[callno]->peer);
06471 
06472    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06473    ast_mutex_unlock(&iaxsl[callno]);
06474    if (!(p = find_peer(peer_name, 1))) {
06475       ast_mutex_lock(&iaxsl[callno]);
06476       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06477       return -1;
06478    }
06479    ast_mutex_lock(&iaxsl[callno]);
06480    if (!iaxs[callno])
06481       goto return_unref;
06482 
06483    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06484       if (sin->sin_addr.s_addr) {
06485          time_t nowtime;
06486          time(&nowtime);
06487          realtime_update_peer(peer_name, sin, nowtime);
06488       } else {
06489          realtime_update_peer(peer_name, sin, 0);
06490       }
06491    }
06492    if (inaddrcmp(&p->addr, sin)) {
06493       if (iax2_regfunk)
06494          iax2_regfunk(p->name, 1);
06495       /* Stash the IP address from which they registered */
06496       memcpy(&p->addr, sin, sizeof(p->addr));
06497       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06498       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06499          ast_db_put("IAX/Registry", p->name, data);
06500          if  (option_verbose > 2)
06501             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06502                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06503          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06504          register_peer_exten(p, 1);
06505          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06506       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06507          if  (option_verbose > 2)
06508             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06509                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06510          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06511          register_peer_exten(p, 0);
06512          ast_db_del("IAX/Registry", p->name);
06513          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06514       }
06515       /* Update the host */
06516       /* Verify that the host is really there */
06517       iax2_poke_peer(p, callno);
06518    }     
06519 
06520    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06521    if (!iaxs[callno]) {
06522       res = -1;
06523       goto return_unref;
06524    }
06525 
06526    /* Store socket fd */
06527    p->sockfd = fd;
06528    /* Setup the expiry */
06529    if (p->expire > -1) {
06530       if (!ast_sched_del(sched, p->expire)) {
06531          p->expire = -1;
06532          peer_unref(p);
06533       }
06534    }
06535    /* treat an unspecified refresh interval as the minimum */
06536    if (!refresh)
06537       refresh = min_reg_expire;
06538    if (refresh > max_reg_expire) {
06539       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06540          p->name, max_reg_expire, refresh);
06541       p->expiry = max_reg_expire;
06542    } else if (refresh < min_reg_expire) {
06543       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06544          p->name, min_reg_expire, refresh);
06545       p->expiry = min_reg_expire;
06546    } else {
06547       p->expiry = refresh;
06548    }
06549    if (p->expiry && sin->sin_addr.s_addr) {
06550       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06551       if (p->expire == -1)
06552          peer_unref(p);
06553    }
06554    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06555    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06556    if (sin->sin_addr.s_addr) {
06557       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06558       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06559       if (!ast_strlen_zero(p->mailbox)) {
06560          int new, old;
06561          ast_app_inboxcount(p->mailbox, &new, &old);
06562          if (new > 255)
06563             new = 255;
06564          if (old > 255)
06565             old = 255;
06566          msgcount = (old << 8) | new;
06567          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06568       }
06569       if (ast_test_flag(p, IAX_HASCALLERID)) {
06570          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06571          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06572       }
06573    }
06574    version = iax_check_version(devtype);
06575    if (version) 
06576       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06577 
06578    res = 0;
06579 
06580 return_unref:
06581    peer_unref(p);
06582 
06583    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06584 }
06585 
06586 static int registry_authrequest(int callno)
06587 {
06588    struct iax_ie_data ied;
06589    struct iax2_peer *p;
06590    char challenge[10];
06591    const char *peer_name;
06592    int sentauthmethod;
06593 
06594    peer_name = ast_strdupa(iaxs[callno]->peer);
06595 
06596    /* SLD: third call to find_peer in registration */
06597    ast_mutex_unlock(&iaxsl[callno]);
06598    if ((p = find_peer(peer_name, 1))) {
06599       last_authmethod = p->authmethods;
06600    }
06601 
06602    ast_mutex_lock(&iaxsl[callno]);
06603    if (!iaxs[callno])
06604       goto return_unref;
06605 
06606    memset(&ied, 0, sizeof(ied));
06607    /* The selection of which delayed reject is sent may leak information,
06608     * if it sets a static response.  For example, if a host is known to only
06609     * use MD5 authentication, then an RSA response would indicate that the
06610     * peer does not exist, and vice-versa.
06611     * Therefore, we use whatever the last peer used (which may vary over the
06612     * course of a server, which should leak minimal information). */
06613    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06614    if (!p) {
06615       iaxs[callno]->authmethods = sentauthmethod;
06616    }
06617    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06618    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06619       /* Build the challenge */
06620       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06621       ast_string_field_set(iaxs[callno], challenge, challenge);
06622       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06623    }
06624    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06625 
06626 return_unref:
06627    if (p) {
06628       peer_unref(p);
06629    }
06630 
06631    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06632 }
06633 
06634 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06635 {
06636    struct iax2_registry *reg;
06637    /* Start pessimistic */
06638    struct iax_ie_data ied;
06639    char peer[256] = "";
06640    char challenge[256] = "";
06641    int res;
06642    int authmethods = 0;
06643    if (ies->authmethods)
06644       authmethods = ies->authmethods;
06645    if (ies->username)
06646       ast_copy_string(peer, ies->username, sizeof(peer));
06647    if (ies->challenge)
06648       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06649    memset(&ied, 0, sizeof(ied));
06650    reg = iaxs[callno]->reg;
06651    if (reg) {
06652          if (inaddrcmp(&reg->addr, sin)) {
06653             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06654             return -1;
06655          }
06656          if (ast_strlen_zero(reg->secret)) {
06657             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06658             reg->regstate = REG_STATE_NOAUTH;
06659             return -1;
06660          }
06661          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06662          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06663          if (reg->secret[0] == '[') {
06664             char tmpkey[256];
06665             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06666             tmpkey[strlen(tmpkey) - 1] = '\0';
06667             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
06668          } else
06669             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
06670          if (!res) {
06671             reg->regstate = REG_STATE_AUTHSENT;
06672             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06673          } else
06674             return -1;
06675          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06676    } else   
06677       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06678    return -1;
06679 }
06680 
06681 static void stop_stuff(int callno)
06682 {
06683    iax2_destroy_helper(iaxs[callno]);
06684 }
06685 
06686 static void __auth_reject(const void *nothing)
06687 {
06688    /* Called from IAX thread only, without iaxs lock */
06689    int callno = (int)(long)(nothing);
06690    struct iax_ie_data ied;
06691    ast_mutex_lock(&iaxsl[callno]);
06692    if (iaxs[callno]) {
06693       memset(&ied, 0, sizeof(ied));
06694       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06695          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06696          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06697       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06698          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06699          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06700       }
06701       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06702    }
06703    ast_mutex_unlock(&iaxsl[callno]);
06704 }
06705 
06706 static int auth_reject(const void *data)
06707 {
06708    int callno = (int)(long)(data);
06709    ast_mutex_lock(&iaxsl[callno]);
06710    if (iaxs[callno])
06711       iaxs[callno]->authid = -1;
06712    ast_mutex_unlock(&iaxsl[callno]);
06713 #ifdef SCHED_MULTITHREADED
06714    if (schedule_action(__auth_reject, data))
06715 #endif      
06716       __auth_reject(data);
06717    return 0;
06718 }
06719 
06720 static int auth_fail(int callno, int failcode)
06721 {
06722    /* Schedule sending the authentication failure in one second, to prevent
06723       guessing */
06724    if (iaxs[callno]) {
06725       iaxs[callno]->authfail = failcode;
06726       if (delayreject) {
06727          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06728          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06729       } else
06730          auth_reject((void *)(long)callno);
06731    }
06732    return 0;
06733 }
06734 
06735 static void __auto_hangup(const void *nothing)
06736 {
06737    /* Called from IAX thread only, without iaxs lock */
06738    int callno = (int)(long)(nothing);
06739    struct iax_ie_data ied;
06740    ast_mutex_lock(&iaxsl[callno]);
06741    if (iaxs[callno]) {
06742       memset(&ied, 0, sizeof(ied));
06743       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06744       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06745       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06746    }
06747    ast_mutex_unlock(&iaxsl[callno]);
06748 }
06749 
06750 static int auto_hangup(const void *data)
06751 {
06752    int callno = (int)(long)(data);
06753    ast_mutex_lock(&iaxsl[callno]);
06754    if (iaxs[callno]) {
06755       iaxs[callno]->autoid = -1;
06756    }
06757    ast_mutex_unlock(&iaxsl[callno]);
06758 #ifdef SCHED_MULTITHREADED
06759    if (schedule_action(__auto_hangup, data))
06760 #endif      
06761       __auto_hangup(data);
06762    return 0;
06763 }
06764 
06765 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06766 {
06767    struct iax_ie_data ied;
06768    /* Auto-hangup with 30 seconds of inactivity */
06769    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06770    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06771    memset(&ied, 0, sizeof(ied));
06772    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06773    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06774    dp->flags |= CACHE_FLAG_TRANSMITTED;
06775 }
06776 
06777 static int iax2_vnak(int callno)
06778 {
06779    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06780 }
06781 
06782 static void vnak_retransmit(int callno, int last)
06783 {
06784    struct iax_frame *f;
06785 
06786    AST_LIST_LOCK(&iaxq.queue);
06787    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06788       /* Send a copy immediately */
06789       if ((f->callno == callno) && iaxs[f->callno] &&
06790          ((unsigned char ) (f->oseqno - last) < 128) &&
06791          (f->retries >= 0)) {
06792          send_packet(f);
06793       }
06794    }
06795    AST_LIST_UNLOCK(&iaxq.queue);
06796 }
06797 
06798 static void __iax2_poke_peer_s(const void *data)
06799 {
06800    struct iax2_peer *peer = (struct iax2_peer *)data;
06801    iax2_poke_peer(peer, 0);
06802    peer_unref(peer);
06803 }
06804 
06805 static int iax2_poke_peer_s(const void *data)
06806 {
06807    struct iax2_peer *peer = (struct iax2_peer *)data;
06808    peer->pokeexpire = -1;
06809 #ifdef SCHED_MULTITHREADED
06810    if (schedule_action(__iax2_poke_peer_s, data))
06811 #endif      
06812       __iax2_poke_peer_s(data);
06813    return 0;
06814 }
06815 
06816 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06817 {
06818    int res = 0;
06819    struct iax_frame *fr;
06820    struct ast_iax2_meta_hdr *meta;
06821    struct ast_iax2_meta_trunk_hdr *mth;
06822    int calls = 0;
06823    
06824    /* Point to frame */
06825    fr = (struct iax_frame *)tpeer->trunkdata;
06826    /* Point to meta data */
06827    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06828    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06829    if (tpeer->trunkdatalen) {
06830       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06831       meta->zeros = 0;
06832       meta->metacmd = IAX_META_TRUNK;
06833       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06834          meta->cmddata = IAX_META_TRUNK_MINI;
06835       else
06836          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06837       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06838       /* And the rest of the ast_iax2 header */
06839       fr->direction = DIRECTION_OUTGRESS;
06840       fr->retrans = -1;
06841       fr->transfer = 0;
06842       /* Any appropriate call will do */
06843       fr->data = fr->afdata;
06844       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06845       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06846       calls = tpeer->calls;
06847 #if 0
06848       if (option_debug)
06849          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));
06850 #endif      
06851       /* Reset transmit trunk side data */
06852       tpeer->trunkdatalen = 0;
06853       tpeer->calls = 0;
06854    }
06855    if (res < 0)
06856       return res;
06857    return calls;
06858 }
06859 
06860 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06861 {
06862    /* Drop when trunk is about 5 seconds idle */
06863    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06864       return 1;
06865    return 0;
06866 }
06867 
06868 static int timing_read(int *id, int fd, short events, void *cbdata)
06869 {
06870    char buf[1024];
06871    int res;
06872    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06873    int processed = 0;
06874    int totalcalls = 0;
06875 #ifdef DAHDI_TIMERACK
06876    int x = 1;
06877 #endif
06878    struct timeval now;
06879    if (iaxtrunkdebug)
06880       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06881    gettimeofday(&now, NULL);
06882    if (events & AST_IO_PRI) {
06883 #ifdef DAHDI_TIMERACK
06884       /* Great, this is a timing interface, just call the ioctl */
06885       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
06886          ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
06887          usleep(1);
06888          return -1;
06889       }
06890 #endif      
06891    } else {
06892       /* Read and ignore from the pseudo channel for timing */
06893       res = read(fd, buf, sizeof(buf));
06894       if (res < 1) {
06895          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06896          return 1;
06897       }
06898    }
06899    /* For each peer that supports trunking... */
06900    ast_mutex_lock(&tpeerlock);
06901    tpeer = tpeers;
06902    while(tpeer) {
06903       processed++;
06904       res = 0;
06905       ast_mutex_lock(&tpeer->lock);
06906       /* We can drop a single tpeer per pass.  That makes all this logic
06907          substantially easier */
06908       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06909          /* Take it out of the list, but don't free it yet, because it
06910             could be in use */
06911          if (prev)
06912             prev->next = tpeer->next;
06913          else
06914             tpeers = tpeer->next;
06915          drop = tpeer;
06916       } else {
06917          res = send_trunk(tpeer, &now);
06918          if (iaxtrunkdebug)
06919             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);
06920       }     
06921       totalcalls += res;   
06922       res = 0;
06923       ast_mutex_unlock(&tpeer->lock);
06924       prev = tpeer;
06925       tpeer = tpeer->next;
06926    }
06927    ast_mutex_unlock(&tpeerlock);
06928    if (drop) {
06929       ast_mutex_lock(&drop->lock);
06930       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06931          because by the time they could get tpeerlock, we've already grabbed it */
06932       if (option_debug)
06933          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06934       if (drop->trunkdata) {
06935          free(drop->trunkdata);
06936          drop->trunkdata = NULL;
06937       }
06938       ast_mutex_unlock(&drop->lock);
06939       ast_mutex_destroy(&drop->lock);
06940       free(drop);
06941       
06942    }
06943    if (iaxtrunkdebug)
06944       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06945    iaxtrunkdebug =0;
06946    return 1;
06947 }
06948 
06949 struct dpreq_data {
06950    int callno;
06951    char context[AST_MAX_EXTENSION];
06952    char callednum[AST_MAX_EXTENSION];
06953    char *callerid;
06954 };
06955 
06956 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06957 {
06958    unsigned short dpstatus = 0;
06959    struct iax_ie_data ied1;
06960    int mm;
06961 
06962    memset(&ied1, 0, sizeof(ied1));
06963    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06964    /* Must be started */
06965    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06966       dpstatus = IAX_DPSTATUS_EXISTS;
06967    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06968       dpstatus = IAX_DPSTATUS_CANEXIST;
06969    } else {
06970       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06971    }
06972    if (ast_ignore_pattern(context, callednum))
06973       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06974    if (mm)
06975       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06976    if (!skiplock)
06977       ast_mutex_lock(&iaxsl[callno]);
06978    if (iaxs[callno]) {
06979       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06980       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06981       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06982       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06983    }
06984    if (!skiplock)
06985       ast_mutex_unlock(&iaxsl[callno]);
06986 }
06987 
06988 static void *dp_lookup_thread(void *data)
06989 {
06990    /* Look up for dpreq */
06991    struct dpreq_data *dpr = data;
06992    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06993    if (dpr->callerid)
06994       free(dpr->callerid);
06995    free(dpr);
06996    return NULL;
06997 }
06998 
06999 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07000 {
07001    pthread_t newthread;
07002    struct dpreq_data *dpr;
07003    pthread_attr_t attr;
07004    
07005    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07006       return;
07007 
07008    pthread_attr_init(&attr);
07009    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
07010 
07011    dpr->callno = callno;
07012    ast_copy_string(dpr->context, context, sizeof(dpr->context));
07013    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07014    if (callerid)
07015       dpr->callerid = ast_strdup(callerid);
07016    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
07017       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07018    }
07019 
07020    pthread_attr_destroy(&attr);
07021 }
07022 
07023 struct iax_dual {
07024    struct ast_channel *chan1;
07025    struct ast_channel *chan2;
07026 };
07027 
07028 static void *iax_park_thread(void *stuff)
07029 {
07030    struct ast_channel *chan1, *chan2;
07031    struct iax_dual *d;
07032    struct ast_frame *f;
07033    int ext;
07034    int res;
07035    d = stuff;
07036    chan1 = d->chan1;
07037    chan2 = d->chan2;
07038    free(d);
07039    f = ast_read(chan1);
07040    if (f)
07041       ast_frfree(f);
07042    res = ast_park_call(chan1, chan2, 0, &ext);
07043    ast_hangup(chan2);
07044    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07045    return NULL;
07046 }
07047 
07048 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07049 {
07050    struct iax_dual *d;
07051    struct ast_channel *chan1m, *chan2m;
07052    pthread_t th;
07053    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07054    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07055    if (chan2m && chan1m) {
07056       /* Make formats okay */
07057       chan1m->readformat = chan1->readformat;
07058       chan1m->writeformat = chan1->writeformat;
07059       ast_channel_masquerade(chan1m, chan1);
07060       /* Setup the extensions and such */
07061       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
07062       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
07063       chan1m->priority = chan1->priority;
07064       
07065       /* We make a clone of the peer channel too, so we can play
07066          back the announcement */
07067       /* Make formats okay */
07068       chan2m->readformat = chan2->readformat;
07069       chan2m->writeformat = chan2->writeformat;
07070       ast_channel_masquerade(chan2m, chan2);
07071       /* Setup the extensions and such */
07072       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
07073       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
07074       chan2m->priority = chan2->priority;
07075       if (ast_do_masquerade(chan2m)) {
07076          ast_log(LOG_WARNING, "Masquerade failed :(\n");
07077          ast_hangup(chan2m);
07078          return -1;
07079       }
07080    } else {
07081       if (chan1m)
07082          ast_hangup(chan1m);
07083       if (chan2m)
07084          ast_hangup(chan2m);
07085       return -1;
07086    }
07087    if ((d = ast_calloc(1, sizeof(*d)))) {
07088       pthread_attr_t attr;
07089 
07090       pthread_attr_init(&attr);
07091       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07092 
07093       d->chan1 = chan1m;
07094       d->chan2 = chan2m;
07095       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
07096          pthread_attr_destroy(&attr);
07097          return 0;
07098       }
07099       pthread_attr_destroy(&attr);
07100       free(d);
07101    }
07102    return -1;
07103 }
07104 
07105 
07106 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
07107 
07108 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
07109 {
07110    unsigned int ourver;
07111    char rsi[80];
07112    snprintf(rsi, sizeof(rsi), "si-%s", si);
07113    if (iax_provision_version(&ourver, rsi, 1))
07114       return 0;
07115    if (option_debug)
07116       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
07117    if (ourver != ver) 
07118       iax2_provision(sin, sockfd, NULL, rsi, 1);
07119    return 0;
07120 }
07121 
07122 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
07123 {
07124    jb_info stats;
07125    jb_getinfo(pvt->jb, &stats);
07126    
07127    memset(iep, 0, sizeof(*iep));
07128 
07129    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
07130    if(stats.frames_in == 0) stats.frames_in = 1;
07131    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
07132    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
07133    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
07134    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
07135    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07136 }
07137 
07138 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
07139 {
07140    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07141    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07142    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07143    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07144    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07145    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07146    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07147 }
07148 
07149 static int socket_process(struct iax2_thread *thread);
07150 
07151 /*!
07152  * \brief Handle any deferred full frames for this thread
07153  */
07154 static void handle_deferred_full_frames(struct iax2_thread *thread)
07155 {
07156    struct iax2_pkt_buf *pkt_buf;
07157 
07158    ast_mutex_lock(&thread->lock);
07159 
07160    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07161       ast_mutex_unlock(&thread->lock);
07162 
07163       thread->buf = pkt_buf->buf;
07164       thread->buf_len = pkt_buf->len;
07165       thread->buf_size = pkt_buf->len + 1;
07166       
07167       socket_process(thread);
07168 
07169       thread->buf = NULL;
07170       ast_free(pkt_buf);
07171 
07172       ast_mutex_lock(&thread->lock);
07173    }
07174 
07175    ast_mutex_unlock(&thread->lock);
07176 }
07177 
07178 /*!
07179  * \brief Queue the last read full frame for processing by a certain thread
07180  *
07181  * If there are already any full frames queued, they are sorted
07182  * by sequence number.
07183  */
07184 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07185 {
07186    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07187    struct ast_iax2_full_hdr *fh, *cur_fh;
07188 
07189    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07190       return;
07191 
07192    pkt_buf->len = from_here->buf_len;
07193    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07194 
07195    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07196    ast_mutex_lock(&to_here->lock);
07197    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07198       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07199       if (fh->oseqno < cur_fh->oseqno) {
07200          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
07201          break;
07202       }
07203    }
07204    AST_LIST_TRAVERSE_SAFE_END
07205 
07206    if (!cur_pkt_buf)
07207       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07208    
07209    ast_mutex_unlock(&to_here->lock);
07210 }
07211 
07212 static int socket_read(int *id, int fd, short events, void *cbdata)
07213 {
07214    struct iax2_thread *thread;
07215    socklen_t len;
07216    time_t t;
07217    static time_t last_errtime = 0;
07218    struct ast_iax2_full_hdr *fh;
07219 
07220    if (!(thread = find_idle_thread())) {
07221       time(&t);
07222       if (t != last_errtime && option_debug)
07223          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
07224       last_errtime = t;
07225       usleep(1);
07226       return 1;
07227    }
07228 
07229    len = sizeof(thread->iosin);
07230    thread->iofd = fd;
07231    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07232    thread->buf_size = sizeof(thread->readbuf);
07233    thread->buf = thread->readbuf;
07234    if (thread->buf_len < 0) {
07235       if (errno != ECONNREFUSED && errno != EAGAIN)
07236          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07237       handle_error();
07238       thread->iostate = IAX_IOSTATE_IDLE;
07239       signal_condition(&thread->lock, &thread->cond);
07240       return 1;
07241    }
07242    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
07243       thread->iostate = IAX_IOSTATE_IDLE;
07244       signal_condition(&thread->lock, &thread->cond);
07245       return 1;
07246    }
07247    
07248    /* Determine if this frame is a full frame; if so, and any thread is currently
07249       processing a full frame for the same callno from this peer, then drop this
07250       frame (and the peer will retransmit it) */
07251    fh = (struct ast_iax2_full_hdr *) thread->buf;
07252    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
07253       struct iax2_thread *cur = NULL;
07254       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
07255       
07256       AST_LIST_LOCK(&active_list);
07257       AST_LIST_TRAVERSE(&active_list, cur, list) {
07258          if ((cur->ffinfo.callno == callno) &&
07259              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
07260             break;
07261       }
07262       if (cur) {
07263          /* we found another thread processing a full frame for this call,
07264             so queue it up for processing later. */
07265          defer_full_frame(thread, cur);
07266          AST_LIST_UNLOCK(&active_list);
07267          thread->iostate = IAX_IOSTATE_IDLE;
07268          signal_condition(&thread->lock, &thread->cond);
07269          return 1;
07270       } else {
07271          /* this thread is going to process this frame, so mark it */
07272          thread->ffinfo.callno = callno;
07273          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
07274          thread->ffinfo.type = fh->type;
07275          thread->ffinfo.csub = fh->csub;
07276       }
07277       AST_LIST_UNLOCK(&active_list);
07278    }
07279    
07280    /* Mark as ready and send on its way */
07281    thread->iostate = IAX_IOSTATE_READY;
07282 #ifdef DEBUG_SCHED_MULTITHREAD
07283    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07284 #endif
07285    signal_condition(&thread->lock, &thread->cond);
07286 
07287    return 1;
07288 }
07289 
07290 static int socket_process(struct iax2_thread *thread)
07291 {
07292    struct sockaddr_in sin;
07293    int res;
07294    int updatehistory=1;
07295    int new = NEW_PREVENT;
07296    void *ptr;
07297    int dcallno = 0;
07298    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07299    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07300    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07301    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07302    struct ast_iax2_meta_trunk_hdr *mth;
07303    struct ast_iax2_meta_trunk_entry *mte;
07304    struct ast_iax2_meta_trunk_mini *mtm;
07305    struct iax_frame *fr;
07306    struct iax_frame *cur;
07307    struct ast_frame f = { 0, };
07308    struct ast_channel *c;
07309    struct iax2_dpcache *dp;
07310    struct iax2_peer *peer;
07311    struct iax2_trunk_peer *tpeer;
07312    struct timeval rxtrunktime;
07313    struct iax_ies ies;
07314    struct iax_ie_data ied0, ied1;
07315    int format;
07316    int fd;
07317    int exists;
07318    int minivid = 0;
07319    unsigned int ts;
07320    char empty[32]="";      /* Safety measure */
07321    struct iax_frame *duped_fr;
07322    char host_pref_buf[128];
07323    char caller_pref_buf[128];
07324    struct ast_codec_pref pref;
07325    char *using_prefs = "mine";
07326 
07327    /* allocate an iax_frame with 4096 bytes of data buffer */
07328    fr = alloca(sizeof(*fr) + 4096);
07329    memset(fr, 0, sizeof(*fr));
07330    fr->afdatalen = 4096; /* From alloca() above */
07331 
07332    /* Copy frequently used parameters to the stack */
07333    res = thread->buf_len;
07334    fd = thread->iofd;
07335    memcpy(&sin, &thread->iosin, sizeof(sin));
07336 
07337    if (res < sizeof(*mh)) {
07338       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07339       return 1;
07340    }
07341    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07342       if (res < sizeof(*vh)) {
07343          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));
07344          return 1;
07345       }
07346 
07347       /* This is a video frame, get call number */
07348       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07349       minivid = 1;
07350    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07351       unsigned char metatype;
07352 
07353       if (res < sizeof(*meta)) {
07354          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));
07355          return 1;
07356       }
07357 
07358       /* This is a meta header */
07359       switch(meta->metacmd) {
07360       case IAX_META_TRUNK:
07361          if (res < (sizeof(*meta) + sizeof(*mth))) {
07362             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07363                sizeof(*meta) + sizeof(*mth));
07364             return 1;
07365          }
07366          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07367          ts = ntohl(mth->ts);
07368          metatype = meta->cmddata;
07369          res -= (sizeof(*meta) + sizeof(*mth));
07370          ptr = mth->data;
07371          tpeer = find_tpeer(&sin, fd);
07372          if (!tpeer) {
07373             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));
07374             return 1;
07375          }
07376          tpeer->trunkact = ast_tvnow();
07377          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07378             tpeer->rxtrunktime = tpeer->trunkact;
07379          rxtrunktime = tpeer->rxtrunktime;
07380          ast_mutex_unlock(&tpeer->lock);
07381          while(res >= sizeof(*mte)) {
07382             /* Process channels */
07383             unsigned short callno, trunked_ts, len;
07384 
07385             if (metatype == IAX_META_TRUNK_MINI) {
07386                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07387                ptr += sizeof(*mtm);
07388                res -= sizeof(*mtm);
07389                len = ntohs(mtm->len);
07390                callno = ntohs(mtm->mini.callno);
07391                trunked_ts = ntohs(mtm->mini.ts);
07392             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07393                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07394                ptr += sizeof(*mte);
07395                res -= sizeof(*mte);
07396                len = ntohs(mte->len);
07397                callno = ntohs(mte->callno);
07398                trunked_ts = 0;
07399             } else {
07400                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07401                break;
07402             }
07403             /* Stop if we don't have enough data */
07404             if (len > res)
07405                break;
07406             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07407             if (fr->callno) {
07408                /* If it's a valid call, deliver the contents.  If not, we
07409                   drop it, since we don't have a scallno to use for an INVAL */
07410                /* Process as a mini frame */
07411                memset(&f, 0, sizeof(f));
07412                f.frametype = AST_FRAME_VOICE;
07413                if (iaxs[fr->callno]) {
07414                   if (iaxs[fr->callno]->voiceformat > 0) {
07415                      f.subclass = iaxs[fr->callno]->voiceformat;
07416                      f.datalen = len;
07417                      if (f.datalen >= 0) {
07418                         if (f.datalen)
07419                            f.data = ptr;
07420                         if(trunked_ts) {
07421                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07422                         } else
07423                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07424                         /* Don't pass any packets until we're started */
07425                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07426                            /* Common things */
07427                            f.src = "IAX2";
07428                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07429                               f.samples = ast_codec_get_samples(&f);
07430                            iax_frame_wrap(fr, &f);
07431                            duped_fr = iaxfrdup2(fr);
07432                            if (duped_fr) {
07433                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07434                            }
07435                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07436                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07437                               iaxs[fr->callno]->last = fr->ts;
07438 #if 1
07439                               if (option_debug && iaxdebug)
07440                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07441 #endif
07442                            }
07443                         }
07444                      } else {
07445                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07446                      }
07447                   } else {
07448                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
07449                      iax2_vnak(fr->callno);
07450                   }
07451                }
07452                ast_mutex_unlock(&iaxsl[fr->callno]);
07453             }
07454             ptr += len;
07455             res -= len;
07456          }
07457          
07458       }
07459       return 1;
07460    }
07461 
07462 #ifdef DEBUG_SUPPORT
07463    if (iaxdebug && (res >= sizeof(*fh)))
07464       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07465 #endif
07466    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07467       if (res < sizeof(*fh)) {
07468          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));
07469          return 1;
07470       }
07471 
07472       /* Get the destination call number */
07473       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07474       /* Retrieve the type and subclass */
07475       f.frametype = fh->type;
07476       if (f.frametype == AST_FRAME_VIDEO) {
07477          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07478       } else {
07479          f.subclass = uncompress_subclass(fh->csub);
07480       }
07481 
07482       /* Deal with POKE/PONG without allocating a callno */
07483       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07484          /* Reply back with a PONG, but don't care about the result. */
07485          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1);
07486          return 1;
07487       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07488          /* Ignore */
07489          return 1;
07490       }
07491 
07492       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07493                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07494                          (f.subclass == IAX_COMMAND_REGREL)))
07495          new = NEW_ALLOW;
07496    } else {
07497       /* Don't know anything about it yet */
07498       f.frametype = AST_FRAME_NULL;
07499       f.subclass = 0;
07500    }
07501 
07502    if (!fr->callno) {
07503       int check_dcallno = 0;
07504 
07505       /*
07506        * We enforce accurate destination call numbers for all full frames except
07507        * LAGRQ and PING commands.  This is because older versions of Asterisk
07508        * schedule these commands to get sent very quickly, and they will sometimes
07509        * be sent before they receive the first frame from the other side.  When
07510        * that happens, it doesn't contain the destination call number.  However,
07511        * not checking it for these frames is safe.
07512        * 
07513        * Discussed in the following thread:
07514        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07515        */
07516 
07517       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07518          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07519       }
07520 
07521       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07522    }
07523 
07524    if (fr->callno > 0)
07525       ast_mutex_lock(&iaxsl[fr->callno]);
07526 
07527    if (!fr->callno || !iaxs[fr->callno]) {
07528       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07529          frame, reply with an inval */
07530       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07531          /* We can only raw hangup control frames */
07532          if (((f.subclass != IAX_COMMAND_INVAL) &&
07533              (f.subclass != IAX_COMMAND_TXCNT) &&
07534              (f.subclass != IAX_COMMAND_TXACC) &&
07535              (f.subclass != IAX_COMMAND_FWDOWNL))||
07536              (f.frametype != AST_FRAME_IAX))
07537             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07538             fd);
07539       }
07540       if (fr->callno > 0) 
07541          ast_mutex_unlock(&iaxsl[fr->callno]);
07542       return 1;
07543    }
07544    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07545       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07546          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07547          ast_mutex_unlock(&iaxsl[fr->callno]);
07548          return 1;
07549       }
07550 #ifdef DEBUG_SUPPORT
07551       else if (iaxdebug)
07552          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07553 #endif
07554    }
07555 
07556    /* count this frame */
07557    iaxs[fr->callno]->frames_received++;
07558 
07559    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07560       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07561       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07562       unsigned short new_peercallno;
07563 
07564       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07565       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07566          if (iaxs[fr->callno]->peercallno) {
07567             remove_by_peercallno(iaxs[fr->callno]);
07568          }
07569          iaxs[fr->callno]->peercallno = new_peercallno;
07570          store_by_peercallno(iaxs[fr->callno]);
07571       }
07572    }
07573    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07574       if (option_debug  && iaxdebug)
07575          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07576       /* Check if it's out of order (and not an ACK or INVAL) */
07577       fr->oseqno = fh->oseqno;
07578       fr->iseqno = fh->iseqno;
07579       fr->ts = ntohl(fh->ts);
07580 #ifdef IAXTESTS
07581       if (test_resync) {
07582          if (option_debug)
07583             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07584          fr->ts += test_resync;
07585       }
07586 #endif /* IAXTESTS */
07587 #if 0
07588       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07589            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07590                         (f.subclass == IAX_COMMAND_NEW ||
07591                          f.subclass == IAX_COMMAND_AUTHREQ ||
07592                          f.subclass == IAX_COMMAND_ACCEPT ||
07593                          f.subclass == IAX_COMMAND_REJECT))      ) )
07594 #endif
07595       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07596          updatehistory = 0;
07597       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07598          (iaxs[fr->callno]->iseqno ||
07599             ((f.subclass != IAX_COMMAND_TXCNT) &&
07600             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07601             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07602             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07603             (f.subclass != IAX_COMMAND_TXACC)) ||
07604             (f.frametype != AST_FRAME_IAX))) {
07605          if (
07606           ((f.subclass != IAX_COMMAND_ACK) &&
07607            (f.subclass != IAX_COMMAND_INVAL) &&
07608            (f.subclass != IAX_COMMAND_TXCNT) &&
07609            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07610            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07611            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07612            (f.subclass != IAX_COMMAND_TXACC) &&
07613            (f.subclass != IAX_COMMAND_VNAK)) ||
07614            (f.frametype != AST_FRAME_IAX)) {
07615             /* If it's not an ACK packet, it's out of order. */
07616             if (option_debug)
07617                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07618                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07619             /* Check to see if we need to request retransmission,
07620              * and take sequence number wraparound into account */
07621             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07622                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07623                if ((f.frametype != AST_FRAME_IAX) || 
07624                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07625                   if (option_debug)
07626                      ast_log(LOG_DEBUG, "Acking anyway\n");
07627                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07628                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07629                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07630                }
07631             } else {
07632                /* Send a VNAK requesting retransmission */
07633                iax2_vnak(fr->callno);
07634             }
07635             ast_mutex_unlock(&iaxsl[fr->callno]);
07636             return 1;
07637          }
07638       } else {
07639          /* Increment unless it's an ACK or VNAK */
07640          if (((f.subclass != IAX_COMMAND_ACK) &&
07641              (f.subclass != IAX_COMMAND_INVAL) &&
07642              (f.subclass != IAX_COMMAND_TXCNT) &&
07643              (f.subclass != IAX_COMMAND_TXACC) &&
07644             (f.subclass != IAX_COMMAND_VNAK)) ||
07645              (f.frametype != AST_FRAME_IAX))
07646             iaxs[fr->callno]->iseqno++;
07647       }
07648       /* A full frame */
07649       if (res < sizeof(*fh)) {
07650          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07651          ast_mutex_unlock(&iaxsl[fr->callno]);
07652          return 1;
07653       }
07654       /* Ensure text frames are NULL-terminated */
07655       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07656          if (res < thread->buf_size)
07657             thread->buf[res++] = '\0';
07658          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07659             thread->buf[res - 1] = '\0';
07660       }
07661       f.datalen = res - sizeof(*fh);
07662 
07663       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07664          from the real peer, not the transfer peer */
07665       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07666           ((f.subclass != IAX_COMMAND_INVAL) ||
07667            (f.frametype != AST_FRAME_IAX))) {
07668          unsigned char x;
07669          int call_to_destroy;
07670          /* XXX This code is not very efficient.  Surely there is a better way which still
07671                 properly handles boundary conditions? XXX */
07672          /* First we have to qualify that the ACKed value is within our window */
07673          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07674             if (fr->iseqno == x)
07675                break;
07676          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07677             /* The acknowledgement is within our window.  Time to acknowledge everything
07678                that it says to */
07679             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07680                /* Ack the packet with the given timestamp */
07681                if (option_debug && iaxdebug)
07682                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07683                call_to_destroy = 0;
07684                AST_LIST_LOCK(&iaxq.queue);
07685                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07686                   /* If it's our call, and our timestamp, mark -1 retries */
07687                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07688                      cur->retries = -1;
07689                      /* Destroy call if this is the end */
07690                      if (cur->final)
07691                         call_to_destroy = fr->callno;
07692                   }
07693                }
07694                AST_LIST_UNLOCK(&iaxq.queue);
07695                if (call_to_destroy) {
07696                   if (iaxdebug && option_debug)
07697                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07698                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07699                   iax2_destroy(call_to_destroy);
07700                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07701                }
07702             }
07703             /* Note how much we've received acknowledgement for */
07704             if (iaxs[fr->callno])
07705                iaxs[fr->callno]->rseqno = fr->iseqno;
07706             else {
07707                /* Stop processing now */
07708                ast_mutex_unlock(&iaxsl[fr->callno]);
07709                return 1;
07710             }
07711          } else if (option_debug)
07712             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07713       }
07714       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07715          ((f.frametype != AST_FRAME_IAX) || 
07716           ((f.subclass != IAX_COMMAND_TXACC) &&
07717            (f.subclass != IAX_COMMAND_TXCNT)))) {
07718          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07719          ast_mutex_unlock(&iaxsl[fr->callno]);
07720          return 1;
07721       }
07722 
07723       if (f.datalen) {
07724          if (f.frametype == AST_FRAME_IAX) {
07725             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07726                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07727                ast_mutex_unlock(&iaxsl[fr->callno]);
07728                return 1;
07729             }
07730             f.data = NULL;
07731             f.datalen = 0;
07732          } else
07733             f.data = thread->buf + sizeof(*fh);
07734       } else {
07735          if (f.frametype == AST_FRAME_IAX)
07736             f.data = NULL;
07737          else
07738             f.data = empty;
07739          memset(&ies, 0, sizeof(ies));
07740       }
07741 
07742       /* when we receive the first full frame for a new incoming channel,
07743          it is safe to start the PBX on the channel because we have now
07744          completed a 3-way handshake with the peer */
07745       if ((f.frametype == AST_FRAME_VOICE) ||
07746           (f.frametype == AST_FRAME_VIDEO) ||
07747           (f.frametype == AST_FRAME_IAX)) {
07748          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07749             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07750             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07751                ast_mutex_unlock(&iaxsl[fr->callno]);
07752                return 1;
07753             }
07754          }
07755       }
07756 
07757       if (f.frametype == AST_FRAME_VOICE) {
07758          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07759                iaxs[fr->callno]->voiceformat = f.subclass;
07760                if (option_debug)
07761                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07762                if (iaxs[fr->callno]->owner) {
07763                   int orignative;
07764 retryowner:
07765                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07766                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07767                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07768                   }
07769                   if (iaxs[fr->callno]) {
07770                      if (iaxs[fr->callno]->owner) {
07771                         orignative = iaxs[fr->callno]->owner->nativeformats;
07772                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07773                         if (iaxs[fr->callno]->owner->readformat)
07774                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07775                         iaxs[fr->callno]->owner->nativeformats = orignative;
07776                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07777                      }
07778                   } else {
07779                      if (option_debug)
07780                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07781                      ast_mutex_unlock(&iaxsl[fr->callno]);
07782                      return 1;
07783                   }
07784                }
07785          }
07786       }
07787       if (f.frametype == AST_FRAME_VIDEO) {
07788          if (f.subclass != iaxs[fr->callno]->videoformat) {
07789             if (option_debug)
07790                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07791             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07792          }
07793       }
07794       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
07795          if (f.subclass == AST_CONTROL_BUSY) {
07796             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
07797          } else if (f.subclass == AST_CONTROL_CONGESTION) {
07798             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
07799          }
07800       }
07801       if (f.frametype == AST_FRAME_IAX) {
07802          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07803          /* Handle the IAX pseudo frame itself */
07804          if (option_debug && iaxdebug) {
07805             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07806          }
07807 
07808                         /* Update last ts unless the frame's timestamp originated with us. */
07809          if (iaxs[fr->callno]->last < fr->ts &&
07810                             f.subclass != IAX_COMMAND_ACK &&
07811                             f.subclass != IAX_COMMAND_PONG &&
07812                             f.subclass != IAX_COMMAND_LAGRP) {
07813             iaxs[fr->callno]->last = fr->ts;
07814             if (option_debug && iaxdebug) {
07815                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07816             }
07817          }
07818          iaxs[fr->callno]->last_iax_message = f.subclass;
07819          if (!iaxs[fr->callno]->first_iax_message) {
07820             iaxs[fr->callno]->first_iax_message = f.subclass;
07821          }
07822          switch(f.subclass) {
07823          case IAX_COMMAND_ACK:
07824             /* Do nothing */
07825             break;
07826          case IAX_COMMAND_QUELCH:
07827             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07828                     /* Generate Manager Hold event, if necessary*/
07829                if (iaxs[fr->callno]->owner) {
07830                   manager_event(EVENT_FLAG_CALL, "Hold",
07831                      "Channel: %s\r\n"
07832                      "Uniqueid: %s\r\n",
07833                      iaxs[fr->callno]->owner->name, 
07834                      iaxs[fr->callno]->owner->uniqueid);
07835                }
07836 
07837                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07838                if (ies.musiconhold) {
07839                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07840                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07841                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07842                         S_OR(mohsuggest, NULL),
07843                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07844                      if (!iaxs[fr->callno]) {
07845                         ast_mutex_unlock(&iaxsl[fr->callno]);
07846                         return 1;
07847                      }
07848                   }
07849                }
07850             }
07851             break;
07852          case IAX_COMMAND_UNQUELCH:
07853             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07854                     /* Generate Manager Unhold event, if necessary*/
07855                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07856                   manager_event(EVENT_FLAG_CALL, "Unhold",
07857                      "Channel: %s\r\n"
07858                      "Uniqueid: %s\r\n",
07859                      iaxs[fr->callno]->owner->name, 
07860                      iaxs[fr->callno]->owner->uniqueid);
07861                }
07862 
07863                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07864                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07865                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07866                   if (!iaxs[fr->callno]) {
07867                      ast_mutex_unlock(&iaxsl[fr->callno]);
07868                      return 1;
07869                   }
07870                }
07871             }
07872             break;
07873          case IAX_COMMAND_TXACC:
07874             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07875                /* Ack the packet with the given timestamp */
07876                AST_LIST_LOCK(&iaxq.queue);
07877                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07878                   /* Cancel any outstanding txcnt's */
07879                   if ((fr->callno == cur->callno) && (cur->transfer))
07880                      cur->retries = -1;
07881                }
07882                AST_LIST_UNLOCK(&iaxq.queue);
07883                memset(&ied1, 0, sizeof(ied1));
07884                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07885                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07886                iaxs[fr->callno]->transferring = TRANSFER_READY;
07887             }
07888             break;
07889          case IAX_COMMAND_NEW:
07890             /* Ignore if it's already up */
07891             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07892                break;
07893             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07894                ast_mutex_unlock(&iaxsl[fr->callno]);
07895                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07896                ast_mutex_lock(&iaxsl[fr->callno]);
07897                if (!iaxs[fr->callno]) {
07898                   ast_mutex_unlock(&iaxsl[fr->callno]);
07899                   return 1;
07900                }
07901             }
07902             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07903             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07904                int new_callno;
07905                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07906                   fr->callno = new_callno;
07907             }
07908             /* For security, always ack immediately */
07909             if (delayreject)
07910                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07911             if (check_access(fr->callno, &sin, &ies)) {
07912                /* They're not allowed on */
07913                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07914                if (authdebug)
07915                   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);
07916                break;
07917             }
07918             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07919                const char *context, *exten, *cid_num;
07920 
07921                context = ast_strdupa(iaxs[fr->callno]->context);
07922                exten = ast_strdupa(iaxs[fr->callno]->exten);
07923                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07924 
07925                /* This might re-enter the IAX code and need the lock */
07926                ast_mutex_unlock(&iaxsl[fr->callno]);
07927                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07928                ast_mutex_lock(&iaxsl[fr->callno]);
07929 
07930                if (!iaxs[fr->callno]) {
07931                   ast_mutex_unlock(&iaxsl[fr->callno]);
07932                   return 1;
07933                }
07934             } else
07935                exists = 0;
07936             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07937                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07938                   memset(&ied0, 0, sizeof(ied0));
07939                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07940                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07941                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07942                   if (!iaxs[fr->callno]) {
07943                      ast_mutex_unlock(&iaxsl[fr->callno]);
07944                      return 1;
07945                   }
07946                   if (authdebug)
07947                      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);
07948                } else {
07949                   /* Select an appropriate format */
07950 
07951                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07952                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07953                         using_prefs = "reqonly";
07954                      } else {
07955                         using_prefs = "disabled";
07956                      }
07957                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07958                      memset(&pref, 0, sizeof(pref));
07959                      strcpy(caller_pref_buf, "disabled");
07960                      strcpy(host_pref_buf, "disabled");
07961                   } else {
07962                      using_prefs = "mine";
07963                      /* If the information elements are in here... use them */
07964                      if (ies.codec_prefs)
07965                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07966                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07967                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07968                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07969                            pref = iaxs[fr->callno]->rprefs;
07970                            using_prefs = "caller";
07971                         } else {
07972                            pref = iaxs[fr->callno]->prefs;
07973                         }
07974                      } else
07975                         pref = iaxs[fr->callno]->prefs;
07976                      
07977                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07978                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07979                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07980                   }
07981                   if (!format) {
07982                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07983                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07984                      if (!format) {
07985                         memset(&ied0, 0, sizeof(ied0));
07986                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07987                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07988                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07989                         if (!iaxs[fr->callno]) {
07990                            ast_mutex_unlock(&iaxsl[fr->callno]);
07991                            return 1;
07992                         }
07993                         if (authdebug) {
07994                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07995                               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);
07996                            else 
07997                               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);
07998                         }
07999                      } else {
08000                         /* Pick one... */
08001                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08002                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08003                               format = 0;
08004                         } else {
08005                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08006                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08007                               memset(&pref, 0, sizeof(pref));
08008                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08009                               strcpy(caller_pref_buf,"disabled");
08010                               strcpy(host_pref_buf,"disabled");
08011                            } else {
08012                               using_prefs = "mine";
08013                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08014                                  /* Do the opposite of what we tried above. */
08015                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08016                                     pref = iaxs[fr->callno]->prefs;                       
08017                                  } else {
08018                                     pref = iaxs[fr->callno]->rprefs;
08019                                     using_prefs = "caller";
08020                                  }
08021                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08022                            
08023                               } else /* if no codec_prefs IE do it the old way */
08024                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08025                            }
08026                         }
08027 
08028                         if (!format) {
08029                            memset(&ied0, 0, sizeof(ied0));
08030                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08031                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08032                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08033                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08034                            if (!iaxs[fr->callno]) {
08035                               ast_mutex_unlock(&iaxsl[fr->callno]);
08036                               return 1;
08037                            }
08038                            if (authdebug)
08039                               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);
08040                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
08041                            break;
08042                         }
08043                      }
08044                   }
08045                   if (format) {
08046                      /* No authentication required, let them in */
08047                      memset(&ied1, 0, sizeof(ied1));
08048                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08049                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08050                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08051                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08052                         if (option_verbose > 2) 
08053                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
08054                                     "%srequested format = %s,\n"
08055                                     "%srequested prefs = %s,\n"
08056                                     "%sactual format = %s,\n"
08057                                     "%shost prefs = %s,\n"
08058                                     "%spriority = %s\n",
08059                                     ast_inet_ntoa(sin.sin_addr), 
08060                                     VERBOSE_PREFIX_4,
08061                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
08062                                     VERBOSE_PREFIX_4,
08063                                     caller_pref_buf,
08064                                     VERBOSE_PREFIX_4,
08065                                     ast_getformatname(format), 
08066                                     VERBOSE_PREFIX_4,
08067                                     host_pref_buf, 
08068                                     VERBOSE_PREFIX_4,
08069                                     using_prefs);
08070                         
08071                         iaxs[fr->callno]->chosenformat = format;
08072                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08073                      } else {
08074                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08075                         /* If this is a TBD call, we're ready but now what...  */
08076                         if (option_verbose > 2)
08077                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08078                      }
08079                   }
08080                }
08081                break;
08082             }
08083             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
08084                merge_encryption(iaxs[fr->callno],ies.encmethods);
08085             else
08086                iaxs[fr->callno]->encmethods = 0;
08087             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
08088                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
08089             if (!iaxs[fr->callno]) {
08090                ast_mutex_unlock(&iaxsl[fr->callno]);
08091                return 1;
08092             }
08093             break;
08094          case IAX_COMMAND_DPREQ:
08095             /* Request status in the dialplan */
08096             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
08097                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
08098                if (iaxcompat) {
08099                   /* Spawn a thread for the lookup */
08100                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
08101                } else {
08102                   /* Just look it up */
08103                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
08104                }
08105             }
08106             break;
08107          case IAX_COMMAND_HANGUP:
08108             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08109             if (option_debug)
08110                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
08111             /* Set hangup cause according to remote */
08112             if (ies.causecode && iaxs[fr->callno]->owner)
08113                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
08114             /* Send ack immediately, before we destroy */
08115             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08116             iax2_destroy(fr->callno);
08117             break;
08118          case IAX_COMMAND_REJECT:
08119             /* Set hangup cause according to remote */
08120             if (ies.causecode && iaxs[fr->callno]->owner)
08121                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
08122 
08123             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
08124                if (iaxs[fr->callno]->owner && authdebug)
08125                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
08126                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
08127                      ies.cause ? ies.cause : "<Unknown>");
08128                if (option_debug)
08129                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
08130                      fr->callno);
08131             }
08132             /* Send ack immediately, before we destroy */
08133             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
08134                          fr->ts, NULL, 0, fr->iseqno);
08135             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
08136                iaxs[fr->callno]->error = EPERM;
08137             iax2_destroy(fr->callno);
08138             break;
08139          case IAX_COMMAND_TRANSFER:
08140          {
08141             struct ast_channel *bridged_chan;
08142 
08143             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
08144                /* Set BLINDTRANSFER channel variables */
08145 
08146                ast_mutex_unlock(&iaxsl[fr->callno]);
08147                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
08148                ast_mutex_lock(&iaxsl[fr->callno]);
08149                if (!iaxs[fr->callno]) {
08150                   ast_mutex_unlock(&iaxsl[fr->callno]);
08151                   return 1;
08152                }
08153 
08154                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
08155                if (!strcmp(ies.called_number, ast_parking_ext())) {
08156                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
08157                   ast_mutex_unlock(&iaxsl[fr->callno]);
08158                   if (iax_park(bridged_chan, saved_channel)) {
08159                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
08160                   } else {
08161                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
08162                   }
08163                   ast_mutex_lock(&iaxsl[fr->callno]);
08164                } else {
08165                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
08166                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
08167                         ies.called_number, iaxs[fr->callno]->context);
08168                   else
08169                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
08170                         ies.called_number, iaxs[fr->callno]->context);
08171                }
08172             } else
08173                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
08174 
08175             break;
08176          }
08177          case IAX_COMMAND_ACCEPT:
08178             /* Ignore if call is already up or needs authentication or is a TBD */
08179             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
08180                break;
08181             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
08182                /* Send ack immediately, before we destroy */
08183                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08184                iax2_destroy(fr->callno);
08185                break;
08186             }
08187             if (ies.format) {
08188                iaxs[fr->callno]->peerformat = ies.format;
08189             } else {
08190                if (iaxs[fr->callno]->owner)
08191                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
08192                else
08193                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
08194             }
08195             if (option_verbose > 2)
08196                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));
08197             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
08198                memset(&ied0, 0, sizeof(ied0));
08199                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08200                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08201                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08202                if (!iaxs[fr->callno]) {
08203                   ast_mutex_unlock(&iaxsl[fr->callno]);
08204                   return 1;
08205                }
08206                if (authdebug)
08207                   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);
08208             } else {
08209                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08210                if (iaxs[fr->callno]->owner) {
08211                   /* Switch us to use a compatible format */
08212                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
08213                   if (option_verbose > 2)
08214                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
08215 retryowner2:
08216                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08217                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08218                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
08219                   }
08220                   
08221                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
08222                      /* Setup read/write formats properly. */
08223                      if (iaxs[fr->callno]->owner->writeformat)
08224                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
08225                      if (iaxs[fr->callno]->owner->readformat)
08226                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
08227                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08228                   }
08229                }
08230             }
08231             if (iaxs[fr->callno]) {
08232                ast_mutex_lock(&dpcache_lock);
08233                dp = iaxs[fr->callno]->dpentries;
08234                while(dp) {
08235                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
08236                      iax2_dprequest(dp, fr->callno);
08237                   }
08238                   dp = dp->peer;
08239                }
08240                ast_mutex_unlock(&dpcache_lock);
08241             }
08242             break;
08243          case IAX_COMMAND_POKE:
08244             /* Send back a pong packet with the original timestamp */
08245             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
08246             if (!iaxs[fr->callno]) {
08247                ast_mutex_unlock(&iaxsl[fr->callno]);
08248                return 1;
08249             }
08250             break;
08251          case IAX_COMMAND_PING:
08252          {
08253             struct iax_ie_data pingied;
08254             construct_rr(iaxs[fr->callno], &pingied);
08255             /* Send back a pong packet with the original timestamp */
08256             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
08257          }
08258             break;
08259          case IAX_COMMAND_PONG:
08260             /* Calculate ping time */
08261             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
08262             /* save RR info */
08263             save_rr(fr, &ies);
08264 
08265             if (iaxs[fr->callno]->peerpoke) {
08266                peer = iaxs[fr->callno]->peerpoke;
08267                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
08268                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
08269                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
08270                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08271                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08272                   }
08273                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
08274                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
08275                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
08276                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08277                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08278                   }
08279                }
08280                peer->lastms = iaxs[fr->callno]->pingtime;
08281                if (peer->smoothing && (peer->lastms > -1))
08282                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
08283                else if (peer->smoothing && peer->lastms < 0)
08284                   peer->historicms = (0 + peer->historicms) / 2;
08285                else              
08286                   peer->historicms = iaxs[fr->callno]->pingtime;
08287 
08288                /* Remove scheduled iax2_poke_noanswer */
08289                if (peer->pokeexpire > -1) {
08290                   if (!ast_sched_del(sched, peer->pokeexpire)) {
08291                      peer_unref(peer);
08292                      peer->pokeexpire = -1;
08293                   }
08294                }
08295                /* Schedule the next cycle */
08296                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
08297                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08298                else
08299                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08300                if (peer->pokeexpire == -1)
08301                   peer_unref(peer);
08302                /* and finally send the ack */
08303                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08304                /* And wrap up the qualify call */
08305                iax2_destroy(fr->callno);
08306                peer->callno = 0;
08307                if (option_debug)
08308                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08309             }
08310             break;
08311          case IAX_COMMAND_LAGRQ:
08312          case IAX_COMMAND_LAGRP:
08313             f.src = "LAGRQ";
08314             f.mallocd = 0;
08315             f.offset = 0;
08316             f.samples = 0;
08317             iax_frame_wrap(fr, &f);
08318             if(f.subclass == IAX_COMMAND_LAGRQ) {
08319                /* Received a LAGRQ - echo back a LAGRP */
08320                fr->af.subclass = IAX_COMMAND_LAGRP;
08321                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08322             } else {
08323                /* Received LAGRP in response to our LAGRQ */
08324                unsigned int ts;
08325                /* This is a reply we've been given, actually measure the difference */
08326                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08327                iaxs[fr->callno]->lag = ts - fr->ts;
08328                if (option_debug && iaxdebug)
08329                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08330                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08331             }
08332             break;
08333          case IAX_COMMAND_AUTHREQ:
08334             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08335                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>");
08336                break;
08337             }
08338             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08339                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08340                         .subclass = AST_CONTROL_HANGUP,
08341                };
08342                ast_log(LOG_WARNING, 
08343                   "I don't know how to authenticate %s to %s\n", 
08344                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08345                iax2_queue_frame(fr->callno, &hangup_fr);
08346             }
08347             if (!iaxs[fr->callno]) {
08348                ast_mutex_unlock(&iaxsl[fr->callno]);
08349                return 1;
08350             }
08351             break;
08352          case IAX_COMMAND_AUTHREP:
08353             /* For security, always ack immediately */
08354             if (delayreject)
08355                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08356             /* Ignore once we've started */
08357             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08358                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>");
08359                break;
08360             }
08361             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08362                if (authdebug)
08363                   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);
08364                memset(&ied0, 0, sizeof(ied0));
08365                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08366                break;
08367             }
08368             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08369                /* This might re-enter the IAX code and need the lock */
08370                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08371             } else
08372                exists = 0;
08373             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08374                if (authdebug)
08375                   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);
08376                memset(&ied0, 0, sizeof(ied0));
08377                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08378                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08379                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08380                if (!iaxs[fr->callno]) {
08381                   ast_mutex_unlock(&iaxsl[fr->callno]);
08382                   return 1;
08383                }
08384             } else {
08385                /* Select an appropriate format */
08386                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08387                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08388                      using_prefs = "reqonly";
08389                   } else {
08390                      using_prefs = "disabled";
08391                   }
08392                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08393                   memset(&pref, 0, sizeof(pref));
08394                   strcpy(caller_pref_buf, "disabled");
08395                   strcpy(host_pref_buf, "disabled");
08396                } else {
08397                   using_prefs = "mine";
08398                   if (ies.codec_prefs)
08399                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08400                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08401                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08402                         pref = iaxs[fr->callno]->rprefs;
08403                         using_prefs = "caller";
08404                      } else {
08405                         pref = iaxs[fr->callno]->prefs;
08406                      }
08407                   } else /* if no codec_prefs IE do it the old way */
08408                      pref = iaxs[fr->callno]->prefs;
08409                
08410                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08411                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08412                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08413                }
08414                if (!format) {
08415                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08416                      if (option_debug)
08417                         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);
08418                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08419                   }
08420                   if (!format) {
08421                      if (authdebug) {
08422                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08423                            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);
08424                         else
08425                            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);
08426                      }
08427                      memset(&ied0, 0, sizeof(ied0));
08428                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08429                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08430                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08431                      if (!iaxs[fr->callno]) {
08432                         ast_mutex_unlock(&iaxsl[fr->callno]);
08433                         return 1;
08434                      }
08435                   } else {
08436                      /* Pick one... */
08437                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08438                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08439                            format = 0;
08440                      } else {
08441                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08442                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08443                            memset(&pref, 0, sizeof(pref));
08444                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08445                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08446                            strcpy(caller_pref_buf,"disabled");
08447                            strcpy(host_pref_buf,"disabled");
08448                         } else {
08449                            using_prefs = "mine";
08450                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08451                               /* Do the opposite of what we tried above. */
08452                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08453                                  pref = iaxs[fr->callno]->prefs;                 
08454                               } else {
08455                                  pref = iaxs[fr->callno]->rprefs;
08456                                  using_prefs = "caller";
08457                               }
08458                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08459                            } else /* if no codec_prefs IE do it the old way */
08460                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08461                         }
08462                      }
08463                      if (!format) {
08464                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08465                         if (authdebug) {
08466                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08467                               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);
08468                            else
08469                               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);
08470                         }
08471                         memset(&ied0, 0, sizeof(ied0));
08472                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08473                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08474                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08475                         if (!iaxs[fr->callno]) {
08476                            ast_mutex_unlock(&iaxsl[fr->callno]);
08477                            return 1;
08478                         }
08479                      }
08480                   }
08481                }
08482                if (format) {
08483                   /* Authentication received */
08484                   memset(&ied1, 0, sizeof(ied1));
08485                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08486                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08487                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08488                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08489                      if (option_verbose > 2) 
08490                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08491                                  "%srequested format = %s,\n"
08492                                  "%srequested prefs = %s,\n"
08493                                  "%sactual format = %s,\n"
08494                                  "%shost prefs = %s,\n"
08495                                  "%spriority = %s\n", 
08496                                  ast_inet_ntoa(sin.sin_addr), 
08497                                  VERBOSE_PREFIX_4,
08498                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08499                                  VERBOSE_PREFIX_4,
08500                                  caller_pref_buf,
08501                                  VERBOSE_PREFIX_4,
08502                                  ast_getformatname(format),
08503                                  VERBOSE_PREFIX_4,
08504                                  host_pref_buf,
08505                                  VERBOSE_PREFIX_4,
08506                                  using_prefs);
08507 
08508                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08509                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08510                         iax2_destroy(fr->callno);
08511                   } else {
08512                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08513                      /* If this is a TBD call, we're ready but now what...  */
08514                      if (option_verbose > 2)
08515                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08516                   }
08517                }
08518             }
08519             break;
08520          case IAX_COMMAND_DIAL:
08521             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08522                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08523                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08524                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08525                   if (authdebug)
08526                      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);
08527                   memset(&ied0, 0, sizeof(ied0));
08528                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08529                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08530                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08531                   if (!iaxs[fr->callno]) {
08532                      ast_mutex_unlock(&iaxsl[fr->callno]);
08533                      return 1;
08534                   }
08535                } else {
08536                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08537                   if (option_verbose > 2) 
08538                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08539                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08540                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08541                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08542                      iax2_destroy(fr->callno);
08543                }
08544             }
08545             break;
08546          case IAX_COMMAND_INVAL:
08547             iaxs[fr->callno]->error = ENOTCONN;
08548             if (option_debug)
08549                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08550             iax2_destroy(fr->callno);
08551             if (option_debug)
08552                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08553             break;
08554          case IAX_COMMAND_VNAK:
08555             if (option_debug)
08556                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08557             /* Force retransmission */
08558             vnak_retransmit(fr->callno, fr->iseqno);
08559             break;
08560          case IAX_COMMAND_REGREQ:
08561          case IAX_COMMAND_REGREL:
08562             /* For security, always ack immediately */
08563             if (delayreject)
08564                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08565             if (register_verify(fr->callno, &sin, &ies)) {
08566                if (!iaxs[fr->callno]) {
08567                   ast_mutex_unlock(&iaxsl[fr->callno]);
08568                   return 1;
08569                }
08570                /* Send delayed failure */
08571                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08572                break;
08573             }
08574             if (!iaxs[fr->callno]) {
08575                ast_mutex_unlock(&iaxsl[fr->callno]);
08576                return 1;
08577             }
08578             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08579                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
08580 
08581                if (f.subclass == IAX_COMMAND_REGREL)
08582                   memset(&sin, 0, sizeof(sin));
08583                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08584                   ast_log(LOG_WARNING, "Registry error\n");
08585                if (!iaxs[fr->callno]) {
08586                   ast_mutex_unlock(&iaxsl[fr->callno]);
08587                   return 1;
08588                }
08589                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08590                   ast_mutex_unlock(&iaxsl[fr->callno]);
08591                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08592                   ast_mutex_lock(&iaxsl[fr->callno]);
08593                   if (!iaxs[fr->callno]) {
08594                      ast_mutex_unlock(&iaxsl[fr->callno]);
08595                      return 1;
08596                   }
08597                }
08598                break;
08599             }
08600             registry_authrequest(fr->callno);
08601             if (!iaxs[fr->callno]) {
08602                ast_mutex_unlock(&iaxsl[fr->callno]);
08603                return 1;
08604             }
08605             break;
08606          case IAX_COMMAND_REGACK:
08607             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08608                ast_log(LOG_WARNING, "Registration failure\n");
08609             /* Send ack immediately, before we destroy */
08610             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08611             iax2_destroy(fr->callno);
08612             break;
08613          case IAX_COMMAND_REGREJ:
08614             if (iaxs[fr->callno]->reg) {
08615                if (authdebug) {
08616                   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));
08617                   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>");
08618                }
08619                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08620             }
08621             /* Send ack immediately, before we destroy */
08622             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08623             iax2_destroy(fr->callno);
08624             break;
08625          case IAX_COMMAND_REGAUTH:
08626             /* Authentication request */
08627             if (registry_rerequest(&ies, fr->callno, &sin)) {
08628                memset(&ied0, 0, sizeof(ied0));
08629                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08630                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08631                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08632                if (!iaxs[fr->callno]) {
08633                   ast_mutex_unlock(&iaxsl[fr->callno]);
08634                   return 1;
08635                }
08636             }
08637             break;
08638          case IAX_COMMAND_TXREJ:
08639             iaxs[fr->callno]->transferring = 0;
08640             if (option_verbose > 2) 
08641                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08642             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08643             if (iaxs[fr->callno]->bridgecallno) {
08644                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08645                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08646                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08647                }
08648             }
08649             break;
08650          case IAX_COMMAND_TXREADY:
08651             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08652                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08653                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08654                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08655                else
08656                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08657                if (option_verbose > 2) 
08658                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08659                if (iaxs[fr->callno]->bridgecallno) {
08660                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08661                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08662                      /* They're both ready, now release them. */
08663                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08664                         if (option_verbose > 2) 
08665                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08666                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08667 
08668                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08669                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08670 
08671                         memset(&ied0, 0, sizeof(ied0));
08672                         memset(&ied1, 0, sizeof(ied1));
08673                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08674                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08675                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08676                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08677                      } else {
08678                         if (option_verbose > 2) 
08679                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08680                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08681 
08682                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08683                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08684                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08685                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08686 
08687                         /* Stop doing lag & ping requests */
08688                         stop_stuff(fr->callno);
08689                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08690 
08691                         memset(&ied0, 0, sizeof(ied0));
08692                         memset(&ied1, 0, sizeof(ied1));
08693                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08694                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08695                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08696                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08697                      }
08698 
08699                   }
08700                }
08701             }
08702             break;
08703          case IAX_COMMAND_TXREQ:
08704             try_transfer(iaxs[fr->callno], &ies);
08705             break;
08706          case IAX_COMMAND_TXCNT:
08707             if (iaxs[fr->callno]->transferring)
08708                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08709             break;
08710          case IAX_COMMAND_TXREL:
08711             /* Send ack immediately, rather than waiting until we've changed addresses */
08712             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08713             complete_transfer(fr->callno, &ies);
08714             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08715             break;   
08716          case IAX_COMMAND_TXMEDIA:
08717             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08718                                         AST_LIST_LOCK(&iaxq.queue);
08719                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08720                                                 /* Cancel any outstanding frames and start anew */
08721                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08722                                                         cur->retries = -1;
08723                                                 }
08724                                         }
08725                                         AST_LIST_UNLOCK(&iaxq.queue);
08726                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08727                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08728             }
08729             break;   
08730          case IAX_COMMAND_DPREP:
08731             complete_dpreply(iaxs[fr->callno], &ies);
08732             break;
08733          case IAX_COMMAND_UNSUPPORT:
08734             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08735             break;
08736          case IAX_COMMAND_FWDOWNL:
08737             /* Firmware download */
08738             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08739                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08740                break;
08741             }
08742             memset(&ied0, 0, sizeof(ied0));
08743             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08744             if (res < 0)
08745                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08746             else if (res > 0)
08747                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08748             else
08749                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08750             if (!iaxs[fr->callno]) {
08751                ast_mutex_unlock(&iaxsl[fr->callno]);
08752                return 1;
08753             }
08754             break;
08755          default:
08756             if (option_debug)
08757                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08758             memset(&ied0, 0, sizeof(ied0));
08759             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08760             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08761          }
08762          /* Don't actually pass these frames along */
08763          if ((f.subclass != IAX_COMMAND_ACK) && 
08764            (f.subclass != IAX_COMMAND_TXCNT) && 
08765            (f.subclass != IAX_COMMAND_TXACC) && 
08766            (f.subclass != IAX_COMMAND_INVAL) &&
08767            (f.subclass != IAX_COMMAND_VNAK)) { 
08768             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08769                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08770          }
08771          ast_mutex_unlock(&iaxsl[fr->callno]);
08772          return 1;
08773       }
08774       /* Unless this is an ACK or INVAL frame, ack it */
08775       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08776          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08777    } else if (minivid) {
08778       f.frametype = AST_FRAME_VIDEO;
08779       if (iaxs[fr->callno]->videoformat > 0) 
08780          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08781       else {
08782          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
08783          iax2_vnak(fr->callno);
08784          ast_mutex_unlock(&iaxsl[fr->callno]);
08785          return 1;
08786       }
08787       f.datalen = res - sizeof(*vh);
08788       if (f.datalen)
08789          f.data = thread->buf + sizeof(*vh);
08790       else
08791          f.data = NULL;
08792 #ifdef IAXTESTS
08793       if (test_resync) {
08794          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08795       } else
08796 #endif /* IAXTESTS */
08797          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08798    } else {
08799       /* A mini frame */
08800       f.frametype = AST_FRAME_VOICE;
08801       if (iaxs[fr->callno]->voiceformat > 0)
08802          f.subclass = iaxs[fr->callno]->voiceformat;
08803       else {
08804          if (option_debug)
08805             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08806          iax2_vnak(fr->callno);
08807          ast_mutex_unlock(&iaxsl[fr->callno]);
08808          return 1;
08809       }
08810       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08811       if (f.datalen < 0) {
08812          ast_log(LOG_WARNING, "Datalen < 0?\n");
08813          ast_mutex_unlock(&iaxsl[fr->callno]);
08814          return 1;
08815       }
08816       if (f.datalen)
08817          f.data = thread->buf + sizeof(*mh);
08818       else
08819          f.data = NULL;
08820 #ifdef IAXTESTS
08821       if (test_resync) {
08822          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08823       } else
08824 #endif /* IAXTESTS */
08825       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08826       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08827    }
08828    /* Don't pass any packets until we're started */
08829    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08830       ast_mutex_unlock(&iaxsl[fr->callno]);
08831       return 1;
08832    }
08833    /* Common things */
08834    f.src = "IAX2";
08835    f.mallocd = 0;
08836    f.offset = 0;
08837    f.len = 0;
08838    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08839       f.samples = ast_codec_get_samples(&f);
08840       /* We need to byteswap incoming slinear samples from network byte order */
08841       if (f.subclass == AST_FORMAT_SLINEAR)
08842          ast_frame_byteswap_be(&f);
08843    } else
08844       f.samples = 0;
08845    iax_frame_wrap(fr, &f);
08846 
08847    /* If this is our most recent packet, use it as our basis for timestamping */
08848    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08849       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08850       fr->outoforder = 0;
08851    } else {
08852       if (option_debug && iaxdebug && iaxs[fr->callno])
08853          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);
08854       fr->outoforder = -1;
08855    }
08856    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08857    duped_fr = iaxfrdup2(fr);
08858    if (duped_fr) {
08859       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08860    }
08861    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08862       iaxs[fr->callno]->last = fr->ts;
08863 #if 1
08864       if (option_debug && iaxdebug)
08865          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08866 #endif
08867    }
08868 
08869    /* Always run again */
08870    ast_mutex_unlock(&iaxsl[fr->callno]);
08871    return 1;
08872 }
08873 
08874 /* Function to clean up process thread if it is cancelled */
08875 static void iax2_process_thread_cleanup(void *data)
08876 {
08877    struct iax2_thread *thread = data;
08878    ast_mutex_destroy(&thread->lock);
08879    ast_cond_destroy(&thread->cond);
08880    free(thread);
08881    ast_atomic_dec_and_test(&iaxactivethreadcount);
08882 }
08883 
08884 static void *iax2_process_thread(void *data)
08885 {
08886    struct iax2_thread *thread = data;
08887    struct timeval tv;
08888    struct timespec ts;
08889    int put_into_idle = 0;
08890 
08891    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08892    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08893    for(;;) {
08894       /* Wait for something to signal us to be awake */
08895       ast_mutex_lock(&thread->lock);
08896 
08897       /* Flag that we're ready to accept signals */
08898       thread->ready_for_signal = 1;
08899       
08900       /* Put into idle list if applicable */
08901       if (put_into_idle)
08902          insert_idle_thread(thread);
08903 
08904       if (thread->type == IAX_TYPE_DYNAMIC) {
08905          struct iax2_thread *t = NULL;
08906          /* Wait to be signalled or time out */
08907          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08908          ts.tv_sec = tv.tv_sec;
08909          ts.tv_nsec = tv.tv_usec * 1000;
08910          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08911             /* This thread was never put back into the available dynamic
08912              * thread list, so just go away. */
08913             if (!put_into_idle) {
08914                ast_mutex_unlock(&thread->lock);
08915                break;
08916             }
08917             AST_LIST_LOCK(&dynamic_list);
08918             /* Account for the case where this thread is acquired *right* after a timeout */
08919             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08920                iaxdynamicthreadcount--;
08921             AST_LIST_UNLOCK(&dynamic_list);
08922             if (t) {
08923                /* This dynamic thread timed out waiting for a task and was
08924                 * not acquired immediately after the timeout, 
08925                 * so it's time to go away. */
08926                ast_mutex_unlock(&thread->lock);
08927                break;
08928             }
08929             /* Someone grabbed our thread *right* after we timed out.
08930              * Wait for them to set us up with something to do and signal
08931              * us to continue. */
08932             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08933             ts.tv_sec = tv.tv_sec;
08934             ts.tv_nsec = tv.tv_usec * 1000;
08935             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08936             {
08937                ast_mutex_unlock(&thread->lock);
08938                break;
08939             }
08940          }
08941       } else {
08942          ast_cond_wait(&thread->cond, &thread->lock);
08943       }
08944 
08945       /* Go back into our respective list */
08946       put_into_idle = 1;
08947 
08948       ast_mutex_unlock(&thread->lock);
08949 
08950       if (thread->iostate == IAX_IOSTATE_IDLE)
08951          continue;
08952 
08953       /* Add ourselves to the active list now */
08954       AST_LIST_LOCK(&active_list);
08955       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08956       AST_LIST_UNLOCK(&active_list);
08957 
08958       /* See what we need to do */
08959       switch(thread->iostate) {
08960       case IAX_IOSTATE_READY:
08961          thread->actions++;
08962          thread->iostate = IAX_IOSTATE_PROCESSING;
08963          socket_process(thread);
08964          handle_deferred_full_frames(thread);
08965          break;
08966       case IAX_IOSTATE_SCHEDREADY:
08967          thread->actions++;
08968          thread->iostate = IAX_IOSTATE_PROCESSING;
08969 #ifdef SCHED_MULTITHREADED
08970          thread->schedfunc(thread->scheddata);
08971 #endif      
08972          break;
08973       }
08974       time(&thread->checktime);
08975       thread->iostate = IAX_IOSTATE_IDLE;
08976 #ifdef DEBUG_SCHED_MULTITHREAD
08977       thread->curfunc[0]='\0';
08978 #endif      
08979 
08980       /* Now... remove ourselves from the active list, and return to the idle list */
08981       AST_LIST_LOCK(&active_list);
08982       AST_LIST_REMOVE(&active_list, thread, list);
08983       AST_LIST_UNLOCK(&active_list);
08984 
08985       /* Make sure another frame didn't sneak in there after we thought we were done. */
08986       handle_deferred_full_frames(thread);
08987    }
08988 
08989    /*!\note For some reason, idle threads are exiting without being removed
08990     * from an idle list, which is causing memory corruption.  Forcibly remove
08991     * it from the list, if it's there.
08992     */
08993    AST_LIST_LOCK(&idle_list);
08994    AST_LIST_REMOVE(&idle_list, thread, list);
08995    AST_LIST_UNLOCK(&idle_list);
08996 
08997    AST_LIST_LOCK(&dynamic_list);
08998    AST_LIST_REMOVE(&dynamic_list, thread, list);
08999    AST_LIST_UNLOCK(&dynamic_list);
09000 
09001    /* I am exiting here on my own volition, I need to clean up my own data structures
09002    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
09003    */
09004    pthread_cleanup_pop(1);
09005 
09006    return NULL;
09007 }
09008 
09009 static int iax2_do_register(struct iax2_registry *reg)
09010 {
09011    struct iax_ie_data ied;
09012    if (option_debug && iaxdebug)
09013       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
09014 
09015    if (reg->dnsmgr && 
09016        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09017       /* Maybe the IP has changed, force DNS refresh */
09018       ast_dnsmgr_refresh(reg->dnsmgr);
09019    }
09020    
09021    /*
09022     * if IP has Changed, free allocated call to create a new one with new IP
09023     * call has the pointer to IP and must be updated to the new one
09024     */
09025    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
09026       int callno = reg->callno;
09027       ast_mutex_lock(&iaxsl[callno]);
09028       iax2_destroy(callno);
09029       ast_mutex_unlock(&iaxsl[callno]);
09030       reg->callno = 0;
09031    }
09032    if (!reg->addr.sin_addr.s_addr) {
09033       if (option_debug && iaxdebug)
09034          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
09035       /* Setup the next registration attempt */
09036       AST_SCHED_DEL(sched, reg->expire);
09037       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
09038       return -1;
09039    }
09040 
09041    if (!reg->callno) {
09042       if (option_debug)
09043          ast_log(LOG_DEBUG, "Allocate call number\n");
09044       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
09045       if (reg->callno < 1) {
09046          ast_log(LOG_WARNING, "Unable to create call for registration\n");
09047          return -1;
09048       } else if (option_debug)
09049          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
09050       iaxs[reg->callno]->reg = reg;
09051       ast_mutex_unlock(&iaxsl[reg->callno]);
09052    }
09053    /* Schedule the next registration attempt */
09054    AST_SCHED_DEL(sched, reg->expire);
09055    /* Setup the next registration a little early */
09056    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
09057    /* Send the request */
09058    memset(&ied, 0, sizeof(ied));
09059    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09060    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09061    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09062    reg->regstate = REG_STATE_REGSENT;
09063    return 0;
09064 }
09065 
09066 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
09067 {
09068    if (pos != 3)
09069       return NULL;
09070    return iax_prov_complete_template(line, word, pos, state);
09071 }
09072 
09073 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
09074 {
09075    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
09076       is found for template */
09077    struct iax_ie_data provdata;
09078    struct iax_ie_data ied;
09079    unsigned int sig;
09080    struct sockaddr_in sin;
09081    int callno;
09082    struct create_addr_info cai;
09083 
09084    memset(&cai, 0, sizeof(cai));
09085 
09086    if (option_debug)
09087       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
09088 
09089    if (iax_provision_build(&provdata, &sig, template, force)) {
09090       if (option_debug)
09091          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
09092       return 0;
09093    }
09094 
09095    if (end) {
09096       memcpy(&sin, end, sizeof(sin));
09097       cai.sockfd = sockfd;
09098    } else if (create_addr(dest, NULL, &sin, &cai))
09099       return -1;
09100 
09101    /* Build the rest of the message */
09102    memset(&ied, 0, sizeof(ied));
09103    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
09104 
09105    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09106    if (!callno)
09107       return -1;
09108 
09109    if (iaxs[callno]) {
09110       /* Schedule autodestruct in case they don't ever give us anything back */
09111       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
09112       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
09113       ast_set_flag(iaxs[callno], IAX_PROVISION);
09114       /* Got a call number now, so go ahead and send the provisioning information */
09115       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
09116    }
09117    ast_mutex_unlock(&iaxsl[callno]);
09118 
09119    return 1;
09120 }
09121 
09122 static char *papp = "IAX2Provision";
09123 static char *psyn = "Provision a calling IAXy with a given template";
09124 static char *pdescrip = 
09125 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
09126 "the calling entity is in fact an IAXy) with the given template or\n"
09127 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
09128 
09129 /*! iax2provision
09130 \ingroup applications
09131 */
09132 static int iax2_prov_app(struct ast_channel *chan, void *data)
09133 {
09134    int res;
09135    char *sdata;
09136    char *opts;
09137    int force =0;
09138    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09139    if (ast_strlen_zero(data))
09140       data = "default";
09141    sdata = ast_strdupa(data);
09142    opts = strchr(sdata, '|');
09143    if (opts)
09144       *opts='\0';
09145 
09146    if (chan->tech != &iax2_tech) {
09147       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
09148       return -1;
09149    } 
09150    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
09151       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
09152       return -1;
09153    }
09154    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
09155    if (option_verbose > 2)
09156       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
09157       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
09158       sdata, res);
09159    return res;
09160 }
09161 
09162 
09163 static int iax2_prov_cmd(int fd, int argc, char *argv[])
09164 {
09165    int force = 0;
09166    int res;
09167    if (argc < 4)
09168       return RESULT_SHOWUSAGE;
09169    if ((argc > 4)) {
09170       if (!strcasecmp(argv[4], "forced"))
09171          force = 1;
09172       else
09173          return RESULT_SHOWUSAGE;
09174    }
09175    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
09176    if (res < 0)
09177       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
09178    else if (res < 1)
09179       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
09180    else
09181       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
09182    return RESULT_SUCCESS;
09183 }
09184 
09185 static void __iax2_poke_noanswer(const void *data)
09186 {
09187    struct iax2_peer *peer = (struct iax2_peer *)data;
09188    int callno;
09189 
09190    if (peer->lastms > -1) {
09191       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
09192       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
09193       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09194    }
09195    if ((callno = peer->callno) > 0) {
09196       ast_mutex_lock(&iaxsl[callno]);
09197       iax2_destroy(callno);
09198       ast_mutex_unlock(&iaxsl[callno]);
09199    }
09200    peer->callno = 0;
09201    peer->lastms = -1;
09202    /* Try again quickly */
09203    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09204    if (peer->pokeexpire == -1)
09205       peer_unref(peer);
09206 }
09207 
09208 static int iax2_poke_noanswer(const void *data)
09209 {
09210    struct iax2_peer *peer = (struct iax2_peer *)data;
09211    peer->pokeexpire = -1;
09212 #ifdef SCHED_MULTITHREADED
09213    if (schedule_action(__iax2_poke_noanswer, data))
09214 #endif      
09215       __iax2_poke_noanswer(data);
09216    peer_unref(peer);
09217    return 0;
09218 }
09219 
09220 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
09221 {
09222    struct iax2_peer *peer = obj;
09223 
09224    iax2_poke_peer(peer, 0);
09225 
09226    return 0;
09227 }
09228 
09229 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
09230 {
09231    int callno;
09232    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
09233       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
09234         immediately after clearing things out */
09235       peer->lastms = 0;
09236       peer->historicms = 0;
09237       peer->pokeexpire = -1;
09238       peer->callno = 0;
09239       return 0;
09240    }
09241 
09242    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
09243    if ((callno = peer->callno) > 0) {
09244       ast_log(LOG_NOTICE, "Still have a callno...\n");
09245       ast_mutex_lock(&iaxsl[callno]);
09246       iax2_destroy(callno);
09247       ast_mutex_unlock(&iaxsl[callno]);
09248    }
09249    if (heldcall)
09250       ast_mutex_unlock(&iaxsl[heldcall]);
09251    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
09252    if (heldcall)
09253       ast_mutex_lock(&iaxsl[heldcall]);
09254    if (peer->callno < 1) {
09255       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
09256       return -1;
09257    }
09258 
09259    /* Speed up retransmission times for this qualify call */
09260    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
09261    iaxs[peer->callno]->peerpoke = peer;
09262    
09263    /* Remove any pending pokeexpire task */
09264    if (peer->pokeexpire > -1) {
09265       if (!ast_sched_del(sched, peer->pokeexpire)) {
09266          peer->pokeexpire = -1;
09267          peer_unref(peer);
09268       }
09269    }
09270 
09271    /* Queue up a new task to handle no reply */
09272    /* If the host is already unreachable then use the unreachable interval instead */
09273    if (peer->lastms < 0) {
09274       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
09275    } else
09276       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
09277 
09278    if (peer->pokeexpire == -1)
09279       peer_unref(peer);
09280 
09281    /* And send the poke */
09282    ast_mutex_lock(&iaxsl[callno]);
09283    if (iaxs[callno]) {
09284       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
09285    }
09286    ast_mutex_unlock(&iaxsl[callno]);
09287 
09288    return 0;
09289 }
09290 
09291 static void free_context(struct iax2_context *con)
09292 {
09293    struct iax2_context *conl;
09294    while(con) {
09295       conl = con;
09296       con = con->next;
09297       free(conl);
09298    }
09299 }
09300 
09301 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09302 {
09303    int callno;
09304    int res;
09305    int fmt, native;
09306    struct sockaddr_in sin;
09307    struct ast_channel *c;
09308    struct parsed_dial_string pds;
09309    struct create_addr_info cai;
09310    char *tmpstr;
09311 
09312    memset(&pds, 0, sizeof(pds));
09313    tmpstr = ast_strdupa(data);
09314    parse_dial_string(tmpstr, &pds);
09315 
09316    if (ast_strlen_zero(pds.peer)) {
09317       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09318       return NULL;
09319    }
09320           
09321    memset(&cai, 0, sizeof(cai));
09322    cai.capability = iax2_capability;
09323 
09324    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09325    
09326    /* Populate our address from the given */
09327    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09328       *cause = AST_CAUSE_UNREGISTERED;
09329       return NULL;
09330    }
09331 
09332    if (pds.port)
09333       sin.sin_port = htons(atoi(pds.port));
09334 
09335    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09336    if (callno < 1) {
09337       ast_log(LOG_WARNING, "Unable to create call\n");
09338       *cause = AST_CAUSE_CONGESTION;
09339       return NULL;
09340    }
09341 
09342    /* If this is a trunk, update it now */
09343    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09344    if (ast_test_flag(&cai, IAX_TRUNK)) {
09345       int new_callno;
09346       if ((new_callno = make_trunk(callno, 1)) != -1)
09347          callno = new_callno;
09348    }
09349    iaxs[callno]->maxtime = cai.maxtime;
09350    if (cai.found)
09351       ast_string_field_set(iaxs[callno], host, pds.peer);
09352 
09353    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09354 
09355    ast_mutex_unlock(&iaxsl[callno]);
09356 
09357    if (c) {
09358       /* Choose a format we can live with */
09359       if (c->nativeformats & format) 
09360          c->nativeformats &= format;
09361       else {
09362          native = c->nativeformats;
09363          fmt = format;
09364          res = ast_translator_best_choice(&fmt, &native);
09365          if (res < 0) {
09366             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09367                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09368             ast_hangup(c);
09369             return NULL;
09370          }
09371          c->nativeformats = native;
09372       }
09373       c->readformat = ast_best_codec(c->nativeformats);
09374       c->writeformat = c->readformat;
09375    }
09376 
09377    return c;
09378 }
09379 
09380 static void *sched_thread(void *ignore)
09381 {
09382    for (;;) {
09383       int ms, count;
09384       struct timespec ts;
09385 
09386       pthread_testcancel();
09387 
09388       ast_mutex_lock(&sched_lock);
09389 
09390       ms = ast_sched_wait(sched);
09391 
09392       if (ms == -1) {
09393          ast_cond_wait(&sched_cond, &sched_lock);
09394       } else {
09395          struct timeval tv;
09396          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
09397          ts.tv_sec = tv.tv_sec;
09398          ts.tv_nsec = tv.tv_usec * 1000;
09399          ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09400       }
09401 
09402       ast_mutex_unlock(&sched_lock);
09403 
09404       pthread_testcancel();
09405 
09406       count = ast_sched_runq(sched);
09407       if (option_debug && count >= 20) {
09408          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09409       }
09410    }
09411 
09412    return NULL;
09413 }
09414 
09415 static void *network_thread(void *ignore)
09416 {
09417    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09418       from the network, and queue them for delivery to the channels */
09419    int res, count, wakeup;
09420    struct iax_frame *f;
09421 
09422    if (timingfd > -1)
09423       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09424    
09425    for(;;) {
09426       pthread_testcancel();
09427 
09428       /* Go through the queue, sending messages which have not yet been
09429          sent, and scheduling retransmissions if appropriate */
09430       AST_LIST_LOCK(&iaxq.queue);
09431       count = 0;
09432       wakeup = -1;
09433       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09434          if (f->sentyet)
09435             continue;
09436          
09437          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09438          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09439             wakeup = 1;
09440             continue;
09441          }
09442 
09443          f->sentyet++;
09444 
09445          if (iaxs[f->callno]) {
09446             send_packet(f);
09447             count++;
09448          } 
09449 
09450          ast_mutex_unlock(&iaxsl[f->callno]);
09451 
09452          if (f->retries < 0) {
09453             /* This is not supposed to be retransmitted */
09454             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09455             iaxq.count--;
09456             /* Free the iax frame */
09457             iax_frame_free(f);
09458          } else {
09459             /* We need reliable delivery.  Schedule a retransmission */
09460             f->retries++;
09461             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09462          }
09463       }
09464       AST_LIST_TRAVERSE_SAFE_END
09465       AST_LIST_UNLOCK(&iaxq.queue);
09466 
09467       pthread_testcancel();
09468 
09469       if (option_debug && count >= 20)
09470          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09471 
09472       /* Now do the IO, and run scheduled tasks */
09473       res = ast_io_wait(io, wakeup);
09474       if (res >= 0) {
09475          if (option_debug && res >= 20)
09476             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09477       }
09478    }
09479    return NULL;
09480 }
09481 
09482 static int start_network_thread(void)
09483 {
09484    pthread_attr_t attr;
09485    int threadcount = 0;
09486    int x;
09487    for (x = 0; x < iaxthreadcount; x++) {
09488       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09489       if (thread) {
09490          thread->type = IAX_TYPE_POOL;
09491          thread->threadnum = ++threadcount;
09492          ast_mutex_init(&thread->lock);
09493          ast_cond_init(&thread->cond, NULL);
09494          pthread_attr_init(&attr);
09495          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09496          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09497             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09498             free(thread);
09499             thread = NULL;
09500          }
09501          AST_LIST_LOCK(&idle_list);
09502          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09503          AST_LIST_UNLOCK(&idle_list);
09504       }
09505    }
09506    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09507    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09508    if (option_verbose > 1)
09509       ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
09510    return 0;
09511 }
09512 
09513 static struct iax2_context *build_context(char *context)
09514 {
09515    struct iax2_context *con;
09516 
09517    if ((con = ast_calloc(1, sizeof(*con))))
09518       ast_copy_string(con->context, context, sizeof(con->context));
09519    
09520    return con;
09521 }
09522 
09523 static int get_auth_methods(char *value)
09524 {
09525    int methods = 0;
09526    if (strstr(value, "rsa"))
09527       methods |= IAX_AUTH_RSA;
09528    if (strstr(value, "md5"))
09529       methods |= IAX_AUTH_MD5;
09530    if (strstr(value, "plaintext"))
09531       methods |= IAX_AUTH_PLAINTEXT;
09532    return methods;
09533 }
09534 
09535 
09536 /*! \brief Check if address can be used as packet source.
09537  \return 0  address available, 1  address unavailable, -1  error
09538 */
09539 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09540 {
09541    int sd;
09542    int res;
09543    
09544    sd = socket(AF_INET, SOCK_DGRAM, 0);
09545    if (sd < 0) {
09546       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09547       return -1;
09548    }
09549 
09550    res = bind(sd, sa, salen);
09551    if (res < 0) {
09552       if (option_debug)
09553          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09554       close(sd);
09555       return 1;
09556    }
09557 
09558    close(sd);
09559    return 0;
09560 }
09561 
09562 /*! \brief Parse the "sourceaddress" value,
09563   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09564   not found. */
09565 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09566 {
09567    struct sockaddr_in sin;
09568    int nonlocal = 1;
09569    int port = IAX_DEFAULT_PORTNO;
09570    int sockfd = defaultsockfd;
09571    char *tmp;
09572    char *addr;
09573    char *portstr;
09574 
09575    if (!(tmp = ast_strdupa(srcaddr)))
09576       return -1;
09577 
09578    addr = strsep(&tmp, ":");
09579    portstr = tmp;
09580 
09581    if (portstr) {
09582       port = atoi(portstr);
09583       if (port < 1)
09584          port = IAX_DEFAULT_PORTNO;
09585    }
09586    
09587    if (!ast_get_ip(&sin, addr)) {
09588       struct ast_netsock *sock;
09589       int res;
09590 
09591       sin.sin_port = 0;
09592       sin.sin_family = AF_INET;
09593       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09594       if (res == 0) {
09595          /* ip address valid. */
09596          sin.sin_port = htons(port);
09597          if (!(sock = ast_netsock_find(netsock, &sin)))
09598             sock = ast_netsock_find(outsock, &sin);
09599          if (sock) {
09600             sockfd = ast_netsock_sockfd(sock);
09601             nonlocal = 0;
09602          } else {
09603             unsigned int orig_saddr = sin.sin_addr.s_addr;
09604             /* INADDR_ANY matches anyway! */
09605             sin.sin_addr.s_addr = INADDR_ANY;
09606             if (ast_netsock_find(netsock, &sin)) {
09607                sin.sin_addr.s_addr = orig_saddr;
09608                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09609                if (sock) {
09610                   sockfd = ast_netsock_sockfd(sock);
09611                   ast_netsock_unref(sock);
09612                   nonlocal = 0;
09613                } else {
09614                   nonlocal = 2;
09615                }
09616             }
09617          }
09618       }
09619    }
09620       
09621    peer->sockfd = sockfd;
09622 
09623    if (nonlocal == 1) {
09624       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09625          srcaddr, peer->name);
09626       return -1;
09627         } else if (nonlocal == 2) {
09628       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09629          srcaddr, peer->name);
09630          return -1;
09631    } else {
09632       if (option_debug)
09633          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09634       return 0;
09635    }
09636 }
09637 
09638 static void peer_destructor(void *obj)
09639 {
09640    struct iax2_peer *peer = obj;
09641    int callno = peer->callno;
09642 
09643    ast_free_ha(peer->ha);
09644 
09645    if (callno > 0) {
09646       ast_mutex_lock(&iaxsl[callno]);
09647       iax2_destroy(callno);
09648       ast_mutex_unlock(&iaxsl[callno]);
09649    }
09650 
09651    register_peer_exten(peer, 0);
09652 
09653    if (peer->dnsmgr)
09654       ast_dnsmgr_release(peer->dnsmgr);
09655 
09656    ast_string_field_free_memory(peer);
09657 }
09658 
09659 /*! \brief Create peer structure based on configuration */
09660 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09661 {
09662    struct iax2_peer *peer = NULL;
09663    struct ast_ha *oldha = NULL;
09664    int maskfound=0;
09665    int found=0;
09666    int firstpass=1;
09667    struct iax2_peer tmp_peer = {
09668       .name = name,
09669    };
09670 
09671    if (!temponly) {
09672       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09673       if (peer && !ast_test_flag(peer, IAX_DELME))
09674          firstpass = 0;
09675    }
09676 
09677    if (peer) {
09678       found++;
09679       if (firstpass) {
09680          oldha = peer->ha;
09681          peer->ha = NULL;
09682       }
09683       unlink_peer(peer);
09684    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09685       peer->expire = -1;
09686       peer->pokeexpire = -1;
09687       peer->sockfd = defaultsockfd;
09688       if (ast_string_field_init(peer, 32))
09689          peer = peer_unref(peer);
09690    }
09691 
09692    if (peer) {
09693       if (firstpass) {
09694          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09695          peer->encmethods = iax2_encryption;
09696          peer->adsi = adsi;
09697          ast_string_field_set(peer,secret,"");
09698          if (!found) {
09699             ast_string_field_set(peer, name, name);
09700             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09701             peer->expiry = min_reg_expire;
09702          }
09703          peer->prefs = prefs;
09704          peer->capability = iax2_capability;
09705          peer->smoothing = 0;
09706          peer->pokefreqok = DEFAULT_FREQ_OK;
09707          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09708          ast_string_field_set(peer,context,"");
09709          ast_string_field_set(peer,peercontext,"");
09710          ast_clear_flag(peer, IAX_HASCALLERID);
09711          ast_string_field_set(peer, cid_name, "");
09712          ast_string_field_set(peer, cid_num, "");
09713          ast_string_field_set(peer, mohinterpret, mohinterpret);
09714          ast_string_field_set(peer, mohsuggest, mohsuggest);
09715       }
09716 
09717       if (!v) {
09718          v = alt;
09719          alt = NULL;
09720       }
09721       while(v) {
09722          if (!strcasecmp(v->name, "secret")) {
09723             ast_string_field_set(peer, secret, v->value);
09724          } else if (!strcasecmp(v->name, "mailbox")) {
09725             ast_string_field_set(peer, mailbox, v->value);
09726          } else if (!strcasecmp(v->name, "hasvoicemail")) {
09727             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
09728                ast_string_field_set(peer, mailbox, name);
09729             }
09730          } else if (!strcasecmp(v->name, "mohinterpret")) {
09731             ast_string_field_set(peer, mohinterpret, v->value);
09732          } else if (!strcasecmp(v->name, "mohsuggest")) {
09733             ast_string_field_set(peer, mohsuggest, v->value);
09734          } else if (!strcasecmp(v->name, "dbsecret")) {
09735             ast_string_field_set(peer, dbsecret, v->value);
09736          } else if (!strcasecmp(v->name, "trunk")) {
09737             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09738             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09739                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
09740                ast_clear_flag(peer, IAX_TRUNK);
09741             }
09742          } else if (!strcasecmp(v->name, "auth")) {
09743             peer->authmethods = get_auth_methods(v->value);
09744          } else if (!strcasecmp(v->name, "encryption")) {
09745             peer->encmethods = get_encrypt_methods(v->value);
09746          } else if (!strcasecmp(v->name, "notransfer")) {
09747             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09748             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09749             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09750          } else if (!strcasecmp(v->name, "transfer")) {
09751             if (!strcasecmp(v->value, "mediaonly")) {
09752                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09753             } else if (ast_true(v->value)) {
09754                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09755             } else 
09756                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09757          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09758             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09759          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09760             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09761          } else if (!strcasecmp(v->name, "host")) {
09762             if (!strcasecmp(v->value, "dynamic")) {
09763                /* They'll register with us */
09764                ast_set_flag(peer, IAX_DYNAMIC); 
09765                if (!found) {
09766                   /* Initialize stuff iff we're not found, otherwise
09767                      we keep going with what we had */
09768                   memset(&peer->addr.sin_addr, 0, 4);
09769                   if (peer->addr.sin_port) {
09770                      /* If we've already got a port, make it the default rather than absolute */
09771                      peer->defaddr.sin_port = peer->addr.sin_port;
09772                      peer->addr.sin_port = 0;
09773                   }
09774                }
09775             } else {
09776                /* Non-dynamic.  Make sure we become that way if we're not */
09777                AST_SCHED_DEL(sched, peer->expire);
09778                ast_clear_flag(peer, IAX_DYNAMIC);
09779                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09780                   return peer_unref(peer);
09781                if (!peer->addr.sin_port)
09782                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09783             }
09784             if (!maskfound)
09785                inet_aton("255.255.255.255", &peer->mask);
09786          } else if (!strcasecmp(v->name, "defaultip")) {
09787             if (ast_get_ip(&peer->defaddr, v->value))
09788                return peer_unref(peer);
09789          } else if (!strcasecmp(v->name, "sourceaddress")) {
09790             peer_set_srcaddr(peer, v->value);
09791          } else if (!strcasecmp(v->name, "permit") ||
09792                   !strcasecmp(v->name, "deny")) {
09793             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09794          } else if (!strcasecmp(v->name, "mask")) {
09795             maskfound++;
09796             inet_aton(v->value, &peer->mask);
09797          } else if (!strcasecmp(v->name, "context")) {
09798             ast_string_field_set(peer, context, v->value);
09799          } else if (!strcasecmp(v->name, "regexten")) {
09800             ast_string_field_set(peer, regexten, v->value);
09801          } else if (!strcasecmp(v->name, "peercontext")) {
09802             ast_string_field_set(peer, peercontext, v->value);
09803          } else if (!strcasecmp(v->name, "port")) {
09804             if (ast_test_flag(peer, IAX_DYNAMIC))
09805                peer->defaddr.sin_port = htons(atoi(v->value));
09806             else
09807                peer->addr.sin_port = htons(atoi(v->value));
09808          } else if (!strcasecmp(v->name, "username")) {
09809             ast_string_field_set(peer, username, v->value);
09810          } else if (!strcasecmp(v->name, "allow")) {
09811             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09812          } else if (!strcasecmp(v->name, "disallow")) {
09813             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09814          } else if (!strcasecmp(v->name, "callerid")) {
09815             if (!ast_strlen_zero(v->value)) {
09816                char name2[80];
09817                char num2[80];
09818                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09819                ast_string_field_set(peer, cid_name, name2);
09820                ast_string_field_set(peer, cid_num, num2);
09821             } else {
09822                ast_string_field_set(peer, cid_name, "");
09823                ast_string_field_set(peer, cid_num, "");
09824             }
09825             ast_set_flag(peer, IAX_HASCALLERID);
09826          } else if (!strcasecmp(v->name, "fullname")) {
09827             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
09828             ast_set_flag(peer, IAX_HASCALLERID);
09829          } else if (!strcasecmp(v->name, "cid_number")) {
09830             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
09831             ast_set_flag(peer, IAX_HASCALLERID);
09832          } else if (!strcasecmp(v->name, "sendani")) {
09833             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09834          } else if (!strcasecmp(v->name, "inkeys")) {
09835             ast_string_field_set(peer, inkeys, v->value);
09836          } else if (!strcasecmp(v->name, "outkey")) {
09837             ast_string_field_set(peer, outkey, v->value);
09838          } else if (!strcasecmp(v->name, "qualify")) {
09839             if (!strcasecmp(v->value, "no")) {
09840                peer->maxms = 0;
09841             } else if (!strcasecmp(v->value, "yes")) {
09842                peer->maxms = DEFAULT_MAXMS;
09843             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09844                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);
09845                peer->maxms = 0;
09846             }
09847          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09848             peer->smoothing = ast_true(v->value);
09849          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09850             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09851                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);
09852             }
09853          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09854             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09855                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);
09856             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09857          } else if (!strcasecmp(v->name, "timezone")) {
09858             ast_string_field_set(peer, zonetag, v->value);
09859          } else if (!strcasecmp(v->name, "adsi")) {
09860             peer->adsi = ast_true(v->value);
09861          }/* else if (strcasecmp(v->name,"type")) */
09862          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09863          v = v->next;
09864          if (!v) {
09865             v = alt;
09866             alt = NULL;
09867          }
09868       }
09869       if (!peer->authmethods)
09870          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09871       ast_clear_flag(peer, IAX_DELME); 
09872       /* Make sure these are IPv4 addresses */
09873       peer->addr.sin_family = AF_INET;
09874    }
09875    if (oldha)
09876       ast_free_ha(oldha);
09877    return peer;
09878 }
09879 
09880 static void user_destructor(void *obj)
09881 {
09882    struct iax2_user *user = obj;
09883 
09884    ast_free_ha(user->ha);
09885    free_context(user->contexts);
09886    if(user->vars) {
09887       ast_variables_destroy(user->vars);
09888       user->vars = NULL;
09889    }
09890    ast_string_field_free_memory(user);
09891 }
09892 
09893 /*! \brief Create in-memory user structure from configuration */
09894 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09895 {
09896    struct iax2_user *user = NULL;
09897    struct iax2_context *con, *conl = NULL;
09898    struct ast_ha *oldha = NULL;
09899    struct iax2_context *oldcon = NULL;
09900    int format;
09901    int firstpass=1;
09902    int oldcurauthreq = 0;
09903    char *varname = NULL, *varval = NULL;
09904    struct ast_variable *tmpvar = NULL;
09905    struct iax2_user tmp_user = {
09906       .name = name,
09907    };
09908 
09909    if (!temponly) {
09910       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09911       if (user && !ast_test_flag(user, IAX_DELME))
09912          firstpass = 0;
09913    }
09914 
09915    if (user) {
09916       if (firstpass) {
09917          oldcurauthreq = user->curauthreq;
09918          oldha = user->ha;
09919          oldcon = user->contexts;
09920          user->ha = NULL;
09921          user->contexts = NULL;
09922       }
09923       /* Already in the list, remove it and it will be added back (or FREE'd) */
09924       ao2_unlink(users, user);
09925    } else {
09926       user = ao2_alloc(sizeof(*user), user_destructor);
09927    }
09928    
09929    if (user) {
09930       if (firstpass) {
09931          ast_string_field_free_memory(user);
09932          memset(user, 0, sizeof(struct iax2_user));
09933          if (ast_string_field_init(user, 32)) {
09934             user = user_unref(user);
09935             goto cleanup;
09936          }
09937          user->maxauthreq = maxauthreq;
09938          user->curauthreq = oldcurauthreq;
09939          user->prefs = prefs;
09940          user->capability = iax2_capability;
09941          user->encmethods = iax2_encryption;
09942          user->adsi = adsi;
09943          ast_string_field_set(user, name, name);
09944          ast_string_field_set(user, language, language);
09945          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09946          ast_clear_flag(user, IAX_HASCALLERID);
09947          ast_string_field_set(user, cid_name, "");
09948          ast_string_field_set(user, cid_num, "");
09949          ast_string_field_set(user, accountcode, accountcode);
09950          ast_string_field_set(user, mohinterpret, mohinterpret);
09951          ast_string_field_set(user, mohsuggest, mohsuggest);
09952       }
09953       if (!v) {
09954          v = alt;
09955          alt = NULL;
09956       }
09957       while(v) {
09958          if (!strcasecmp(v->name, "context")) {
09959             con = build_context(v->value);
09960             if (con) {
09961                if (conl)
09962                   conl->next = con;
09963                else
09964                   user->contexts = con;
09965                conl = con;
09966             }
09967          } else if (!strcasecmp(v->name, "permit") ||
09968                   !strcasecmp(v->name, "deny")) {
09969             user->ha = ast_append_ha(v->name, v->value, user->ha);
09970          } else if (!strcasecmp(v->name, "setvar")) {
09971             varname = ast_strdupa(v->value);
09972             if (varname && (varval = strchr(varname,'='))) {
09973                *varval = '\0';
09974                varval++;
09975                if((tmpvar = ast_variable_new(varname, varval))) {
09976                   tmpvar->next = user->vars; 
09977                   user->vars = tmpvar;
09978                }
09979             }
09980          } else if (!strcasecmp(v->name, "allow")) {
09981             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09982          } else if (!strcasecmp(v->name, "disallow")) {
09983             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09984          } else if (!strcasecmp(v->name, "trunk")) {
09985             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09986             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09987                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
09988                ast_clear_flag(user, IAX_TRUNK);
09989             }
09990          } else if (!strcasecmp(v->name, "auth")) {
09991             user->authmethods = get_auth_methods(v->value);
09992          } else if (!strcasecmp(v->name, "encryption")) {
09993             user->encmethods = get_encrypt_methods(v->value);
09994          } else if (!strcasecmp(v->name, "notransfer")) {
09995             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09996             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09997             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09998          } else if (!strcasecmp(v->name, "transfer")) {
09999             if (!strcasecmp(v->value, "mediaonly")) {
10000                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10001             } else if (ast_true(v->value)) {
10002                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10003             } else 
10004                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10005          } else if (!strcasecmp(v->name, "codecpriority")) {
10006             if(!strcasecmp(v->value, "caller"))
10007                ast_set_flag(user, IAX_CODEC_USER_FIRST);
10008             else if(!strcasecmp(v->value, "disabled"))
10009                ast_set_flag(user, IAX_CODEC_NOPREFS);
10010             else if(!strcasecmp(v->value, "reqonly")) {
10011                ast_set_flag(user, IAX_CODEC_NOCAP);
10012                ast_set_flag(user, IAX_CODEC_NOPREFS);
10013             }
10014          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10015             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
10016          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10017             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
10018          } else if (!strcasecmp(v->name, "dbsecret")) {
10019             ast_string_field_set(user, dbsecret, v->value);
10020          } else if (!strcasecmp(v->name, "secret")) {
10021             if (!ast_strlen_zero(user->secret)) {
10022                char *old = ast_strdupa(user->secret);
10023 
10024                ast_string_field_build(user, secret, "%s;%s", old, v->value);
10025             } else
10026                ast_string_field_set(user, secret, v->value);
10027          } else if (!strcasecmp(v->name, "callerid")) {
10028             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
10029                char name2[80];
10030                char num2[80];
10031                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10032                ast_string_field_set(user, cid_name, name2);
10033                ast_string_field_set(user, cid_num, num2);
10034                ast_set_flag(user, IAX_HASCALLERID);
10035             } else {
10036                ast_clear_flag(user, IAX_HASCALLERID);
10037                ast_string_field_set(user, cid_name, "");
10038                ast_string_field_set(user, cid_num, "");
10039             }
10040          } else if (!strcasecmp(v->name, "fullname")) {
10041             if (!ast_strlen_zero(v->value)) {
10042                ast_string_field_set(user, cid_name, v->value);
10043                ast_set_flag(user, IAX_HASCALLERID);
10044             } else {
10045                ast_string_field_set(user, cid_name, "");
10046                if (ast_strlen_zero(user->cid_num))
10047                   ast_clear_flag(user, IAX_HASCALLERID);
10048             }
10049          } else if (!strcasecmp(v->name, "cid_number")) {
10050             if (!ast_strlen_zero(v->value)) {
10051                ast_string_field_set(user, cid_num, v->value);
10052                ast_set_flag(user, IAX_HASCALLERID);
10053             } else {
10054                ast_string_field_set(user, cid_num, "");
10055                if (ast_strlen_zero(user->cid_name))
10056                   ast_clear_flag(user, IAX_HASCALLERID);
10057             }
10058          } else if (!strcasecmp(v->name, "accountcode")) {
10059             ast_string_field_set(user, accountcode, v->value);
10060          } else if (!strcasecmp(v->name, "mohinterpret")) {
10061             ast_string_field_set(user, mohinterpret, v->value);
10062          } else if (!strcasecmp(v->name, "mohsuggest")) {
10063             ast_string_field_set(user, mohsuggest, v->value);
10064          } else if (!strcasecmp(v->name, "language")) {
10065             ast_string_field_set(user, language, v->value);
10066          } else if (!strcasecmp(v->name, "amaflags")) {
10067             format = ast_cdr_amaflags2int(v->value);
10068             if (format < 0) {
10069                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10070             } else {
10071                user->amaflags = format;
10072             }
10073          } else if (!strcasecmp(v->name, "inkeys")) {
10074             ast_string_field_set(user, inkeys, v->value);
10075          } else if (!strcasecmp(v->name, "maxauthreq")) {
10076             user->maxauthreq = atoi(v->value);
10077             if (user->maxauthreq < 0)
10078                user->maxauthreq = 0;
10079          } else if (!strcasecmp(v->name, "adsi")) {
10080             user->adsi = ast_true(v->value);
10081          }/* else if (strcasecmp(v->name,"type")) */
10082          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10083          v = v->next;
10084          if (!v) {
10085             v = alt;
10086             alt = NULL;
10087          }
10088       }
10089       if (!user->authmethods) {
10090          if (!ast_strlen_zero(user->secret)) {
10091             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10092             if (!ast_strlen_zero(user->inkeys))
10093                user->authmethods |= IAX_AUTH_RSA;
10094          } else if (!ast_strlen_zero(user->inkeys)) {
10095             user->authmethods = IAX_AUTH_RSA;
10096          } else {
10097             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10098          }
10099       }
10100       ast_clear_flag(user, IAX_DELME);
10101    }
10102 cleanup:
10103    if (oldha)
10104       ast_free_ha(oldha);
10105    if (oldcon)
10106       free_context(oldcon);
10107    return user;
10108 }
10109 
10110 static int peer_delme_cb(void *obj, void *arg, int flags)
10111 {
10112    struct iax2_peer *peer = obj;
10113 
10114    ast_set_flag(peer, IAX_DELME);
10115 
10116    return 0;
10117 }
10118 
10119 static int user_delme_cb(void *obj, void *arg, int flags)
10120 {
10121    struct iax2_user *user = obj;
10122 
10123    ast_set_flag(user, IAX_DELME);
10124 
10125    return 0;
10126 }
10127 
10128 static void delete_users(void)
10129 {
10130    struct iax2_registry *reg;
10131 
10132    ao2_callback(users, 0, user_delme_cb, NULL);
10133 
10134    AST_LIST_LOCK(&registrations);
10135    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
10136       ast_sched_del(sched, reg->expire);
10137       if (reg->callno) {
10138          int callno = reg->callno;
10139          ast_mutex_lock(&iaxsl[callno]);
10140          if (iaxs[callno]) {
10141             iaxs[callno]->reg = NULL;
10142             iax2_destroy(callno);
10143          }
10144          ast_mutex_unlock(&iaxsl[callno]);
10145       }
10146       if (reg->dnsmgr)
10147          ast_dnsmgr_release(reg->dnsmgr);
10148       free(reg);
10149    }
10150    AST_LIST_UNLOCK(&registrations);
10151 
10152    ao2_callback(peers, 0, peer_delme_cb, NULL);
10153 }
10154 
10155 static void prune_users(void)
10156 {
10157    struct iax2_user *user;
10158    struct ao2_iterator i;
10159 
10160    i = ao2_iterator_init(users, 0);
10161    while ((user = ao2_iterator_next(&i))) {
10162       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
10163          ao2_unlink(users, user);
10164       }
10165       user_unref(user);
10166    }
10167 }
10168 
10169 /* Prune peers who still are supposed to be deleted */
10170 static void prune_peers(void)
10171 {
10172    struct iax2_peer *peer;
10173    struct ao2_iterator i;
10174 
10175    i = ao2_iterator_init(peers, 0);
10176    while ((peer = ao2_iterator_next(&i))) {
10177       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
10178          unlink_peer(peer);
10179       }
10180       peer_unref(peer);
10181    }
10182 }
10183 
10184 static void set_timing(void)
10185 {
10186 #ifdef HAVE_DAHDI
10187    int bs = trunkfreq * 8;
10188    if (timingfd > -1) {
10189       if (
10190 #ifdef DAHDI_TIMERACK
10191          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
10192 #endif         
10193          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
10194          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
10195    }
10196 #endif
10197 }
10198 
10199 static void set_config_destroy(void)
10200 {
10201    strcpy(accountcode, "");
10202    strcpy(language, "");
10203    strcpy(mohinterpret, "default");
10204    strcpy(mohsuggest, "");
10205    amaflags = 0;
10206    delayreject = 0;
10207    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
10208    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10209    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
10210    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
10211    delete_users();
10212 }
10213 
10214 /*! \brief Load configuration */
10215 static int set_config(char *config_file, int reload)
10216 {
10217    struct ast_config *cfg, *ucfg;
10218    int capability=iax2_capability;
10219    struct ast_variable *v;
10220    char *cat;
10221    const char *utype;
10222    const char *tosval;
10223    int format;
10224    int portno = IAX_DEFAULT_PORTNO;
10225    int  x;
10226    struct iax2_user *user;
10227    struct iax2_peer *peer;
10228    struct ast_netsock *ns;
10229 #if 0
10230    static unsigned short int last_port=0;
10231 #endif
10232 
10233    cfg = ast_config_load(config_file);
10234    
10235    if (!cfg) {
10236       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
10237       return -1;
10238    }
10239 
10240    if (reload) {
10241       set_config_destroy();
10242    }
10243 
10244    /* Reset global codec prefs */   
10245    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
10246    
10247    /* Reset Global Flags */
10248    memset(&globalflags, 0, sizeof(globalflags));
10249    ast_set_flag(&globalflags, IAX_RTUPDATE);
10250 
10251 #ifdef SO_NO_CHECK
10252    nochecksums = 0;
10253 #endif
10254 
10255    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10256    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10257 
10258    maxauthreq = 3;
10259 
10260    v = ast_variable_browse(cfg, "general");
10261 
10262    /* Seed initial tos value */
10263    tosval = ast_variable_retrieve(cfg, "general", "tos");
10264    if (tosval) {
10265       if (ast_str2tos(tosval, &tos))
10266          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
10267    }
10268    while(v) {
10269       if (!strcasecmp(v->name, "bindport")){ 
10270          if (reload)
10271             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
10272          else
10273             portno = atoi(v->value);
10274       } else if (!strcasecmp(v->name, "pingtime")) 
10275          ping_time = atoi(v->value);
10276       else if (!strcasecmp(v->name, "iaxthreadcount")) {
10277          if (reload) {
10278             if (atoi(v->value) != iaxthreadcount)
10279                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
10280          } else {
10281             iaxthreadcount = atoi(v->value);
10282             if (iaxthreadcount < 1) {
10283                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
10284                iaxthreadcount = 1;
10285             } else if (iaxthreadcount > 256) {
10286                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
10287                iaxthreadcount = 256;
10288             }
10289          }
10290       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
10291          if (reload) {
10292             AST_LIST_LOCK(&dynamic_list);
10293             iaxmaxthreadcount = atoi(v->value);
10294             AST_LIST_UNLOCK(&dynamic_list);
10295          } else {
10296             iaxmaxthreadcount = atoi(v->value);
10297             if (iaxmaxthreadcount < 0) {
10298                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
10299                iaxmaxthreadcount = 0;
10300             } else if (iaxmaxthreadcount > 256) {
10301                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
10302                iaxmaxthreadcount = 256;
10303             }
10304          }
10305       } else if (!strcasecmp(v->name, "nochecksums")) {
10306 #ifdef SO_NO_CHECK
10307          if (ast_true(v->value))
10308             nochecksums = 1;
10309          else
10310             nochecksums = 0;
10311 #else
10312          if (ast_true(v->value))
10313             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10314 #endif
10315       }
10316       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
10317          maxjitterbuffer = atoi(v->value);
10318       else if (!strcasecmp(v->name, "resyncthreshold")) 
10319          resyncthreshold = atoi(v->value);
10320       else if (!strcasecmp(v->name, "maxjitterinterps")) 
10321          maxjitterinterps = atoi(v->value);
10322       else if (!strcasecmp(v->name, "lagrqtime")) 
10323          lagrq_time = atoi(v->value);
10324       else if (!strcasecmp(v->name, "maxregexpire")) 
10325          max_reg_expire = atoi(v->value);
10326       else if (!strcasecmp(v->name, "minregexpire")) 
10327          min_reg_expire = atoi(v->value);
10328       else if (!strcasecmp(v->name, "bindaddr")) {
10329          if (reload) {
10330             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10331          } else {
10332             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10333                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10334             } else {
10335                if (option_verbose > 1) {
10336                   if (strchr(v->value, ':'))
10337                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10338                   else
10339                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10340                }
10341                if (defaultsockfd < 0) 
10342                   defaultsockfd = ast_netsock_sockfd(ns);
10343                ast_netsock_unref(ns);
10344             }
10345          }
10346       } else if (!strcasecmp(v->name, "authdebug"))
10347          authdebug = ast_true(v->value);
10348       else if (!strcasecmp(v->name, "encryption"))
10349          iax2_encryption = get_encrypt_methods(v->value);
10350       else if (!strcasecmp(v->name, "notransfer")) {
10351          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10352          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10353          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10354       } else if (!strcasecmp(v->name, "transfer")) {
10355          if (!strcasecmp(v->value, "mediaonly")) {
10356             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10357          } else if (ast_true(v->value)) {
10358             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10359          } else 
10360             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10361       } else if (!strcasecmp(v->name, "codecpriority")) {
10362          if(!strcasecmp(v->value, "caller"))
10363             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10364          else if(!strcasecmp(v->value, "disabled"))
10365             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10366          else if(!strcasecmp(v->value, "reqonly")) {
10367             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10368             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10369          }
10370       } else if (!strcasecmp(v->name, "jitterbuffer"))
10371          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10372       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10373          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10374       else if (!strcasecmp(v->name, "delayreject"))
10375          delayreject = ast_true(v->value);
10376       else if (!strcasecmp(v->name, "allowfwdownload"))
10377          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10378       else if (!strcasecmp(v->name, "rtcachefriends"))
10379          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10380       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10381          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10382       else if (!strcasecmp(v->name, "rtupdate"))
10383          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10384       else if (!strcasecmp(v->name, "trunktimestamps"))
10385          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10386       else if (!strcasecmp(v->name, "rtautoclear")) {
10387          int i = atoi(v->value);
10388          if(i > 0)
10389             global_rtautoclear = i;
10390          else
10391             i = 0;
10392          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10393       } else if (!strcasecmp(v->name, "trunkfreq")) {
10394          trunkfreq = atoi(v->value);
10395          if (trunkfreq < 10)
10396             trunkfreq = 10;
10397       } else if (!strcasecmp(v->name, "autokill")) {
10398          if (sscanf(v->value, "%d", &x) == 1) {
10399             if (x >= 0)
10400                autokill = x;
10401             else
10402                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10403          } else if (ast_true(v->value)) {
10404             autokill = DEFAULT_MAXMS;
10405          } else {
10406             autokill = 0;
10407          }
10408       } else if (!strcasecmp(v->name, "bandwidth")) {
10409          if (!strcasecmp(v->value, "low")) {
10410             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10411          } else if (!strcasecmp(v->value, "medium")) {
10412             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10413          } else if (!strcasecmp(v->value, "high")) {
10414             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10415          } else
10416             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10417       } else if (!strcasecmp(v->name, "allow")) {
10418          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10419       } else if (!strcasecmp(v->name, "disallow")) {
10420          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10421       } else if (!strcasecmp(v->name, "register")) {
10422          iax2_register(v->value, v->lineno);
10423       } else if (!strcasecmp(v->name, "iaxcompat")) {
10424          iaxcompat = ast_true(v->value);
10425       } else if (!strcasecmp(v->name, "regcontext")) {
10426          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10427          /* Create context if it doesn't exist already */
10428          if (!ast_context_find(regcontext))
10429             ast_context_create(NULL, regcontext, "IAX2");
10430       } else if (!strcasecmp(v->name, "tos")) {
10431          if (ast_str2tos(v->value, &tos))
10432             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10433       } else if (!strcasecmp(v->name, "accountcode")) {
10434          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10435       } else if (!strcasecmp(v->name, "mohinterpret")) {
10436          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
10437       } else if (!strcasecmp(v->name, "mohsuggest")) {
10438          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
10439       } else if (!strcasecmp(v->name, "amaflags")) {
10440          format = ast_cdr_amaflags2int(v->value);
10441          if (format < 0) {
10442             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10443          } else {
10444             amaflags = format;
10445          }
10446       } else if (!strcasecmp(v->name, "language")) {
10447          ast_copy_string(language, v->value, sizeof(language));
10448       } else if (!strcasecmp(v->name, "maxauthreq")) {
10449          maxauthreq = atoi(v->value);
10450          if (maxauthreq < 0)
10451             maxauthreq = 0;
10452       } else if (!strcasecmp(v->name, "adsi")) {
10453          adsi = ast_true(v->value);
10454       } /*else if (strcasecmp(v->name,"type")) */
10455       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10456       v = v->next;
10457    }
10458    
10459    if (defaultsockfd < 0) {
10460       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10461          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10462       } else {
10463          if (option_verbose > 1)
10464             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10465          defaultsockfd = ast_netsock_sockfd(ns);
10466          ast_netsock_unref(ns);
10467       }
10468    }
10469    if (reload) {
10470       ast_netsock_release(outsock);
10471       outsock = ast_netsock_list_alloc();
10472       if (!outsock) {
10473          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10474          return -1;
10475       }
10476       ast_netsock_init(outsock);
10477    }
10478 
10479    if (min_reg_expire > max_reg_expire) {
10480       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10481          min_reg_expire, max_reg_expire, max_reg_expire);
10482       min_reg_expire = max_reg_expire;
10483    }
10484    iax2_capability = capability;
10485    
10486    ucfg = ast_config_load("users.conf");
10487    if (ucfg) {
10488       struct ast_variable *gen;
10489       int genhasiax;
10490       int genregisteriax;
10491       const char *hasiax, *registeriax;
10492       
10493       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10494       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10495       gen = ast_variable_browse(ucfg, "general");
10496       cat = ast_category_browse(ucfg, NULL);
10497       while (cat) {
10498          if (strcasecmp(cat, "general")) {
10499             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10500             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10501             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10502                /* Start with general parameters, then specific parameters, user and peer */
10503                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10504                if (user) {
10505                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10506                   user = user_unref(user);
10507                }
10508                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10509                if (peer) {
10510                   if (ast_test_flag(peer, IAX_DYNAMIC))
10511                      reg_source_db(peer);
10512                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10513                   peer = peer_unref(peer);
10514                }
10515             }
10516             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10517                char tmp[256];
10518                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10519                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10520                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10521                if (!host)
10522                   host = ast_variable_retrieve(ucfg, "general", "host");
10523                if (!username)
10524                   username = ast_variable_retrieve(ucfg, "general", "username");
10525                if (!secret)
10526                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10527                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10528                   if (!ast_strlen_zero(secret))
10529                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10530                   else
10531                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10532                   iax2_register(tmp, 0);
10533                }
10534             }
10535          }
10536          cat = ast_category_browse(ucfg, cat);
10537       }
10538       ast_config_destroy(ucfg);
10539    }
10540    
10541    cat = ast_category_browse(cfg, NULL);
10542    while(cat) {
10543       if (strcasecmp(cat, "general")) {
10544          utype = ast_variable_retrieve(cfg, cat, "type");
10545          if (utype) {
10546             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10547                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10548                if (user) {
10549                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10550                   user = user_unref(user);
10551                }
10552             }
10553             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10554                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10555                if (peer) {
10556                   if (ast_test_flag(peer, IAX_DYNAMIC))
10557                      reg_source_db(peer);
10558                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10559                   peer = peer_unref(peer);
10560                }
10561             } else if (strcasecmp(utype, "user")) {
10562                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10563             }
10564          } else
10565             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10566       }
10567       cat = ast_category_browse(cfg, cat);
10568    }
10569    ast_config_destroy(cfg);
10570    set_timing();
10571    return 1;
10572 }
10573 
10574 static void poke_all_peers(void)
10575 {
10576    struct ao2_iterator i;
10577    struct iax2_peer *peer;
10578 
10579    i = ao2_iterator_init(peers, 0);
10580    while ((peer = ao2_iterator_next(&i))) {
10581       iax2_poke_peer(peer, 0);
10582       peer_unref(peer);
10583    }
10584 }
10585 static int reload_config(void)
10586 {
10587    char *config = "iax.conf";
10588    struct iax2_registry *reg;
10589 
10590    if (set_config(config, 1) > 0) {
10591       prune_peers();
10592       prune_users();
10593       AST_LIST_LOCK(&registrations);
10594       AST_LIST_TRAVERSE(&registrations, reg, entry)
10595          iax2_do_register(reg);
10596       AST_LIST_UNLOCK(&registrations);
10597       /* Qualify hosts, too */
10598       poke_all_peers();
10599    }
10600    reload_firmware(0);
10601    iax_provision_reload();
10602 
10603    return 0;
10604 }
10605 
10606 static int iax2_reload(int fd, int argc, char *argv[])
10607 {
10608    return reload_config();
10609 }
10610 
10611 static int reload(void)
10612 {
10613    return reload_config();
10614 }
10615 
10616 static int cache_get_callno_locked(const char *data)
10617 {
10618    struct sockaddr_in sin;
10619    int x;
10620    int callno;
10621    struct iax_ie_data ied;
10622    struct create_addr_info cai;
10623    struct parsed_dial_string pds;
10624    char *tmpstr;
10625 
10626    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10627       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10628          look up entries for a single context */
10629       if (!ast_mutex_trylock(&iaxsl[x])) {
10630          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10631             return x;
10632          ast_mutex_unlock(&iaxsl[x]);
10633       }
10634    }
10635 
10636    /* No match found, we need to create a new one */
10637 
10638    memset(&cai, 0, sizeof(cai));
10639    memset(&ied, 0, sizeof(ied));
10640    memset(&pds, 0, sizeof(pds));
10641 
10642    tmpstr = ast_strdupa(data);
10643    parse_dial_string(tmpstr, &pds);
10644 
10645    if (ast_strlen_zero(pds.peer)) {
10646       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10647       return -1;
10648    }
10649 
10650    /* Populate our address from the given */
10651    if (create_addr(pds.peer, NULL, &sin, &cai))
10652       return -1;
10653 
10654    if (option_debug)
10655       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10656          pds.peer, pds.username, pds.password, pds.context);
10657 
10658    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10659    if (callno < 1) {
10660       ast_log(LOG_WARNING, "Unable to create call\n");
10661       return -1;
10662    }
10663 
10664    ast_string_field_set(iaxs[callno], dproot, data);
10665    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10666 
10667    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10668    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10669    /* the string format is slightly different from a standard dial string,
10670       because the context appears in the 'exten' position
10671    */
10672    if (pds.exten)
10673       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10674    if (pds.username)
10675       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10676    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10677    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10678    /* Keep password handy */
10679    if (pds.password)
10680       ast_string_field_set(iaxs[callno], secret, pds.password);
10681    if (pds.key)
10682       ast_string_field_set(iaxs[callno], outkey, pds.key);
10683    /* Start the call going */
10684    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10685 
10686    return callno;
10687 }
10688 
10689 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10690 {
10691    struct iax2_dpcache *dp, *prev = NULL, *next;
10692    struct timeval tv;
10693    int x;
10694    int com[2];
10695    int timeout;
10696    int old=0;
10697    int outfd;
10698    int abort;
10699    int callno;
10700    struct ast_channel *c;
10701    struct ast_frame *f;
10702    gettimeofday(&tv, NULL);
10703    dp = dpcache;
10704    while(dp) {
10705       next = dp->next;
10706       /* Expire old caches */
10707       if (ast_tvcmp(tv, dp->expiry) > 0) {
10708             /* It's expired, let it disappear */
10709             if (prev)
10710                prev->next = dp->next;
10711             else
10712                dpcache = dp->next;
10713             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10714                /* Free memory and go again */
10715                free(dp);
10716             } else {
10717                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);
10718             }
10719             dp = next;
10720             continue;
10721       }
10722       /* We found an entry that matches us! */
10723       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10724          break;
10725       prev = dp;
10726       dp = next;
10727    }
10728    if (!dp) {
10729       /* No matching entry.  Create a new one. */
10730       /* First, can we make a callno? */
10731       callno = cache_get_callno_locked(data);
10732       if (callno < 0) {
10733          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10734          return NULL;
10735       }
10736       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10737          ast_mutex_unlock(&iaxsl[callno]);
10738          return NULL;
10739       }
10740       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10741       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10742       gettimeofday(&dp->expiry, NULL);
10743       dp->orig = dp->expiry;
10744       /* Expires in 30 mins by default */
10745       dp->expiry.tv_sec += iaxdefaultdpcache;
10746       dp->next = dpcache;
10747       dp->flags = CACHE_FLAG_PENDING;
10748       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10749          dp->waiters[x] = -1;
10750       dpcache = dp;
10751       dp->peer = iaxs[callno]->dpentries;
10752       iaxs[callno]->dpentries = dp;
10753       /* Send the request if we're already up */
10754       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10755          iax2_dprequest(dp, callno);
10756       ast_mutex_unlock(&iaxsl[callno]);
10757    }
10758    /* By here we must have a dp */
10759    if (dp->flags & CACHE_FLAG_PENDING) {
10760       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10761          for a reply to come back so long as it's pending */
10762       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10763          /* Find an empty slot */
10764          if (dp->waiters[x] < 0)
10765             break;
10766       }
10767       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10768          ast_log(LOG_WARNING, "No more waiter positions available\n");
10769          return NULL;
10770       }
10771       if (pipe(com)) {
10772          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10773          return NULL;
10774       }
10775       dp->waiters[x] = com[1];
10776       /* Okay, now we wait */
10777       timeout = iaxdefaulttimeout * 1000;
10778       /* Temporarily unlock */
10779       ast_mutex_unlock(&dpcache_lock);
10780       /* Defer any dtmf */
10781       if (chan)
10782          old = ast_channel_defer_dtmf(chan);
10783       abort = 0;
10784       while(timeout) {
10785          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10786          if (outfd > -1) {
10787             break;
10788          }
10789          if (c) {
10790             f = ast_read(c);
10791             if (f)
10792                ast_frfree(f);
10793             else {
10794                /* Got hung up on, abort! */
10795                break;
10796                abort = 1;
10797             }
10798          }
10799       }
10800       if (!timeout) {
10801          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10802       }
10803       ast_mutex_lock(&dpcache_lock);
10804       dp->waiters[x] = -1;
10805       close(com[1]);
10806       close(com[0]);
10807       if (abort) {
10808          /* Don't interpret anything, just abort.  Not sure what th epoint
10809            of undeferring dtmf on a hung up channel is but hey whatever */
10810          if (!old && chan)
10811             ast_channel_undefer_dtmf(chan);
10812          return NULL;
10813       }
10814       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10815          /* Now to do non-independent analysis the results of our wait */
10816          if (dp->flags & CACHE_FLAG_PENDING) {
10817             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10818                pending.  Don't let it take as long to timeout. */
10819             dp->flags &= ~CACHE_FLAG_PENDING;
10820             dp->flags |= CACHE_FLAG_TIMEOUT;
10821             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10822                systems without leaving it unavailable once the server comes back online */
10823             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10824             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
10825                if (dp->waiters[x] > -1) {
10826                   if (write(dp->waiters[x], "asdf", 4) < 0) {
10827                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10828                   }
10829                }
10830             }
10831          }
10832       }
10833       /* Our caller will obtain the rest */
10834       if (!old && chan)
10835          ast_channel_undefer_dtmf(chan);
10836    }
10837    return dp;  
10838 }
10839 
10840 /*! \brief Part of the IAX2 switch interface */
10841 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10842 {
10843    struct iax2_dpcache *dp;
10844    int res = 0;
10845 #if 0
10846    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10847 #endif
10848    if ((priority != 1) && (priority != 2))
10849       return 0;
10850    ast_mutex_lock(&dpcache_lock);
10851    dp = find_cache(chan, data, context, exten, priority);
10852    if (dp) {
10853       if (dp->flags & CACHE_FLAG_EXISTS)
10854          res= 1;
10855    }
10856    ast_mutex_unlock(&dpcache_lock);
10857    if (!dp) {
10858       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10859    }
10860    return res;
10861 }
10862 
10863 /*! \brief part of the IAX2 dial plan switch interface */
10864 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10865 {
10866    int res = 0;
10867    struct iax2_dpcache *dp;
10868 #if 0
10869    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10870 #endif
10871    if ((priority != 1) && (priority != 2))
10872       return 0;
10873    ast_mutex_lock(&dpcache_lock);
10874    dp = find_cache(chan, data, context, exten, priority);
10875    if (dp) {
10876       if (dp->flags & CACHE_FLAG_CANEXIST)
10877          res= 1;
10878    }
10879    ast_mutex_unlock(&dpcache_lock);
10880    if (!dp) {
10881       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10882    }
10883    return res;
10884 }
10885 
10886 /*! \brief Part of the IAX2 Switch interface */
10887 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10888 {
10889    int res = 0;
10890    struct iax2_dpcache *dp;
10891 #if 0
10892    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10893 #endif
10894    if ((priority != 1) && (priority != 2))
10895       return 0;
10896    ast_mutex_lock(&dpcache_lock);
10897    dp = find_cache(chan, data, context, exten, priority);
10898    if (dp) {
10899       if (dp->flags & CACHE_FLAG_MATCHMORE)
10900          res= 1;
10901    }
10902    ast_mutex_unlock(&dpcache_lock);
10903    if (!dp) {
10904       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10905    }
10906    return res;
10907 }
10908 
10909 /*! \brief Execute IAX2 dialplan switch */
10910 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10911 {
10912    char odata[256];
10913    char req[256];
10914    char *ncontext;
10915    struct iax2_dpcache *dp;
10916    struct ast_app *dial;
10917 #if 0
10918    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);
10919 #endif
10920    if (priority == 2) {
10921       /* Indicate status, can be overridden in dialplan */
10922       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10923       if (dialstatus) {
10924          dial = pbx_findapp(dialstatus);
10925          if (dial) 
10926             pbx_exec(chan, dial, "");
10927       }
10928       return -1;
10929    } else if (priority != 1)
10930       return -1;
10931    ast_mutex_lock(&dpcache_lock);
10932    dp = find_cache(chan, data, context, exten, priority);
10933    if (dp) {
10934       if (dp->flags & CACHE_FLAG_EXISTS) {
10935          ast_copy_string(odata, data, sizeof(odata));
10936          ncontext = strchr(odata, '/');
10937          if (ncontext) {
10938             *ncontext = '\0';
10939             ncontext++;
10940             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10941          } else {
10942             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10943          }
10944          if (option_verbose > 2)
10945             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10946       } else {
10947          ast_mutex_unlock(&dpcache_lock);
10948          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10949          return -1;
10950       }
10951    }
10952    ast_mutex_unlock(&dpcache_lock);
10953    dial = pbx_findapp("Dial");
10954    if (dial) {
10955       return pbx_exec(chan, dial, req);
10956    } else {
10957       ast_log(LOG_WARNING, "No dial application registered\n");
10958    }
10959    return -1;
10960 }
10961 
10962 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10963 {
10964    struct iax2_peer *peer;
10965    char *peername, *colname;
10966 
10967    peername = ast_strdupa(data);
10968 
10969    /* if our channel, return the IP address of the endpoint of current channel */
10970    if (!strcmp(peername,"CURRENTCHANNEL")) {
10971            unsigned short callno;
10972       if (chan->tech != &iax2_tech)
10973          return -1;
10974       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10975       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10976       return 0;
10977    }
10978 
10979    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10980       *colname++ = '\0';
10981    else if ((colname = strchr(peername, '|')))
10982       *colname++ = '\0';
10983    else
10984       colname = "ip";
10985 
10986    if (!(peer = find_peer(peername, 1)))
10987       return -1;
10988 
10989    if (!strcasecmp(colname, "ip")) {
10990       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10991    } else  if (!strcasecmp(colname, "status")) {
10992       peer_status(peer, buf, len); 
10993    } else  if (!strcasecmp(colname, "mailbox")) {
10994       ast_copy_string(buf, peer->mailbox, len);
10995    } else  if (!strcasecmp(colname, "context")) {
10996       ast_copy_string(buf, peer->context, len);
10997    } else  if (!strcasecmp(colname, "expire")) {
10998       snprintf(buf, len, "%d", peer->expire);
10999    } else  if (!strcasecmp(colname, "dynamic")) {
11000       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
11001    } else  if (!strcasecmp(colname, "callerid_name")) {
11002       ast_copy_string(buf, peer->cid_name, len);
11003    } else  if (!strcasecmp(colname, "callerid_num")) {
11004       ast_copy_string(buf, peer->cid_num, len);
11005    } else  if (!strcasecmp(colname, "codecs")) {
11006       ast_getformatname_multiple(buf, len -1, peer->capability);
11007    } else  if (!strncasecmp(colname, "codec[", 6)) {
11008       char *codecnum, *ptr;
11009       int index = 0, codec = 0;
11010       
11011       codecnum = strchr(colname, '[');
11012       *codecnum = '\0';
11013       codecnum++;
11014       if ((ptr = strchr(codecnum, ']'))) {
11015          *ptr = '\0';
11016       }
11017       index = atoi(codecnum);
11018       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11019          ast_copy_string(buf, ast_getformatname(codec), len);
11020       } else {
11021          buf[0] = '\0';
11022       }
11023    } else {
11024       buf[0] = '\0';
11025    }
11026 
11027    peer_unref(peer);
11028 
11029    return 0;
11030 }
11031 
11032 struct ast_custom_function iaxpeer_function = {
11033    .name = "IAXPEER",
11034    .synopsis = "Gets IAX peer information",
11035    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
11036    .read = function_iaxpeer,
11037    .desc = "If peername specified, valid items are:\n"
11038    "- ip (default)          The IP address.\n"
11039    "- status                The peer's status (if qualify=yes)\n"
11040    "- mailbox               The configured mailbox.\n"
11041    "- context               The configured context.\n"
11042    "- expire                The epoch time of the next expire.\n"
11043    "- dynamic               Is it dynamic? (yes/no).\n"
11044    "- callerid_name         The configured Caller ID name.\n"
11045    "- callerid_num          The configured Caller ID number.\n"
11046    "- codecs                The configured codecs.\n"
11047    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
11048    "\n"
11049    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
11050    "\n"
11051 };
11052 
11053 
11054 /*! \brief Part of the device state notification system ---*/
11055 static int iax2_devicestate(void *data) 
11056 {
11057    struct parsed_dial_string pds;
11058    char *tmp = ast_strdupa(data);
11059    struct iax2_peer *p;
11060    int res = AST_DEVICE_INVALID;
11061 
11062    memset(&pds, 0, sizeof(pds));
11063    parse_dial_string(tmp, &pds);
11064 
11065    if (ast_strlen_zero(pds.peer)) {
11066       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11067       return res;
11068    }
11069    
11070    if (option_debug > 2)
11071       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
11072 
11073    /* SLD: FIXME: second call to find_peer during registration */
11074    if (!(p = find_peer(pds.peer, 1)))
11075       return res;
11076 
11077    res = AST_DEVICE_UNAVAILABLE;
11078    if (option_debug > 2) 
11079       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
11080          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
11081    
11082    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
11083        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
11084       /* Peer is registered, or have default IP address
11085          and a valid registration */
11086       if (p->historicms == 0 || p->historicms <= p->maxms)
11087          /* let the core figure out whether it is in use or not */
11088          res = AST_DEVICE_UNKNOWN;  
11089    }
11090 
11091    peer_unref(p);
11092 
11093    return res;
11094 }
11095 
11096 static struct ast_switch iax2_switch = 
11097 {
11098    name:          "IAX2",
11099    description:      "IAX Remote Dialplan Switch",
11100    exists:        iax2_exists,
11101    canmatch:      iax2_canmatch,
11102    exec:       iax2_exec,
11103    matchmore:     iax2_matchmore,
11104 };
11105 
11106 static char show_stats_usage[] =
11107 "Usage: iax2 show stats\n"
11108 "       Display statistics on IAX channel driver.\n";
11109 
11110 static char show_cache_usage[] =
11111 "Usage: iax2 show cache\n"
11112 "       Display currently cached IAX Dialplan results.\n";
11113 
11114 static char show_peer_usage[] =
11115 "Usage: iax2 show peer <name>\n"
11116 "       Display details on specific IAX peer\n";
11117 
11118 static char prune_realtime_usage[] =
11119 "Usage: iax2 prune realtime [<peername>|all]\n"
11120 "       Prunes object(s) from the cache\n";
11121 
11122 static char iax2_reload_usage[] =
11123 "Usage: iax2 reload\n"
11124 "       Reloads IAX configuration from iax.conf\n";
11125 
11126 static char show_prov_usage[] =
11127 "Usage: iax2 provision <host> <template> [forced]\n"
11128 "       Provisions the given peer or IP address using a template\n"
11129 "       matching either 'template' or '*' if the template is not\n"
11130 "       found.  If 'forced' is specified, even empty provisioning\n"
11131 "       fields will be provisioned as empty fields.\n";
11132 
11133 static char show_users_usage[] = 
11134 "Usage: iax2 show users [like <pattern>]\n"
11135 "       Lists all known IAX2 users.\n"
11136 "       Optional regular expression pattern is used to filter the user list.\n";
11137 
11138 static char show_channels_usage[] = 
11139 "Usage: iax2 show channels\n"
11140 "       Lists all currently active IAX channels.\n";
11141 
11142 static char show_netstats_usage[] = 
11143 "Usage: iax2 show netstats\n"
11144 "       Lists network status for all currently active IAX channels.\n";
11145 
11146 static char show_threads_usage[] = 
11147 "Usage: iax2 show threads\n"
11148 "       Lists status of IAX helper threads\n";
11149 
11150 static char show_peers_usage[] = 
11151 "Usage: iax2 show peers [registered] [like <pattern>]\n"
11152 "       Lists all known IAX2 peers.\n"
11153 "       Optional 'registered' argument lists only peers with known addresses.\n"
11154 "       Optional regular expression pattern is used to filter the peer list.\n";
11155 
11156 static char show_firmware_usage[] = 
11157 "Usage: iax2 show firmware\n"
11158 "       Lists all known IAX firmware images.\n";
11159 
11160 static char show_reg_usage[] =
11161 "Usage: iax2 show registry\n"
11162 "       Lists all registration requests and status.\n";
11163 
11164 static char debug_usage[] = 
11165 "Usage: iax2 set debug\n"
11166 "       Enables dumping of IAX packets for debugging purposes\n";
11167 
11168 static char no_debug_usage[] = 
11169 "Usage: iax2 set debug off\n"
11170 "       Disables dumping of IAX packets for debugging purposes\n";
11171 
11172 static char debug_trunk_usage[] =
11173 "Usage: iax2 set debug trunk\n"
11174 "       Requests current status of IAX trunking\n";
11175 
11176 static char no_debug_trunk_usage[] =
11177 "Usage: iax2 set debug trunk off\n"
11178 "       Requests current status of IAX trunking\n";
11179 
11180 static char debug_jb_usage[] =
11181 "Usage: iax2 set debug jb\n"
11182 "       Enables jitterbuffer debugging information\n";
11183 
11184 static char no_debug_jb_usage[] =
11185 "Usage: iax2 set debug jb off\n"
11186 "       Disables jitterbuffer debugging information\n";
11187 
11188 static char iax2_test_losspct_usage[] =
11189 "Usage: iax2 test losspct <percentage>\n"
11190 "       For testing, throws away <percentage> percent of incoming packets\n";
11191 
11192 #ifdef IAXTESTS
11193 static char iax2_test_late_usage[] =
11194 "Usage: iax2 test late <ms>\n"
11195 "       For testing, count the next frame as <ms> ms late\n";
11196 
11197 static char iax2_test_resync_usage[] =
11198 "Usage: iax2 test resync <ms>\n"
11199 "       For testing, adjust all future frames by <ms> ms\n";
11200 
11201 static char iax2_test_jitter_usage[] =
11202 "Usage: iax2 test jitter <ms> <pct>\n"
11203 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
11204 #endif /* IAXTESTS */
11205 
11206 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
11207    { "iax2", "trunk", "debug", NULL },
11208    iax2_do_trunk_debug, NULL,
11209    NULL };
11210 
11211 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
11212    { "iax2", "jb", "debug", NULL },
11213    iax2_do_jb_debug, NULL,
11214    NULL };
11215 
11216 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
11217    { "iax2", "no", "debug", NULL },
11218    iax2_no_debug, NULL,
11219    NULL };
11220 
11221 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
11222    { "iax2", "no", "trunk", "debug", NULL },
11223    iax2_no_trunk_debug, NULL,
11224    NULL };
11225 
11226 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
11227    { "iax2", "no", "jb", "debug", NULL },
11228    iax2_no_jb_debug, NULL,
11229    NULL };
11230 
11231 static struct ast_cli_entry cli_iax2[] = {
11232    { { "iax2", "show", "cache", NULL },
11233    iax2_show_cache, "Display IAX cached dialplan",
11234    show_cache_usage, NULL, },
11235 
11236    { { "iax2", "show", "channels", NULL },
11237    iax2_show_channels, "List active IAX channels",
11238    show_channels_usage, NULL, },
11239 
11240    { { "iax2", "show", "firmware", NULL },
11241    iax2_show_firmware, "List available IAX firmwares",
11242    show_firmware_usage, NULL, },
11243 
11244    { { "iax2", "show", "netstats", NULL },
11245    iax2_show_netstats, "List active IAX channel netstats",
11246    show_netstats_usage, NULL, },
11247 
11248    { { "iax2", "show", "peers", NULL },
11249    iax2_show_peers, "List defined IAX peers",
11250    show_peers_usage, NULL, },
11251 
11252    { { "iax2", "show", "registry", NULL },
11253    iax2_show_registry, "Display IAX registration status",
11254    show_reg_usage, NULL, },
11255 
11256    { { "iax2", "show", "stats", NULL },
11257    iax2_show_stats, "Display IAX statistics",
11258    show_stats_usage, NULL, },
11259 
11260    { { "iax2", "show", "threads", NULL },
11261    iax2_show_threads, "Display IAX helper thread info",
11262    show_threads_usage, NULL, },
11263 
11264    { { "iax2", "show", "users", NULL },
11265    iax2_show_users, "List defined IAX users",
11266    show_users_usage, NULL, },
11267 
11268    { { "iax2", "prune", "realtime", NULL },
11269    iax2_prune_realtime, "Prune a cached realtime lookup",
11270    prune_realtime_usage, complete_iax2_show_peer },
11271 
11272    { { "iax2", "reload", NULL },
11273    iax2_reload, "Reload IAX configuration",
11274    iax2_reload_usage },
11275 
11276    { { "iax2", "show", "peer", NULL },
11277    iax2_show_peer, "Show details on specific IAX peer",
11278    show_peer_usage, complete_iax2_show_peer },
11279 
11280    { { "iax2", "set", "debug", NULL },
11281    iax2_do_debug, "Enable IAX debugging",
11282    debug_usage },
11283 
11284    { { "iax2", "set", "debug", "trunk", NULL },
11285    iax2_do_trunk_debug, "Enable IAX trunk debugging",
11286    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
11287 
11288    { { "iax2", "set", "debug", "jb", NULL },
11289    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
11290    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
11291 
11292    { { "iax2", "set", "debug", "off", NULL },
11293    iax2_no_debug, "Disable IAX debugging",
11294    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
11295 
11296    { { "iax2", "set", "debug", "trunk", "off", NULL },
11297    iax2_no_trunk_debug, "Disable IAX trunk debugging",
11298    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
11299 
11300    { { "iax2", "set", "debug", "jb", "off", NULL },
11301    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
11302    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
11303 
11304    { { "iax2", "test", "losspct", NULL },
11305    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
11306    iax2_test_losspct_usage },
11307 
11308    { { "iax2", "provision", NULL },
11309    iax2_prov_cmd, "Provision an IAX device",
11310    show_prov_usage, iax2_prov_complete_template_3rd },
11311 
11312 #ifdef IAXTESTS
11313    { { "iax2", "test", "late", NULL },
11314    iax2_test_late, "Test the receipt of a late frame",
11315    iax2_test_late_usage },
11316 
11317    { { "iax2", "test", "resync", NULL },
11318    iax2_test_resync, "Test a resync in received timestamps",
11319    iax2_test_resync_usage },
11320 
11321    { { "iax2", "test", "jitter", NULL },
11322    iax2_test_jitter, "Simulates jitter for testing",
11323    iax2_test_jitter_usage },
11324 #endif /* IAXTESTS */
11325 };
11326 
11327 static int __unload_module(void)
11328 {
11329    struct iax2_thread *thread = NULL;
11330    int x;
11331 
11332    /* Make sure threads do not hold shared resources when they are canceled */
11333    
11334    /* Grab the sched lock resource to keep it away from threads about to die */
11335    /* Cancel the network thread, close the net socket */
11336    if (netthreadid != AST_PTHREADT_NULL) {
11337       AST_LIST_LOCK(&iaxq.queue);
11338       ast_mutex_lock(&sched_lock);
11339       pthread_cancel(netthreadid);
11340       ast_cond_signal(&sched_cond);
11341       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11342       AST_LIST_UNLOCK(&iaxq.queue);
11343       pthread_join(netthreadid, NULL);
11344    }
11345    if (schedthreadid != AST_PTHREADT_NULL) {
11346       ast_mutex_lock(&sched_lock);  
11347       pthread_cancel(schedthreadid);
11348       ast_cond_signal(&sched_cond);
11349       ast_mutex_unlock(&sched_lock);   
11350       pthread_join(schedthreadid, NULL);
11351    }
11352    
11353    /* Call for all threads to halt */
11354    AST_LIST_LOCK(&idle_list);
11355    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11356       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11357       pthread_cancel(thread->threadid);
11358    }
11359    AST_LIST_TRAVERSE_SAFE_END
11360    AST_LIST_UNLOCK(&idle_list);
11361 
11362    AST_LIST_LOCK(&active_list);
11363    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11364       AST_LIST_REMOVE_CURRENT(&active_list, list);
11365       pthread_cancel(thread->threadid);
11366    }
11367    AST_LIST_TRAVERSE_SAFE_END
11368    AST_LIST_UNLOCK(&active_list);
11369 
11370    AST_LIST_LOCK(&dynamic_list);
11371         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11372       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11373       pthread_cancel(thread->threadid);
11374         }
11375    AST_LIST_TRAVERSE_SAFE_END
11376         AST_LIST_UNLOCK(&dynamic_list);
11377 
11378    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11379 
11380    /* Wait for threads to exit */
11381    while(0 < iaxactivethreadcount)
11382       usleep(10000);
11383    
11384    ast_netsock_release(netsock);
11385    ast_netsock_release(outsock);
11386    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11387       if (iaxs[x]) {
11388          iax2_destroy(x);
11389       }
11390    }
11391    ast_manager_unregister( "IAXpeers" );
11392    ast_manager_unregister( "IAXnetstats" );
11393    ast_unregister_application(papp);
11394    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11395    ast_unregister_switch(&iax2_switch);
11396    ast_channel_unregister(&iax2_tech);
11397    delete_users();
11398    iax_provision_unload();
11399    sched_context_destroy(sched);
11400    reload_firmware(1);
11401 
11402    ast_mutex_destroy(&waresl.lock);
11403 
11404    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11405       ast_mutex_destroy(&iaxsl[x]);
11406    }
11407 
11408    ao2_ref(peers, -1);
11409    ao2_ref(users, -1);
11410    ao2_ref(iax_peercallno_pvts, -1);
11411    ao2_ref(iax_transfercallno_pvts, -1);  
11412 
11413    return 0;
11414 }
11415 
11416 static int unload_module(void)
11417 {
11418    ast_custom_function_unregister(&iaxpeer_function);
11419    return __unload_module();
11420 }
11421 
11422 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11423 {
11424    struct iax2_peer *peer = obj;
11425 
11426    if (peer->sockfd < 0)
11427       peer->sockfd = defaultsockfd;
11428 
11429    return 0;
11430 }
11431 
11432 static int pvt_hash_cb(const void *obj, const int flags)
11433 {
11434    const struct chan_iax2_pvt *pvt = obj;
11435 
11436    return pvt->peercallno;
11437 }
11438 
11439 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11440 {
11441    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11442 
11443    /* The frames_received field is used to hold whether we're matching
11444     * against a full frame or not ... */
11445 
11446    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11447       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11448 }
11449 
11450 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
11451 {
11452    const struct chan_iax2_pvt *pvt = obj;
11453 
11454    return pvt->transfercallno;
11455 }
11456 
11457 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
11458 {
11459    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11460 
11461    /* The frames_received field is used to hold whether we're matching
11462     * against a full frame or not ... */
11463 
11464    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
11465       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11466 }
11467 /*! \brief Load IAX2 module, load configuraiton ---*/
11468 static int load_module(void)
11469 {
11470    char *config = "iax.conf";
11471    int res = 0;
11472    int x;
11473    struct iax2_registry *reg = NULL;
11474 
11475    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11476    if (!peers)
11477       return AST_MODULE_LOAD_FAILURE;
11478    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11479    if (!users) {
11480       ao2_ref(peers, -1);
11481       return AST_MODULE_LOAD_FAILURE;
11482    }
11483    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11484    if (!iax_peercallno_pvts) {
11485       ao2_ref(peers, -1);
11486       ao2_ref(users, -1);
11487       return AST_MODULE_LOAD_FAILURE;
11488    }
11489    iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
11490    if (!iax_transfercallno_pvts) {
11491       ao2_ref(peers, -1);
11492       ao2_ref(users, -1);
11493       ao2_ref(iax_peercallno_pvts, -1);
11494       return AST_MODULE_LOAD_FAILURE;
11495    }
11496    ast_custom_function_register(&iaxpeer_function);
11497 
11498    iax_set_output(iax_debug_output);
11499    iax_set_error(iax_error_output);
11500    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11501    
11502 #ifdef HAVE_DAHDI
11503 #ifdef DAHDI_TIMERACK
11504    timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
11505    if (timingfd < 0)
11506 #endif
11507       timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
11508    if (timingfd < 0) 
11509       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11510 #endif
11511 
11512    memset(iaxs, 0, sizeof(iaxs));
11513 
11514    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11515       ast_mutex_init(&iaxsl[x]);
11516    }
11517    
11518    ast_cond_init(&sched_cond, NULL);
11519 
11520    io = io_context_create();
11521    sched = sched_context_create();
11522    
11523    if (!io || !sched) {
11524       ast_log(LOG_ERROR, "Out of memory\n");
11525       return -1;
11526    }
11527 
11528    netsock = ast_netsock_list_alloc();
11529    if (!netsock) {
11530       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11531       return -1;
11532    }
11533    ast_netsock_init(netsock);
11534 
11535    outsock = ast_netsock_list_alloc();
11536    if (!outsock) {
11537       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11538       return -1;
11539    }
11540    ast_netsock_init(outsock);
11541 
11542    ast_mutex_init(&waresl.lock);
11543 
11544    AST_LIST_HEAD_INIT(&iaxq.queue);
11545    
11546    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11547 
11548    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11549    
11550    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11551    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11552 
11553    if(set_config(config, 0) == -1)
11554       return AST_MODULE_LOAD_DECLINE;
11555 
11556    if (ast_channel_register(&iax2_tech)) {
11557       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11558       __unload_module();
11559       return -1;
11560    }
11561 
11562    if (ast_register_switch(&iax2_switch)) 
11563       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11564 
11565    res = start_network_thread();
11566    if (!res) {
11567       if (option_verbose > 1) 
11568          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11569    } else {
11570       ast_log(LOG_ERROR, "Unable to start network thread\n");
11571       ast_netsock_release(netsock);
11572       ast_netsock_release(outsock);
11573    }
11574 
11575    AST_LIST_LOCK(&registrations);
11576    AST_LIST_TRAVERSE(&registrations, reg, entry)
11577       iax2_do_register(reg);
11578    AST_LIST_UNLOCK(&registrations); 
11579 
11580    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11581    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11582 
11583    reload_firmware(0);
11584    iax_provision_reload();
11585    return res;
11586 }
11587 
11588 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11589       .load = load_module,
11590       .unload = unload_module,
11591       .reload = reload,
11592           );

Generated on Tue Jul 14 23:09:43 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7