Fri Jul 24 00:40:47 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  * \todo Implement musicclass settings for IAX2 devices
00031  */
00032 
00033 /*** MODULEINFO
00034    <use>crypto</use>
00035  ***/
00036 
00037 #include "asterisk.h"
00038 
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 199209 $")
00040 
00041 #include <sys/mman.h>
00042 #include <dirent.h>
00043 #include <sys/socket.h>
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include <netinet/in_systm.h>
00047 #include <netinet/ip.h>
00048 #include <sys/time.h>
00049 #include <sys/signal.h>
00050 #include <signal.h>
00051 #include <strings.h>
00052 #include <netdb.h>
00053 #include <fcntl.h>
00054 #include <sys/stat.h>
00055 #include <regex.h>
00056 
00057 #include "asterisk/paths.h"   /* need ast_config_AST_DATA_DIR for firmware */
00058 
00059 #include "asterisk/lock.h"
00060 #include "asterisk/frame.h" 
00061 #include "asterisk/channel.h"
00062 #include "asterisk/module.h"
00063 #include "asterisk/pbx.h"
00064 #include "asterisk/sched.h"
00065 #include "asterisk/io.h"
00066 #include "asterisk/config.h"
00067 #include "asterisk/cli.h"
00068 #include "asterisk/translate.h"
00069 #include "asterisk/md5.h"
00070 #include "asterisk/cdr.h"
00071 #include "asterisk/crypto.h"
00072 #include "asterisk/acl.h"
00073 #include "asterisk/manager.h"
00074 #include "asterisk/callerid.h"
00075 #include "asterisk/app.h"
00076 #include "asterisk/astdb.h"
00077 #include "asterisk/musiconhold.h"
00078 #include "asterisk/features.h"
00079 #include "asterisk/utils.h"
00080 #include "asterisk/causes.h"
00081 #include "asterisk/localtime.h"
00082 #include "asterisk/aes.h"
00083 #include "asterisk/dnsmgr.h"
00084 #include "asterisk/devicestate.h"
00085 #include "asterisk/netsock.h"
00086 #include "asterisk/stringfields.h"
00087 #include "asterisk/linkedlists.h"
00088 #include "asterisk/event.h"
00089 #include "asterisk/astobj2.h"
00090 #include "asterisk/timing.h"
00091 
00092 #include "iax2.h"
00093 #include "iax2-parser.h"
00094 #include "iax2-provision.h"
00095 #include "jitterbuf.h"
00096 
00097 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00098    multithreaded mode. */
00099 #define SCHED_MULTITHREADED
00100 
00101 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00102    thread is actually doing. */
00103 #define DEBUG_SCHED_MULTITHREAD
00104 
00105 
00106 #ifdef SO_NO_CHECK
00107 static int nochecksums = 0;
00108 #endif
00109 
00110 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00111 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00112 
00113 #define DEFAULT_THREAD_COUNT 10
00114 #define DEFAULT_MAX_THREAD_COUNT 100
00115 #define DEFAULT_RETRY_TIME 1000
00116 #define MEMORY_SIZE 100
00117 #define DEFAULT_DROP 3
00118 
00119 #define DEBUG_SUPPORT
00120 
00121 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00122 
00123 /* Sample over last 100 units to determine historic jitter */
00124 #define GAMMA (0.01)
00125 
00126 static struct ast_codec_pref prefs;
00127 
00128 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00129 
00130 
00131 /*! \brief Maximum transmission unit for the UDP packet in the trunk not to be
00132     fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240 */
00133 #define MAX_TRUNK_MTU 1240 
00134 
00135 static int global_max_trunk_mtu;    /*!< Maximum MTU, 0 if not used */
00136 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;    /*!< Trunk MTU statistics */
00137 
00138 #define DEFAULT_CONTEXT "default"
00139 
00140 static char default_parkinglot[AST_MAX_CONTEXT];
00141 
00142 static char language[MAX_LANGUAGE] = "";
00143 static char regcontext[AST_MAX_CONTEXT] = "";
00144 
00145 static int maxauthreq = 3;
00146 static int max_retries = 4;
00147 static int ping_time = 21;
00148 static int lagrq_time = 10;
00149 static int maxjitterbuffer=1000;
00150 static int resyncthreshold=1000;
00151 static int maxjitterinterps=10;
00152 static int jittertargetextra = 40; /* number of milliseconds the new jitter buffer adds on to its size */
00153 
00154 #define MAX_TRUNKDATA           640 * 200       /*!< 40ms, uncompressed linear * 200 channels */
00155 
00156 static int trunkfreq = 20;
00157 static int trunkmaxsize = MAX_TRUNKDATA;
00158 
00159 static int authdebug = 1;
00160 static int autokill = 0;
00161 static int iaxcompat = 0;
00162 static int last_authmethod = 0;
00163 
00164 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00165 
00166 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00167 
00168 static struct {
00169    unsigned int tos;
00170    unsigned int cos;
00171 } qos = { 0, 0 };
00172 
00173 static int min_reg_expire;
00174 static int max_reg_expire;
00175 
00176 static int srvlookup = 0;
00177 
00178 static struct ast_timer *timer;           /* Timer for trunking */
00179 
00180 static struct ast_netsock_list *netsock;
00181 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00182 static int defaultsockfd = -1;
00183 
00184 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00185 
00186 /* Ethernet, etc */
00187 #define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00188 /* T1, maybe ISDN */
00189 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00190                 ~AST_FORMAT_SLINEAR &        \
00191                 ~AST_FORMAT_SLINEAR16 &         \
00192                 ~AST_FORMAT_ULAW &        \
00193                 ~AST_FORMAT_ALAW &        \
00194                 ~AST_FORMAT_G722) 
00195 /* A modem */
00196 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00197                 ~AST_FORMAT_G726 &        \
00198                 ~AST_FORMAT_G726_AAL2 &      \
00199                 ~AST_FORMAT_ADPCM)
00200 
00201 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00202                 ~AST_FORMAT_G723_1)
00203 
00204 
00205 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00206 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00207 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00208 
00209 /* if a pvt has encryption setup done and is running on the call */
00210 #define IAX_CALLENCRYPTED(pvt) \
00211    (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00212 
00213 #define IAX_DEBUGDIGEST(msg, key) do { \
00214       int idx; \
00215       char digest[33] = ""; \
00216       \
00217       if (!iaxdebug) \
00218          break; \
00219       \
00220       for (idx = 0; idx < 16; idx++) \
00221          sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00222       \
00223       ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00224    } while(0)
00225 
00226 static   struct io_context *io;
00227 static   struct sched_context *sched;
00228 
00229 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00230 
00231 static int iaxdebug = 0;
00232 
00233 static int iaxtrunkdebug = 0;
00234 
00235 static int test_losspct = 0;
00236 #ifdef IAXTESTS
00237 static int test_late = 0;
00238 static int test_resync = 0;
00239 static int test_jit = 0;
00240 static int test_jitpct = 0;
00241 #endif /* IAXTESTS */
00242 
00243 static char accountcode[AST_MAX_ACCOUNT_CODE];
00244 static char mohinterpret[MAX_MUSICCLASS];
00245 static char mohsuggest[MAX_MUSICCLASS];
00246 static int amaflags = 0;
00247 static int adsi = 0;
00248 static int delayreject = 0;
00249 static int iax2_encryption = 0;
00250 
00251 static struct ast_flags globalflags = { 0 };
00252 
00253 static pthread_t netthreadid = AST_PTHREADT_NULL;
00254 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00255 AST_MUTEX_DEFINE_STATIC(sched_lock);
00256 static ast_cond_t sched_cond;
00257 
00258 enum iax2_state {
00259    IAX_STATE_STARTED =        (1 << 0),
00260    IAX_STATE_AUTHENTICATED =  (1 << 1),
00261    IAX_STATE_TBD =            (1 << 2),
00262 };
00263 
00264 struct iax2_context {
00265    char context[AST_MAX_CONTEXT];
00266    struct iax2_context *next;
00267 };
00268 
00269 enum iax2_flags {
00270    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00271    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00272    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00273    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00274    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00275    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00276    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00277    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00278         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00279    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00280    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00281    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00282    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00283    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00284    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00285    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00286    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00287    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00288    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00289    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00290    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00291    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00292    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00293    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00294    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00295    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00296                        response, so that we've achieved a three-way handshake with
00297                        them before sending voice or anything else*/
00298    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00299 };
00300 
00301 static int global_rtautoclear = 120;
00302 
00303 static int reload_config(void);
00304 
00305 struct iax2_user {
00306    AST_DECLARE_STRING_FIELDS(
00307       AST_STRING_FIELD(name);
00308       AST_STRING_FIELD(secret);
00309       AST_STRING_FIELD(dbsecret);
00310       AST_STRING_FIELD(accountcode);
00311       AST_STRING_FIELD(mohinterpret);
00312       AST_STRING_FIELD(mohsuggest);
00313       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00314       AST_STRING_FIELD(language);
00315       AST_STRING_FIELD(cid_num);
00316       AST_STRING_FIELD(cid_name);
00317       AST_STRING_FIELD(parkinglot);           /*!< Default parkinglot for device */
00318    );
00319    
00320    int authmethods;
00321    int encmethods;
00322    int amaflags;
00323    int adsi;
00324    unsigned int flags;
00325    int capability;
00326    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00327    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00328    struct ast_codec_pref prefs;
00329    struct ast_ha *ha;
00330    struct iax2_context *contexts;
00331    struct ast_variable *vars;
00332 };
00333 
00334 struct iax2_peer {
00335    AST_DECLARE_STRING_FIELDS(
00336       AST_STRING_FIELD(name);
00337       AST_STRING_FIELD(username);
00338       AST_STRING_FIELD(secret);
00339       AST_STRING_FIELD(dbsecret);
00340       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00341 
00342       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00343       AST_STRING_FIELD(context);      /*!< For transfers only */
00344       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00345       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00346       AST_STRING_FIELD(mohinterpret);
00347       AST_STRING_FIELD(mohsuggest);
00348       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00349       /* Suggested caller id if registering */
00350       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00351       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00352       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00353       AST_STRING_FIELD(parkinglot);   /*!< Default parkinglot for device */
00354    );
00355    struct ast_codec_pref prefs;
00356    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00357    struct sockaddr_in addr;
00358    int formats;
00359    int sockfd;             /*!< Socket to use for transmission */
00360    struct in_addr mask;
00361    int adsi;
00362    unsigned int flags;
00363 
00364    /* Dynamic Registration fields */
00365    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00366    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00367    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00368 
00369    int expire;             /*!< Schedule entry for expiry */
00370    int expiry;             /*!< How soon to expire */
00371    int capability;               /*!< Capability */
00372 
00373    /* Qualification */
00374    int callno;             /*!< Call number of POKE request */
00375    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00376    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00377    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00378 
00379    int pokefreqok;               /*!< How often to check if the host is up */
00380    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00381    int historicms;               /*!< How long recent average responses took */
00382    int smoothing;             /*!< Sample over how many units to determine historic ms */
00383 
00384    struct ast_event_sub *mwi_event_sub;
00385 
00386    struct ast_ha *ha;
00387 };
00388 
00389 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00390 
00391 struct iax2_trunk_peer {
00392    ast_mutex_t lock;
00393    int sockfd;
00394    struct sockaddr_in addr;
00395    struct timeval txtrunktime;      /*!< Transmit trunktime */
00396    struct timeval rxtrunktime;      /*!< Receive trunktime */
00397    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00398    struct timeval trunkact;      /*!< Last trunk activity */
00399    unsigned int lastsent;        /*!< Last sent time */
00400    /* Trunk data and length */
00401    unsigned char *trunkdata;
00402    unsigned int trunkdatalen;
00403    unsigned int trunkdataalloc;
00404    int trunkmaxmtu;
00405    int trunkerror;
00406    int calls;
00407    AST_LIST_ENTRY(iax2_trunk_peer) list;
00408 };
00409 
00410 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00411 
00412 struct iax_firmware {
00413    AST_LIST_ENTRY(iax_firmware) list;
00414    int fd;
00415    int mmaplen;
00416    int dead;
00417    struct ast_iax2_firmware_header *fwh;
00418    unsigned char *buf;
00419 };
00420 
00421 enum iax_reg_state {
00422    REG_STATE_UNREGISTERED = 0,
00423    REG_STATE_REGSENT,
00424    REG_STATE_AUTHSENT,
00425    REG_STATE_REGISTERED,
00426    REG_STATE_REJECTED,
00427    REG_STATE_TIMEOUT,
00428    REG_STATE_NOAUTH
00429 };
00430 
00431 enum iax_transfer_state {
00432    TRANSFER_NONE = 0,
00433    TRANSFER_BEGIN,
00434    TRANSFER_READY,
00435    TRANSFER_RELEASED,
00436    TRANSFER_PASSTHROUGH,
00437    TRANSFER_MBEGIN,
00438    TRANSFER_MREADY,
00439    TRANSFER_MRELEASED,
00440    TRANSFER_MPASSTHROUGH,
00441    TRANSFER_MEDIA,
00442    TRANSFER_MEDIAPASS
00443 };
00444 
00445 struct iax2_registry {
00446    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00447    char username[80];
00448    char secret[80];        /*!< Password or key name in []'s */
00449    int expire;          /*!< Sched ID of expiration */
00450    int refresh;            /*!< How often to refresh */
00451    enum iax_reg_state regstate;
00452    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00453    int callno;          /*!< Associated call number if applicable */
00454    struct sockaddr_in us;        /*!< Who the server thinks we are */
00455    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00456    AST_LIST_ENTRY(iax2_registry) entry;
00457 };
00458 
00459 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00460 
00461 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00462 #define MIN_RETRY_TIME     100
00463 #define MAX_RETRY_TIME     10000
00464 
00465 #define MAX_JITTER_BUFFER  50
00466 #define MIN_JITTER_BUFFER  10
00467 
00468 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00469 
00470 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00471 
00472 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00473 #define TS_GAP_FOR_JB_RESYNC  5000
00474 
00475 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00476 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00477 static int iaxdynamicthreadcount = 0;
00478 static int iaxdynamicthreadnum = 0;
00479 static int iaxactivethreadcount = 0;
00480 
00481 struct iax_rr {
00482    int jitter;
00483    int losspct;
00484    int losscnt;
00485    int packets;
00486    int delay;
00487    int dropped;
00488    int ooo;
00489 };
00490 
00491 struct iax2_pvt_ref;
00492 
00493 struct chan_iax2_pvt {
00494    /*! Socket to send/receive on for this call */
00495    int sockfd;
00496    /*! Last received voice format */
00497    int voiceformat;
00498    /*! Last received video format */
00499    int videoformat;
00500    /*! Last sent voice format */
00501    int svoiceformat;
00502    /*! Last sent video format */
00503    int svideoformat;
00504    /*! What we are capable of sending */
00505    int capability;
00506    /*! Last received timestamp */
00507    unsigned int last;
00508    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00509    unsigned int lastsent;
00510    /*! Timestamp of the last video frame sent */
00511    unsigned int lastvsent;
00512    /*! Next outgoing timestamp if everything is good */
00513    unsigned int nextpred;
00514    /*! True if the last voice we transmitted was not silence/CNG */
00515    unsigned int notsilenttx:1;
00516    /*! Ping time */
00517    unsigned int pingtime;
00518    /*! Max time for initial response */
00519    int maxtime;
00520    /*! Peer Address */
00521    struct sockaddr_in addr;
00522    /*! Actual used codec preferences */
00523    struct ast_codec_pref prefs;
00524    /*! Requested codec preferences */
00525    struct ast_codec_pref rprefs;
00526    /*! Our call number */
00527    unsigned short callno;
00528    /*! Peer callno */
00529    unsigned short peercallno;
00530    /*! Negotiated format, this is only used to remember what format was
00531        chosen for an unauthenticated call so that the channel can get
00532        created later using the right format */
00533    int chosenformat;
00534    /*! Peer selected format */
00535    int peerformat;
00536    /*! Peer capability */
00537    int peercapability;
00538    /*! timeval that we base our transmission on */
00539    struct timeval offset;
00540    /*! timeval that we base our delivery on */
00541    struct timeval rxcore;
00542    /*! The jitterbuffer */
00543    jitterbuf *jb;
00544    /*! active jb read scheduler id */
00545    int jbid;                       
00546    /*! LAG */
00547    int lag;
00548    /*! Error, as discovered by the manager */
00549    int error;
00550    /*! Owner if we have one */
00551    struct ast_channel *owner;
00552    /*! What's our state? */
00553    struct ast_flags state;
00554    /*! Expiry (optional) */
00555    int expiry;
00556    /*! Next outgoing sequence number */
00557    unsigned char oseqno;
00558    /*! Next sequence number they have not yet acknowledged */
00559    unsigned char rseqno;
00560    /*! Next incoming sequence number */
00561    unsigned char iseqno;
00562    /*! Last incoming sequence number we have acknowledged */
00563    unsigned char aseqno;
00564 
00565    AST_DECLARE_STRING_FIELDS(
00566       /*! Peer name */
00567       AST_STRING_FIELD(peer);
00568       /*! Default Context */
00569       AST_STRING_FIELD(context);
00570       /*! Caller ID if available */
00571       AST_STRING_FIELD(cid_num);
00572       AST_STRING_FIELD(cid_name);
00573       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00574       AST_STRING_FIELD(ani);
00575       /*! DNID */
00576       AST_STRING_FIELD(dnid);
00577       /*! RDNIS */
00578       AST_STRING_FIELD(rdnis);
00579       /*! Requested Extension */
00580       AST_STRING_FIELD(exten);
00581       /*! Expected Username */
00582       AST_STRING_FIELD(username);
00583       /*! Expected Secret */
00584       AST_STRING_FIELD(secret);
00585       /*! MD5 challenge */
00586       AST_STRING_FIELD(challenge);
00587       /*! Public keys permitted keys for incoming authentication */
00588       AST_STRING_FIELD(inkeys);
00589       /*! Private key for outgoing authentication */
00590       AST_STRING_FIELD(outkey);
00591       /*! Preferred language */
00592       AST_STRING_FIELD(language);
00593       /*! Hostname/peername for naming purposes */
00594       AST_STRING_FIELD(host);
00595 
00596       AST_STRING_FIELD(dproot);
00597       AST_STRING_FIELD(accountcode);
00598       AST_STRING_FIELD(mohinterpret);
00599       AST_STRING_FIELD(mohsuggest);
00600       /*! received OSP token */
00601       AST_STRING_FIELD(osptoken);
00602       /*! Default parkinglot */
00603       AST_STRING_FIELD(parkinglot);
00604    );
00605    /*! AUTHREJ all AUTHREP frames */
00606    int authrej;
00607    /*! permitted authentication methods */
00608    int authmethods;
00609    /*! permitted encryption methods */
00610    int encmethods;
00611    /*! Encryption AES-128 Key */
00612    ast_aes_encrypt_key ecx;
00613    /*! Decryption AES-128 Key corresponding to ecx */
00614    ast_aes_decrypt_key mydcx;
00615    /*! Decryption AES-128 Key used to decrypt peer frames */
00616    ast_aes_decrypt_key dcx;
00617    /*! scheduler id associated with iax_key_rotate 
00618     * for encrypted calls*/
00619    int keyrotateid;
00620    /*! 32 bytes of semi-random data */
00621    unsigned char semirand[32];
00622    /*! Associated registry */
00623    struct iax2_registry *reg;
00624    /*! Associated peer for poking */
00625    struct iax2_peer *peerpoke;
00626    /*! IAX_ flags */
00627    unsigned int flags;
00628    int adsi;
00629 
00630    /*! Transferring status */
00631    enum iax_transfer_state transferring;
00632    /*! Transfer identifier */
00633    int transferid;
00634    /*! Who we are IAX transferring to */
00635    struct sockaddr_in transfer;
00636    /*! What's the new call number for the transfer */
00637    unsigned short transfercallno;
00638    /*! Transfer encrypt AES-128 Key */
00639    ast_aes_encrypt_key tdcx;
00640 
00641    /*! Status of knowledge of peer ADSI capability */
00642    int peeradsicpe;
00643 
00644    /*! Who we are bridged to */
00645    unsigned short bridgecallno;
00646    
00647    int pingid;       /*!< Transmit PING request */
00648    int lagid;        /*!< Retransmit lag request */
00649    int autoid;       /*!< Auto hangup for Dialplan requestor */
00650    int authid;       /*!< Authentication rejection ID */
00651    int authfail;        /*!< Reason to report failure */
00652    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00653    int calling_ton;
00654    int calling_tns;
00655    int calling_pres;
00656    int amaflags;
00657    AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00658    /*! variables inherited from the user definition */
00659    struct ast_variable *vars;
00660    /*! variables transmitted in a NEW packet */
00661    struct ast_variable *iaxvars;
00662    /*! last received remote rr */
00663    struct iax_rr remote_rr;
00664    /*! Current base time: (just for stats) */
00665    int min;
00666    /*! Dropped frame count: (just for stats) */
00667    int frames_dropped;
00668    /*! received frame count: (just for stats) */
00669    int frames_received;
00670 };
00671 
00672 /*!
00673  * \brief a list of frames that may need to be retransmitted
00674  *
00675  * \note The contents of this list do not need to be explicitly destroyed
00676  * on module unload.  This is because all active calls are destroyed, and
00677  * all frames in this queue will get destroyed as a part of that process.
00678  */
00679 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00680 
00681 /*!
00682  * This module will get much higher performance when doing a lot of
00683  * user and peer lookups if the number of buckets is increased from 1.
00684  * However, to maintain old behavior for Asterisk 1.4, these are set to
00685  * 1 by default.  When using multiple buckets, search order through these
00686  * containers is considered random, so you will not be able to depend on
00687  * the order the entires are specified in iax.conf for matching order. */
00688 #ifdef LOW_MEMORY
00689 #define MAX_PEER_BUCKETS 17
00690 #else
00691 #define MAX_PEER_BUCKETS 563
00692 #endif
00693 static struct ao2_container *peers;
00694 
00695 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00696 static struct ao2_container *users;
00697 
00698 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00699 
00700 enum {
00701    /*! Extension exists */
00702    CACHE_FLAG_EXISTS      = (1 << 0),
00703    /*! Extension is nonexistent */
00704    CACHE_FLAG_NONEXISTENT = (1 << 1),
00705    /*! Extension can exist */
00706    CACHE_FLAG_CANEXIST    = (1 << 2),
00707    /*! Waiting to hear back response */
00708    CACHE_FLAG_PENDING     = (1 << 3),
00709    /*! Timed out */
00710    CACHE_FLAG_TIMEOUT     = (1 << 4),
00711    /*! Request transmitted */
00712    CACHE_FLAG_TRANSMITTED = (1 << 5),
00713    /*! Timeout */
00714    CACHE_FLAG_UNKNOWN     = (1 << 6),
00715    /*! Matchmore */
00716    CACHE_FLAG_MATCHMORE   = (1 << 7),
00717 };
00718 
00719 struct iax2_dpcache {
00720    char peercontext[AST_MAX_CONTEXT];
00721    char exten[AST_MAX_EXTENSION];
00722    struct timeval orig;
00723    struct timeval expiry;
00724    int flags;
00725    unsigned short callno;
00726    int waiters[256];
00727    AST_LIST_ENTRY(iax2_dpcache) cache_list;
00728    AST_LIST_ENTRY(iax2_dpcache) peer_list;
00729 };
00730 
00731 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00732 
00733 static void reg_source_db(struct iax2_peer *p);
00734 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00735 
00736 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00737 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state);
00738 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00739 
00740 enum iax2_thread_iostate {
00741    IAX_IOSTATE_IDLE,
00742    IAX_IOSTATE_READY,
00743    IAX_IOSTATE_PROCESSING,
00744    IAX_IOSTATE_SCHEDREADY,
00745 };
00746 
00747 enum iax2_thread_type {
00748    IAX_THREAD_TYPE_POOL,
00749    IAX_THREAD_TYPE_DYNAMIC,
00750 };
00751 
00752 struct iax2_pkt_buf {
00753    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00754    size_t len;
00755    unsigned char buf[1];
00756 };
00757 
00758 struct iax2_thread {
00759    AST_LIST_ENTRY(iax2_thread) list;
00760    enum iax2_thread_type type;
00761    enum iax2_thread_iostate iostate;
00762 #ifdef SCHED_MULTITHREADED
00763    void (*schedfunc)(const void *);
00764    const void *scheddata;
00765 #endif
00766 #ifdef DEBUG_SCHED_MULTITHREAD
00767    char curfunc[80];
00768 #endif   
00769    int actions;
00770    pthread_t threadid;
00771    int threadnum;
00772    struct sockaddr_in iosin;
00773    unsigned char readbuf[4096]; 
00774    unsigned char *buf;
00775    ssize_t buf_len;
00776    size_t buf_size;
00777    int iofd;
00778    time_t checktime;
00779    ast_mutex_t lock;
00780    ast_cond_t cond;
00781    ast_mutex_t init_lock;
00782    ast_cond_t init_cond;
00783    /*! if this thread is processing a full frame,
00784      some information about that frame will be stored
00785      here, so we can avoid dispatching any more full
00786      frames for that callno to other threads */
00787    struct {
00788       unsigned short callno;
00789       struct sockaddr_in sin;
00790       unsigned char type;
00791       unsigned char csub;
00792    } ffinfo;
00793    /*! Queued up full frames for processing.  If more full frames arrive for
00794     *  a call which this thread is already processing a full frame for, they
00795     *  are queued up here. */
00796    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00797 };
00798 
00799 /* Thread lists */
00800 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00801 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00802 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00803 
00804 static void *iax2_process_thread(void *data);
00805 static void iax2_destroy(int callno);
00806 
00807 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00808 {
00809    ast_mutex_lock(lock);
00810    ast_cond_signal(cond);
00811    ast_mutex_unlock(lock);
00812 }
00813 
00814 /*!
00815  * \brief an array of iax2 pvt structures
00816  *
00817  * The container for active chan_iax2_pvt structures is implemented as an
00818  * array for extremely quick direct access to the correct pvt structure
00819  * based on the local call number.  The local call number is used as the
00820  * index into the array where the associated pvt structure is stored.
00821  */
00822 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
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 chan_iax2_pvt structure locks
00837  *
00838  * These locks are used when accessing a pvt structure in the iaxs array.
00839  * The index used here is the same as used in the iaxs array.  It is the
00840  * local call number for the associated pvt struct.
00841  */
00842 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00843 
00844 /*!
00845  * \brief The last time a call number was used
00846  *
00847  * It is important to know the last time that a call number was used locally so
00848  * that it is not used again too soon.  The reason for this is the same as the
00849  * reason that the TCP protocol state machine requires a "TIME WAIT" state.
00850  *
00851  * For example, say that a call is up.  Then, the remote side sends a HANGUP,
00852  * which we respond to with an ACK.  However, there is no way to know whether
00853  * the ACK made it there successfully.  If it were to get lost, the remote
00854  * side may retransmit the HANGUP.  If in the meantime, this call number has
00855  * been reused locally, given the right set of circumstances, this retransmitted
00856  * HANGUP could potentially improperly hang up the new session.  So, to avoid
00857  * this potential issue, we must wait a specified timeout period before reusing
00858  * a local call number.
00859  *
00860  * The specified time that we must wait before reusing a local call number is
00861  * defined as MIN_REUSE_TIME, with a default of 60 seconds.
00862  */
00863 static struct timeval lastused[ARRAY_LEN(iaxs)];
00864 
00865 /*!
00866  *  * \brief Another container of iax2_pvt structures
00867  *  
00868  *  Active IAX2 pvt stucts used during transfering a call are stored here.  
00869  */
00870 static struct ao2_container *iax_transfercallno_pvts;
00871 
00872 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00873    but keeps the division between trunked and non-trunked better. */
00874 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00875 
00876 /* Debug routines... */
00877 static struct sockaddr_in debugaddr;
00878 
00879 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
00880 {
00881    if (iaxdebug ||
00882        (sin && debugaddr.sin_addr.s_addr && 
00883         (!ntohs(debugaddr.sin_port) ||
00884          debugaddr.sin_port == sin->sin_port) &&
00885         debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00886       if (iaxdebug) {
00887          iax_showframe(f, fhi, rx, sin, datalen);
00888       } else {
00889          iaxdebug = 1;
00890          iax_showframe(f, fhi, rx, sin, datalen);
00891          iaxdebug = 0;
00892       }
00893    }
00894 }
00895 
00896 static void iax_debug_output(const char *data)
00897 {
00898    if (iaxdebug)
00899       ast_verbose("%s", data);
00900 }
00901 
00902 static void iax_error_output(const char *data)
00903 {
00904    ast_log(LOG_WARNING, "%s", data);
00905 }
00906 
00907 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00908 {
00909    va_list args;
00910    char buf[1024];
00911 
00912    va_start(args, fmt);
00913    vsnprintf(buf, sizeof(buf), fmt, args);
00914    va_end(args);
00915 
00916    ast_log(LOG_ERROR, "%s", buf);
00917 }
00918 
00919 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00920 {
00921    va_list args;
00922    char buf[1024];
00923 
00924    va_start(args, fmt);
00925    vsnprintf(buf, sizeof(buf), fmt, args);
00926    va_end(args);
00927 
00928    ast_log(LOG_WARNING, "%s", buf);
00929 }
00930 
00931 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00932 {
00933    va_list args;
00934    char buf[1024];
00935 
00936    va_start(args, fmt);
00937    vsnprintf(buf, sizeof(buf), fmt, args);
00938    va_end(args);
00939 
00940    ast_verbose("%s", buf);
00941 }
00942 
00943 static int maxtrunkcall = TRUNK_CALL_START;
00944 static int maxnontrunkcall = 1;
00945 
00946 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);
00947 static int expire_registry(const void *data);
00948 static int iax2_answer(struct ast_channel *c);
00949 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00950 static int iax2_devicestate(void *data);
00951 static int iax2_digit_begin(struct ast_channel *c, char digit);
00952 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00953 static int iax2_do_register(struct iax2_registry *reg);
00954 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00955 static int iax2_hangup(struct ast_channel *c);
00956 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00957 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00958 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00959 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00960 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00961 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00962 static int iax2_sendtext(struct ast_channel *c, const char *text);
00963 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00964 static int iax2_transfer(struct ast_channel *c, const char *dest);
00965 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00966 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
00967 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00968 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00969 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00970 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00971 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00972 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00973 static struct ast_frame *iax2_read(struct ast_channel *c);
00974 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00975 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00976 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00977 static void *iax2_dup_variable_datastore(void *);
00978 static void prune_peers(void);
00979 static void prune_users(void);
00980 static void iax2_free_variable_datastore(void *);
00981 
00982 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
00983 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
00984 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00985 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00986 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00987 static void build_rand_pad(unsigned char *buf, ssize_t len);
00988 
00989 static const struct ast_channel_tech iax2_tech = {
00990    .type = "IAX2",
00991    .description = tdesc,
00992    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00993    .properties = AST_CHAN_TP_WANTSJITTER,
00994    .requester = iax2_request,
00995    .devicestate = iax2_devicestate,
00996    .send_digit_begin = iax2_digit_begin,
00997    .send_digit_end = iax2_digit_end,
00998    .send_text = iax2_sendtext,
00999    .send_image = iax2_sendimage,
01000    .send_html = iax2_sendhtml,
01001    .call = iax2_call,
01002    .hangup = iax2_hangup,
01003    .answer = iax2_answer,
01004    .read = iax2_read,
01005    .write = iax2_write,
01006    .write_video = iax2_write,
01007    .indicate = iax2_indicate,
01008    .setoption = iax2_setoption,
01009    .bridge = iax2_bridge,
01010    .transfer = iax2_transfer,
01011    .fixup = iax2_fixup,
01012    .func_channel_read = acf_channel_read,
01013    .func_channel_write = acf_channel_write,
01014 };
01015 
01016 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01017 {
01018    /* The MWI subscriptions exist just so the core knows we care about those
01019     * mailboxes.  However, we just grab the events out of the cache when it
01020     * is time to send MWI, since it is only sent with a REGACK. */
01021 }
01022 
01023 /*! \brief Send manager event at call setup to link between Asterisk channel name
01024    and IAX2 call identifiers */
01025 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt) 
01026 {
01027    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01028       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01029       pvt->owner ? pvt->owner->name : "",
01030       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01031 }
01032 
01033 
01034 static struct ast_datastore_info iax2_variable_datastore_info = {
01035    .type = "IAX2_VARIABLE",
01036    .duplicate = iax2_dup_variable_datastore,
01037    .destroy = iax2_free_variable_datastore,
01038 };
01039 
01040 static void *iax2_dup_variable_datastore(void *old)
01041 {
01042    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01043    struct ast_var_t *oldvar, *newvar;
01044 
01045    newlist = ast_calloc(sizeof(*newlist), 1);
01046    if (!newlist) {
01047       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01048       return NULL;
01049    }
01050 
01051    AST_LIST_HEAD_INIT(newlist);
01052    AST_LIST_LOCK(oldlist);
01053    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01054       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01055       if (newvar)
01056          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01057       else
01058          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01059    }
01060    AST_LIST_UNLOCK(oldlist);
01061    return newlist;
01062 }
01063 
01064 static void iax2_free_variable_datastore(void *old)
01065 {
01066    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01067    struct ast_var_t *oldvar;
01068 
01069    AST_LIST_LOCK(oldlist);
01070    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01071       ast_free(oldvar);
01072    }
01073    AST_LIST_UNLOCK(oldlist);
01074    AST_LIST_HEAD_DESTROY(oldlist);
01075    ast_free(oldlist);
01076 }
01077 
01078 
01079 /* WARNING: insert_idle_thread should only ever be called within the
01080  * context of an iax2_process_thread() thread.
01081  */
01082 static void insert_idle_thread(struct iax2_thread *thread)
01083 {
01084    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01085       AST_LIST_LOCK(&dynamic_list);
01086       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01087       AST_LIST_UNLOCK(&dynamic_list);
01088    } else {
01089       AST_LIST_LOCK(&idle_list);
01090       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01091       AST_LIST_UNLOCK(&idle_list);
01092    }
01093 
01094    return;
01095 }
01096 
01097 static struct iax2_thread *find_idle_thread(void)
01098 {
01099    struct iax2_thread *thread = NULL;
01100 
01101    /* Pop the head of the idle list off */
01102    AST_LIST_LOCK(&idle_list);
01103    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01104    AST_LIST_UNLOCK(&idle_list);
01105 
01106    /* If we popped a thread off the idle list, just return it */
01107    if (thread) {
01108       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01109       return thread;
01110    }
01111 
01112    /* Pop the head of the dynamic list off */
01113    AST_LIST_LOCK(&dynamic_list);
01114    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01115    AST_LIST_UNLOCK(&dynamic_list);
01116 
01117    /* If we popped a thread off the dynamic list, just return it */
01118    if (thread) {
01119       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01120       return thread;
01121    }
01122 
01123    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01124    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01125       return NULL;
01126 
01127    /* Set default values */
01128    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01129    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01130    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01131 
01132    /* Initialize lock and condition */
01133    ast_mutex_init(&thread->lock);
01134    ast_cond_init(&thread->cond, NULL);
01135    ast_mutex_init(&thread->init_lock);
01136    ast_cond_init(&thread->init_cond, NULL);
01137    ast_mutex_lock(&thread->init_lock);
01138 
01139    /* Create thread and send it on it's way */
01140    if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01141       ast_cond_destroy(&thread->cond);
01142       ast_mutex_destroy(&thread->lock);
01143       ast_free(thread);
01144       return NULL;
01145    }
01146 
01147    /* this thread is not processing a full frame (since it is idle),
01148       so ensure that the field for the full frame call number is empty */
01149    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01150 
01151    /* Wait for the thread to be ready before returning it to the caller */
01152    ast_cond_wait(&thread->init_cond, &thread->init_lock);
01153 
01154    /* Done with init_lock */
01155    ast_mutex_unlock(&thread->init_lock);
01156 
01157    return thread;
01158 }
01159 
01160 #ifdef SCHED_MULTITHREADED
01161 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01162 {
01163    struct iax2_thread *thread = NULL;
01164    static time_t lasterror;
01165    static time_t t;
01166 
01167    thread = find_idle_thread();
01168 
01169    if (thread != NULL) {
01170       thread->schedfunc = func;
01171       thread->scheddata = data;
01172       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01173 #ifdef DEBUG_SCHED_MULTITHREAD
01174       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01175 #endif
01176       signal_condition(&thread->lock, &thread->cond);
01177       return 0;
01178    }
01179    time(&t);
01180    if (t != lasterror) 
01181       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01182    lasterror = t;
01183 
01184    return -1;
01185 }
01186 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01187 #endif
01188 
01189 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01190 {
01191    AST_SCHED_REPLACE(id, con, when, callback, data);
01192    signal_condition(&sched_lock, &sched_cond);
01193 
01194    return id;
01195 }
01196 
01197 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01198 {
01199    int res;
01200 
01201    res = ast_sched_add(con, when, callback, data);
01202    signal_condition(&sched_lock, &sched_cond);
01203 
01204    return res;
01205 }
01206 
01207 static int send_ping(const void *data);
01208 
01209 static void __send_ping(const void *data)
01210 {
01211    int callno = (long) data;
01212 
01213    ast_mutex_lock(&iaxsl[callno]);
01214 
01215    if (iaxs[callno]) {
01216       if (iaxs[callno]->peercallno) {
01217          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01218          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01219       } else {
01220          /* I am the schedule, so I'm allowed to do this */
01221          iaxs[callno]->pingid = -1;
01222       }
01223    } else if (option_debug > 0) {
01224       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);
01225    }
01226 
01227    ast_mutex_unlock(&iaxsl[callno]);
01228 }
01229 
01230 static int send_ping(const void *data)
01231 {
01232 #ifdef SCHED_MULTITHREADED
01233    if (schedule_action(__send_ping, data))
01234 #endif      
01235       __send_ping(data);
01236 
01237    return 0;
01238 }
01239 
01240 static int get_encrypt_methods(const char *s)
01241 {
01242    int e;
01243    if (!strcasecmp(s, "aes128"))
01244       e = IAX_ENCRYPT_AES128;
01245    else if (ast_true(s))
01246       e = IAX_ENCRYPT_AES128;
01247    else
01248       e = 0;
01249    return e;
01250 }
01251 
01252 static int send_lagrq(const void *data);
01253 
01254 static void __send_lagrq(const void *data)
01255 {
01256    int callno = (long) data;
01257 
01258    ast_mutex_lock(&iaxsl[callno]);
01259 
01260    if (iaxs[callno]) {
01261       if (iaxs[callno]->peercallno) {
01262          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01263          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01264       } else {
01265          /* I am the schedule, so I'm allowed to do this */
01266          iaxs[callno]->lagid = -1;
01267       }
01268    } else {
01269       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);
01270    }
01271 
01272    ast_mutex_unlock(&iaxsl[callno]);
01273 }
01274 
01275 static int send_lagrq(const void *data)
01276 {
01277 #ifdef SCHED_MULTITHREADED
01278    if (schedule_action(__send_lagrq, data))
01279 #endif      
01280       __send_lagrq(data);
01281    
01282    return 0;
01283 }
01284 
01285 static unsigned char compress_subclass(int subclass)
01286 {
01287    int x;
01288    int power=-1;
01289    /* If it's 128 or smaller, just return it */
01290    if (subclass < IAX_FLAG_SC_LOG)
01291       return subclass;
01292    /* Otherwise find its power */
01293    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01294       if (subclass & (1 << x)) {
01295          if (power > -1) {
01296             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01297             return 0;
01298          } else
01299             power = x;
01300       }
01301    }
01302    return power | IAX_FLAG_SC_LOG;
01303 }
01304 
01305 static int uncompress_subclass(unsigned char csub)
01306 {
01307    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01308    if (csub & IAX_FLAG_SC_LOG) {
01309       /* special case for 'compressed' -1 */
01310       if (csub == 0xff)
01311          return -1;
01312       else
01313          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01314    }
01315    else
01316       return csub;
01317 }
01318 
01319 /*!
01320  * \note The only member of the peer passed here guaranteed to be set is the name field
01321  */
01322 static int peer_hash_cb(const void *obj, const int flags)
01323 {
01324    const struct iax2_peer *peer = obj;
01325 
01326    return ast_str_hash(peer->name);
01327 }
01328 
01329 /*!
01330  * \note The only member of the peer passed here guaranteed to be set is the name field
01331  */
01332 static int peer_cmp_cb(void *obj, void *arg, int flags)
01333 {
01334    struct iax2_peer *peer = obj, *peer2 = arg;
01335 
01336    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01337 }
01338 
01339 /*!
01340  * \note The only member of the user passed here guaranteed to be set is the name field
01341  */
01342 static int user_hash_cb(const void *obj, const int flags)
01343 {
01344    const struct iax2_user *user = obj;
01345 
01346    return ast_str_hash(user->name);
01347 }
01348 
01349 /*!
01350  * \note The only member of the user passed here guaranteed to be set is the name field
01351  */
01352 static int user_cmp_cb(void *obj, void *arg, int flags)
01353 {
01354    struct iax2_user *user = obj, *user2 = arg;
01355 
01356    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01357 }
01358 
01359 /*!
01360  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01361  *       so do not call it with a pvt lock held.
01362  */
01363 static struct iax2_peer *find_peer(const char *name, int realtime) 
01364 {
01365    struct iax2_peer *peer = NULL;
01366    struct iax2_peer tmp_peer = {
01367       .name = name,
01368    };
01369 
01370    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01371 
01372    /* Now go for realtime if applicable */
01373    if(!peer && realtime)
01374       peer = realtime_peer(name, NULL);
01375 
01376    return peer;
01377 }
01378 
01379 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01380 {
01381    ao2_ref(peer, +1);
01382    return peer;
01383 }
01384 
01385 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01386 {
01387    ao2_ref(peer, -1);
01388    return NULL;
01389 }
01390 
01391 static struct iax2_user *find_user(const char *name)
01392 {
01393    struct iax2_user tmp_user = {
01394       .name = name,
01395    };
01396 
01397    return ao2_find(users, &tmp_user, OBJ_POINTER);
01398 }
01399 static inline struct iax2_user *user_ref(struct iax2_user *user)
01400 {
01401    ao2_ref(user, +1);
01402    return user;
01403 }
01404 
01405 static inline struct iax2_user *user_unref(struct iax2_user *user)
01406 {
01407    ao2_ref(user, -1);
01408    return NULL;
01409 }
01410 
01411 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01412 {
01413    struct iax2_peer *peer = NULL;
01414    int res = 0;
01415    struct ao2_iterator i;
01416 
01417    i = ao2_iterator_init(peers, 0);
01418    while ((peer = ao2_iterator_next(&i))) {
01419       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01420           (peer->addr.sin_port == sin.sin_port)) {
01421          ast_copy_string(host, peer->name, len);
01422          peer_unref(peer);
01423          res = 1;
01424          break;
01425       }
01426       peer_unref(peer);
01427    }
01428 
01429    if (!peer) {
01430       peer = realtime_peer(NULL, &sin);
01431       if (peer) {
01432          ast_copy_string(host, peer->name, len);
01433          peer_unref(peer);
01434          res = 1;
01435       }
01436    }
01437 
01438    return res;
01439 }
01440 
01441 /*!\note Assumes the lock on the pvt is already held, when
01442  * iax2_destroy_helper() is called. */
01443 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01444 {
01445    /* Decrement AUTHREQ count if needed */
01446    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01447       struct iax2_user *user;
01448       struct iax2_user tmp_user = {
01449          .name = pvt->username,
01450       };
01451 
01452       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01453       if (user) {
01454          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01455          user_unref(user); 
01456       }
01457 
01458       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01459    }
01460    /* No more pings or lagrq's */
01461    AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01462    AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01463    AST_SCHED_DEL(sched, pvt->autoid);
01464    AST_SCHED_DEL(sched, pvt->authid);
01465    AST_SCHED_DEL(sched, pvt->initid);
01466    AST_SCHED_DEL(sched, pvt->jbid);
01467    AST_SCHED_DEL(sched, pvt->keyrotateid);
01468 }
01469 
01470 static void iax2_frame_free(struct iax_frame *fr)
01471 {
01472    AST_SCHED_DEL(sched, fr->retrans);
01473    iax_frame_free(fr);
01474 }
01475 
01476 static int scheduled_destroy(const void *vid)
01477 {
01478    short callno = PTR_TO_CALLNO(vid);
01479    ast_mutex_lock(&iaxsl[callno]);
01480    if (iaxs[callno]) {
01481       if (option_debug) {
01482          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01483       }
01484       iax2_destroy(callno);
01485    }
01486    ast_mutex_unlock(&iaxsl[callno]);
01487    return 0;
01488 }
01489 
01490 static void pvt_destructor(void *obj)
01491 {
01492    struct chan_iax2_pvt *pvt = obj;
01493    struct iax_frame *cur = NULL;
01494 
01495    ast_mutex_lock(&iaxsl[pvt->callno]);
01496    iax2_destroy_helper(pvt);
01497    ast_mutex_unlock(&iaxsl[pvt->callno]);
01498 
01499    /* Already gone */
01500    ast_set_flag(pvt, IAX_ALREADYGONE); 
01501 
01502    AST_LIST_LOCK(&frame_queue);
01503    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01504       /* Cancel any pending transmissions */
01505       if (cur->callno == pvt->callno) { 
01506          cur->retries = -1;
01507       }
01508    }
01509    AST_LIST_UNLOCK(&frame_queue);
01510 
01511    if (pvt->reg) {
01512       pvt->reg->callno = 0;
01513    }
01514 
01515    if (!pvt->owner) {
01516       jb_frame frame;
01517       if (pvt->vars) {
01518           ast_variables_destroy(pvt->vars);
01519           pvt->vars = NULL;
01520       }
01521 
01522       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01523          iax2_frame_free(frame.data);
01524       }
01525 
01526       jb_destroy(pvt->jb);
01527       ast_string_field_free_memory(pvt);
01528    }
01529 }
01530 
01531 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01532 {
01533    struct chan_iax2_pvt *tmp;
01534    jb_conf jbconf;
01535 
01536    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01537       return NULL;
01538    }
01539 
01540    if (ast_string_field_init(tmp, 32)) {
01541       ao2_ref(tmp, -1);
01542       tmp = NULL;
01543       return NULL;
01544    }
01545       
01546    tmp->prefs = prefs;
01547    tmp->pingid = -1;
01548    tmp->lagid = -1;
01549    tmp->autoid = -1;
01550    tmp->authid = -1;
01551    tmp->initid = -1;
01552    tmp->keyrotateid = -1;
01553 
01554    ast_string_field_set(tmp,exten, "s");
01555    ast_string_field_set(tmp,host, host);
01556 
01557    tmp->jb = jb_new();
01558    tmp->jbid = -1;
01559    jbconf.max_jitterbuf = maxjitterbuffer;
01560    jbconf.resync_threshold = resyncthreshold;
01561    jbconf.max_contig_interp = maxjitterinterps;
01562    jbconf.target_extra = jittertargetextra;
01563    jb_setconf(tmp->jb,&jbconf);
01564 
01565    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01566 
01567    return tmp;
01568 }
01569 
01570 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01571 {
01572    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01573    if (new) {
01574       size_t afdatalen = new->afdatalen;
01575       memcpy(new, fr, sizeof(*new));
01576       iax_frame_wrap(new, &fr->af);
01577       new->afdatalen = afdatalen;
01578       new->data = NULL;
01579       new->datalen = 0;
01580       new->direction = DIRECTION_INGRESS;
01581       new->retrans = -1;
01582    }
01583    return new;
01584 }
01585 
01586 #define NEW_PREVENT  0
01587 #define NEW_ALLOW    1
01588 #define NEW_FORCE    2
01589 
01590 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01591 {
01592    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01593       (cur->addr.sin_port == sin->sin_port)) {
01594       /* This is the main host */
01595       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01596           (check_dcallno ? dcallno == cur->callno : 1) ) {
01597          /* That's us.  Be sure we keep track of the peer call number */
01598          return 1;
01599       }
01600    }
01601    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01602        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01603       /* We're transferring */
01604       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01605          return 1;
01606    }
01607    return 0;
01608 }
01609 
01610 static void update_max_trunk(void)
01611 {
01612    int max = TRUNK_CALL_START;
01613    int x;
01614 
01615    /* XXX Prolly don't need locks here XXX */
01616    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01617       if (iaxs[x]) {
01618          max = x + 1;
01619       }
01620    }
01621 
01622    maxtrunkcall = max;
01623    if (iaxdebug)
01624       ast_debug(1, "New max trunk callno is %d\n", max);
01625 }
01626 
01627 static void update_max_nontrunk(void)
01628 {
01629    int max = 1;
01630    int x;
01631    /* XXX Prolly don't need locks here XXX */
01632    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01633       if (iaxs[x])
01634          max = x + 1;
01635    }
01636    maxnontrunkcall = max;
01637    if (iaxdebug)
01638       ast_debug(1, "New max nontrunk callno is %d\n", max);
01639 }
01640 
01641 static int make_trunk(unsigned short callno, int locked)
01642 {
01643    int x;
01644    int res= 0;
01645    struct timeval now = ast_tvnow();
01646    if (iaxs[callno]->oseqno) {
01647       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01648       return -1;
01649    }
01650    if (callno & TRUNK_CALL_START) {
01651       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01652       return -1;
01653    }
01654    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01655       ast_mutex_lock(&iaxsl[x]);
01656       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01657          /*!
01658           * \note We delete these before switching the slot, because if
01659           * they fire in the meantime, they will generate a warning.
01660           */
01661          AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01662          AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01663          iaxs[x] = iaxs[callno];
01664          iaxs[x]->callno = x;
01665          iaxs[callno] = NULL;
01666          /* Update the two timers that should have been started */
01667          iaxs[x]->pingid = iax2_sched_add(sched, 
01668             ping_time * 1000, send_ping, (void *)(long)x);
01669          iaxs[x]->lagid = iax2_sched_add(sched, 
01670             lagrq_time * 1000, send_lagrq, (void *)(long)x);
01671          if (locked)
01672             ast_mutex_unlock(&iaxsl[callno]);
01673          res = x;
01674          if (!locked)
01675             ast_mutex_unlock(&iaxsl[x]);
01676          break;
01677       }
01678       ast_mutex_unlock(&iaxsl[x]);
01679    }
01680    if (x >= ARRAY_LEN(iaxs) - 1) {
01681       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01682       return -1;
01683    }
01684    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01685    /* We move this call from a non-trunked to a trunked call */
01686    update_max_trunk();
01687    update_max_nontrunk();
01688    return res;
01689 }
01690 
01691 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01692 {
01693    if (!pvt->transfercallno) {
01694       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01695       return;
01696    }
01697 
01698    ao2_link(iax_transfercallno_pvts, pvt);
01699 }
01700 
01701 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01702 {
01703    if (!pvt->transfercallno) {
01704       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01705       return;
01706    }
01707 
01708    ao2_unlink(iax_transfercallno_pvts, pvt);
01709 }
01710 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01711 {
01712    if (!pvt->peercallno) {
01713       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01714       return;
01715    }
01716 
01717    ao2_link(iax_peercallno_pvts, pvt);
01718 }
01719 
01720 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01721 {
01722    if (!pvt->peercallno) {
01723       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01724       return;
01725    }
01726 
01727    ao2_unlink(iax_peercallno_pvts, pvt);
01728 }
01729 
01730 /*
01731  * \note Calling this function while holding another pvt lock can cause a deadlock.
01732  */
01733 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01734 {
01735    int res = 0;
01736    int x;
01737    struct timeval now;
01738    char host[80];
01739 
01740    if (new <= NEW_ALLOW) {
01741       if (callno) {
01742          struct chan_iax2_pvt *pvt;
01743          struct chan_iax2_pvt tmp_pvt = {
01744             .callno = dcallno,
01745             .peercallno = callno,
01746             .transfercallno = callno,
01747             /* hack!! */
01748             .frames_received = check_dcallno,
01749          };
01750 
01751          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01752          /* this works for finding normal call numbers not involving transfering */ 
01753          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01754             if (return_locked) {
01755                ast_mutex_lock(&iaxsl[pvt->callno]);
01756             }
01757             res = pvt->callno;
01758             ao2_ref(pvt, -1);
01759             pvt = NULL;
01760             return res;
01761          }
01762          /* this searches for transfer call numbers that might not get caught otherwise */
01763          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01764          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01765          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01766             if (return_locked) {
01767                ast_mutex_lock(&iaxsl[pvt->callno]);
01768             }
01769             res = pvt->callno;
01770             ao2_ref(pvt, -1);
01771             pvt = NULL;
01772             return res;
01773          }
01774       }
01775          /* This will occur on the first response to a message that we initiated,
01776        * such as a PING. */
01777       if (dcallno) {
01778          ast_mutex_lock(&iaxsl[dcallno]);
01779       }
01780       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01781          iaxs[dcallno]->peercallno = callno;
01782          res = dcallno;
01783          store_by_peercallno(iaxs[dcallno]);
01784          if (!res || !return_locked) {
01785             ast_mutex_unlock(&iaxsl[dcallno]);
01786          }
01787          return res;
01788       }
01789       if (dcallno) {
01790          ast_mutex_unlock(&iaxsl[dcallno]);
01791       }
01792 #ifdef IAX_OLD_FIND
01793       /* If we get here, we SHOULD NOT find a call structure for this
01794          callno; if we do, it means that there is a call structure that
01795          has a peer callno but did NOT get entered into the hash table,
01796          which is bad.
01797 
01798          If we find a call structure using this old, slow method, output a log
01799          message so we'll know about it. After a few months of leaving this in
01800          place, if we don't hear about people seeing these messages, we can
01801          remove this code for good.
01802       */
01803 
01804       for (x = 1; !res && x < maxnontrunkcall; x++) {
01805          ast_mutex_lock(&iaxsl[x]);
01806          if (iaxs[x]) {
01807             /* Look for an exact match */
01808             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01809                res = x;
01810             }
01811          }
01812          if (!res || !return_locked)
01813             ast_mutex_unlock(&iaxsl[x]);
01814       }
01815       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01816          ast_mutex_lock(&iaxsl[x]);
01817          if (iaxs[x]) {
01818             /* Look for an exact match */
01819             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01820                res = x;
01821             }
01822          }
01823          if (!res || !return_locked)
01824             ast_mutex_unlock(&iaxsl[x]);
01825       }
01826 #endif
01827    }
01828    if (!res && (new >= NEW_ALLOW)) {
01829       int start, found = 0;
01830 
01831       /* It may seem odd that we look through the peer list for a name for
01832        * this *incoming* call.  Well, it is weird.  However, users don't
01833        * have an IP address/port number that we can match against.  So,
01834        * this is just checking for a peer that has that IP/port and
01835        * assuming that we have a user of the same name.  This isn't always
01836        * correct, but it will be changed if needed after authentication. */
01837       if (!iax2_getpeername(*sin, host, sizeof(host)))
01838          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01839 
01840       now = ast_tvnow();
01841       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01842       for (x = start; 1; x++) {
01843          if (x == TRUNK_CALL_START) {
01844             x = 1;
01845             continue;
01846          }
01847 
01848          /* Find first unused call number that hasn't been used in a while */
01849          ast_mutex_lock(&iaxsl[x]);
01850          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01851             found = 1;
01852             break;
01853          }
01854          ast_mutex_unlock(&iaxsl[x]);
01855          
01856          if (x == start - 1) {
01857             break;
01858          }
01859       }
01860       /* We've still got lock held if we found a spot */
01861       if (x == start - 1 && !found) {
01862          ast_log(LOG_WARNING, "No more space\n");
01863          return 0;
01864       }
01865       iaxs[x] = new_iax(sin, host);
01866       update_max_nontrunk();
01867       if (iaxs[x]) {
01868          if (iaxdebug)
01869             ast_debug(1, "Creating new call structure %d\n", x);
01870          iaxs[x]->sockfd = sockfd;
01871          iaxs[x]->addr.sin_port = sin->sin_port;
01872          iaxs[x]->addr.sin_family = sin->sin_family;
01873          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01874          iaxs[x]->peercallno = callno;
01875          iaxs[x]->callno = x;
01876          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01877          iaxs[x]->expiry = min_reg_expire;
01878          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01879          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01880          iaxs[x]->amaflags = amaflags;
01881          ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01882          
01883          ast_string_field_set(iaxs[x], accountcode, accountcode);
01884          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01885          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01886          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
01887 
01888          if (iaxs[x]->peercallno) {
01889             store_by_peercallno(iaxs[x]);
01890          }
01891       } else {
01892          ast_log(LOG_WARNING, "Out of resources\n");
01893          ast_mutex_unlock(&iaxsl[x]);
01894          return 0;
01895       }
01896       if (!return_locked)
01897          ast_mutex_unlock(&iaxsl[x]);
01898       res = x;
01899    }
01900    return res;
01901 }
01902 
01903 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01904 
01905    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01906 }
01907 
01908 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01909 
01910    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01911 }
01912 
01913 /*!
01914  * \brief Queue a frame to a call's owning asterisk channel
01915  *
01916  * \pre This function assumes that iaxsl[callno] is locked when called.
01917  *
01918  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01919  * was valid before calling it, it may no longer be valid after calling it.
01920  * This function may unlock and lock the mutex associated with this callno,
01921  * meaning that another thread may grab it and destroy the call.
01922  */
01923 static int iax2_queue_frame(int callno, struct ast_frame *f)
01924 {
01925    for (;;) {
01926       if (iaxs[callno] && iaxs[callno]->owner) {
01927          if (ast_channel_trylock(iaxs[callno]->owner)) {
01928             /* Avoid deadlock by pausing and trying again */
01929             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01930          } else {
01931             ast_queue_frame(iaxs[callno]->owner, f);
01932             ast_channel_unlock(iaxs[callno]->owner);
01933             break;
01934          }
01935       } else
01936          break;
01937    }
01938    return 0;
01939 }
01940 
01941 /*!
01942  * \brief Queue a hangup frame on the ast_channel owner
01943  *
01944  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01945  * is active for the given call number.
01946  *
01947  * \pre Assumes lock for callno is already held.
01948  *
01949  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01950  * was valid before calling it, it may no longer be valid after calling it.
01951  * This function may unlock and lock the mutex associated with this callno,
01952  * meaning that another thread may grab it and destroy the call.
01953  */
01954 static int iax2_queue_hangup(int callno)
01955 {
01956    for (;;) {
01957       if (iaxs[callno] && iaxs[callno]->owner) {
01958          if (ast_channel_trylock(iaxs[callno]->owner)) {
01959             /* Avoid deadlock by pausing and trying again */
01960             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01961          } else {
01962             ast_queue_hangup(iaxs[callno]->owner);
01963             ast_channel_unlock(iaxs[callno]->owner);
01964             break;
01965          }
01966       } else
01967          break;
01968    }
01969    return 0;
01970 }
01971 
01972 /*!
01973  * \brief Queue a control frame on the ast_channel owner
01974  *
01975  * This function queues a control frame on the owner of the IAX2 pvt struct that
01976  * is active for the given call number.
01977  *
01978  * \pre Assumes lock for callno is already held.
01979  *
01980  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01981  * was valid before calling it, it may no longer be valid after calling it.
01982  * This function may unlock and lock the mutex associated with this callno,
01983  * meaning that another thread may grab it and destroy the call.
01984  */
01985 static int iax2_queue_control_data(int callno, 
01986    enum ast_control_frame_type control, const void *data, size_t datalen)
01987 {
01988    for (;;) {
01989       if (iaxs[callno] && iaxs[callno]->owner) {
01990          if (ast_channel_trylock(iaxs[callno]->owner)) {
01991             /* Avoid deadlock by pausing and trying again */
01992             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01993          } else {
01994             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01995             ast_channel_unlock(iaxs[callno]->owner);
01996             break;
01997          }
01998       } else
01999          break;
02000    }
02001    return 0;
02002 }
02003 static void destroy_firmware(struct iax_firmware *cur)
02004 {
02005    /* Close firmware */
02006    if (cur->fwh) {
02007       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02008    }
02009    close(cur->fd);
02010    ast_free(cur);
02011 }
02012 
02013 static int try_firmware(char *s)
02014 {
02015    struct stat stbuf;
02016    struct iax_firmware *cur = NULL;
02017    int ifd, fd, res, len, chunk;
02018    struct ast_iax2_firmware_header *fwh, fwh2;
02019    struct MD5Context md5;
02020    unsigned char sum[16], buf[1024];
02021    char *s2, *last;
02022 
02023    if (!(s2 = alloca(strlen(s) + 100))) {
02024       ast_log(LOG_WARNING, "Alloca failed!\n");
02025       return -1;
02026    }
02027 
02028    last = strrchr(s, '/');
02029    if (last)
02030       last++;
02031    else
02032       last = s;
02033 
02034    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02035 
02036    if ((res = stat(s, &stbuf) < 0)) {
02037       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02038       return -1;
02039    }
02040 
02041    /* Make sure it's not a directory */
02042    if (S_ISDIR(stbuf.st_mode))
02043       return -1;
02044    ifd = open(s, O_RDONLY);
02045    if (ifd < 0) {
02046       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02047       return -1;
02048    }
02049    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02050    if (fd < 0) {
02051       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02052       close(ifd);
02053       return -1;
02054    }
02055    /* Unlink our newly created file */
02056    unlink(s2);
02057    
02058    /* Now copy the firmware into it */
02059    len = stbuf.st_size;
02060    while(len) {
02061       chunk = len;
02062       if (chunk > sizeof(buf))
02063          chunk = sizeof(buf);
02064       res = read(ifd, buf, chunk);
02065       if (res != chunk) {
02066          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02067          close(ifd);
02068          close(fd);
02069          return -1;
02070       }
02071       res = write(fd, buf, chunk);
02072       if (res != chunk) {
02073          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02074          close(ifd);
02075          close(fd);
02076          return -1;
02077       }
02078       len -= chunk;
02079    }
02080    close(ifd);
02081    /* Return to the beginning */
02082    lseek(fd, 0, SEEK_SET);
02083    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02084       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02085       close(fd);
02086       return -1;
02087    }
02088    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02089       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02090       close(fd);
02091       return -1;
02092    }
02093    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02094       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02095       close(fd);
02096       return -1;
02097    }
02098    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02099       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02100       close(fd);
02101       return -1;
02102    }
02103    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
02104    if (fwh == (void *) -1) {
02105       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02106       close(fd);
02107       return -1;
02108    }
02109    MD5Init(&md5);
02110    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02111    MD5Final(sum, &md5);
02112    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02113       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02114       munmap((void*)fwh, stbuf.st_size);
02115       close(fd);
02116       return -1;
02117    }
02118 
02119    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02120       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02121          /* Found a candidate */
02122          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02123             /* The version we have on loaded is older, load this one instead */
02124             break;
02125          /* This version is no newer than what we have.  Don't worry about it.
02126             We'll consider it a proper load anyhow though */
02127          munmap((void*)fwh, stbuf.st_size);
02128          close(fd);
02129          return 0;
02130       }
02131    }
02132    
02133    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02134       cur->fd = -1;
02135       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02136    }
02137    
02138    if (cur) {
02139       if (cur->fwh)
02140          munmap((void*)cur->fwh, cur->mmaplen);
02141       if (cur->fd > -1)
02142          close(cur->fd);
02143       cur->fwh = fwh;
02144       cur->fd = fd;
02145       cur->mmaplen = stbuf.st_size;
02146       cur->dead = 0;
02147    }
02148    
02149    return 0;
02150 }
02151 
02152 static int iax_check_version(char *dev)
02153 {
02154    int res = 0;
02155    struct iax_firmware *cur = NULL;
02156 
02157    if (ast_strlen_zero(dev))
02158       return 0;
02159 
02160    AST_LIST_LOCK(&firmwares);
02161    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02162       if (!strcmp(dev, (char *)cur->fwh->devname)) {
02163          res = ntohs(cur->fwh->version);
02164          break;
02165       }
02166    }
02167    AST_LIST_UNLOCK(&firmwares);
02168 
02169    return res;
02170 }
02171 
02172 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02173 {
02174    int res = -1;
02175    unsigned int bs = desc & 0xff;
02176    unsigned int start = (desc >> 8) & 0xffffff;
02177    unsigned int bytes;
02178    struct iax_firmware *cur;
02179 
02180    if (ast_strlen_zero((char *)dev) || !bs)
02181       return -1;
02182 
02183    start *= bs;
02184    
02185    AST_LIST_LOCK(&firmwares);
02186    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02187       if (strcmp((char *)dev, (char *)cur->fwh->devname))
02188          continue;
02189       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02190       if (start < ntohl(cur->fwh->datalen)) {
02191          bytes = ntohl(cur->fwh->datalen) - start;
02192          if (bytes > bs)
02193             bytes = bs;
02194          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02195       } else {
02196          bytes = 0;
02197          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02198       }
02199       if (bytes == bs)
02200          res = 0;
02201       else
02202          res = 1;
02203       break;
02204    }
02205    AST_LIST_UNLOCK(&firmwares);
02206 
02207    return res;
02208 }
02209 
02210 
02211 static void reload_firmware(int unload)
02212 {
02213    struct iax_firmware *cur = NULL;
02214    DIR *fwd;
02215    struct dirent *de;
02216    char dir[256], fn[256];
02217 
02218    AST_LIST_LOCK(&firmwares);
02219 
02220    /* Mark all as dead */
02221    AST_LIST_TRAVERSE(&firmwares, cur, list)
02222       cur->dead = 1;
02223 
02224    /* Now that we have marked them dead... load new ones */
02225    if (!unload) {
02226       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02227       fwd = opendir(dir);
02228       if (fwd) {
02229          while((de = readdir(fwd))) {
02230             if (de->d_name[0] != '.') {
02231                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02232                if (!try_firmware(fn)) {
02233                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02234                }
02235             }
02236          }
02237          closedir(fwd);
02238       } else 
02239          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02240    }
02241 
02242    /* Clean up leftovers */
02243    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02244       if (!cur->dead)
02245          continue;
02246       AST_LIST_REMOVE_CURRENT(list);
02247       destroy_firmware(cur);
02248    }
02249    AST_LIST_TRAVERSE_SAFE_END;
02250 
02251    AST_LIST_UNLOCK(&firmwares);
02252 }
02253 
02254 /*!
02255  * \note This function assumes that iaxsl[callno] is locked when called.
02256  *
02257  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02258  * was valid before calling it, it may no longer be valid after calling it.
02259  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02260  * associated with this callno, meaning that another thread may grab it and destroy the call.
02261  */
02262 static int __do_deliver(void *data)
02263 {
02264    /* Just deliver the packet by using queueing.  This is called by
02265      the IAX thread with the iaxsl lock held. */
02266    struct iax_frame *fr = data;
02267    fr->retrans = -1;
02268    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02269    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02270       iax2_queue_frame(fr->callno, &fr->af);
02271    /* Free our iax frame */
02272    iax2_frame_free(fr);
02273    /* And don't run again */
02274    return 0;
02275 }
02276 
02277 static int handle_error(void)
02278 {
02279    /* XXX Ideally we should figure out why an error occurred and then abort those
02280       rather than continuing to try.  Unfortunately, the published interface does
02281       not seem to work XXX */
02282 #if 0
02283    struct sockaddr_in *sin;
02284    int res;
02285    struct msghdr m;
02286    struct sock_extended_err e;
02287    m.msg_name = NULL;
02288    m.msg_namelen = 0;
02289    m.msg_iov = NULL;
02290    m.msg_control = &e;
02291    m.msg_controllen = sizeof(e);
02292    m.msg_flags = 0;
02293    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02294    if (res < 0)
02295       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02296    else {
02297       if (m.msg_controllen) {
02298          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02299          if (sin) 
02300             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02301          else
02302             ast_log(LOG_WARNING, "No address detected??\n");
02303       } else {
02304          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02305       }
02306    }
02307 #endif
02308    return 0;
02309 }
02310 
02311 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02312 {
02313    int res;
02314    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02315                sizeof(*sin));
02316    if (res < 0) {
02317       ast_debug(1, "Received error: %s\n", strerror(errno));
02318       handle_error();
02319    } else
02320       res = 0;
02321    return res;
02322 }
02323 
02324 static int send_packet(struct iax_frame *f)
02325 {
02326    int res;
02327    int callno = f->callno;
02328 
02329    /* Don't send if there was an error, but return error instead */
02330    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02331        return -1;
02332    
02333    /* Called with iaxsl held */
02334    if (iaxdebug)
02335       ast_debug(3, "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));
02336    
02337    if (f->transfer) {
02338       if (iaxdebug)
02339          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02340       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
02341    } else {
02342       if (iaxdebug)
02343          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02344       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
02345    }
02346    if (res < 0) {
02347       if (iaxdebug)
02348          ast_debug(1, "Received error: %s\n", strerror(errno));
02349       handle_error();
02350    } else
02351       res = 0;
02352 
02353    return res;
02354 }
02355 
02356 /*!
02357  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02358  *       for the given call number may disappear during its execution.
02359  */
02360 static int iax2_predestroy(int callno)
02361 {
02362    struct ast_channel *c = NULL;
02363    struct chan_iax2_pvt *pvt = iaxs[callno];
02364 
02365    if (!pvt)
02366       return -1;
02367 
02368    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02369       iax2_destroy_helper(pvt);
02370       ast_set_flag(pvt, IAX_ALREADYGONE); 
02371    }
02372 
02373    if ((c = pvt->owner)) {
02374       c->tech_pvt = NULL;
02375       iax2_queue_hangup(callno);
02376       pvt->owner = NULL;
02377       ast_module_unref(ast_module_info->self);
02378    }
02379 
02380    return 0;
02381 }
02382 
02383 static void iax2_destroy(int callno)
02384 {
02385    struct chan_iax2_pvt *pvt = NULL;
02386    struct ast_channel *owner = NULL;
02387 
02388 retry:
02389    if ((pvt = iaxs[callno])) {
02390       iax2_destroy_helper(pvt);
02391    }
02392 
02393    lastused[callno] = ast_tvnow();
02394    
02395    owner = pvt ? pvt->owner : NULL;
02396 
02397    if (owner) {
02398       if (ast_channel_trylock(owner)) {
02399          ast_debug(3, "Avoiding IAX destroy deadlock\n");
02400          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02401          goto retry;
02402       }
02403    }
02404 
02405    if (!owner) {
02406       iaxs[callno] = NULL;
02407    }
02408 
02409    if (pvt) {
02410       if (!owner) {
02411          pvt->owner = NULL;
02412       } else {
02413          /* If there's an owner, prod it to give up */
02414          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
02415           * because we already hold the owner channel lock. */
02416          ast_queue_hangup(owner);
02417       }
02418 
02419       if (pvt->peercallno) {
02420          remove_by_peercallno(pvt);
02421       }
02422 
02423       if (pvt->transfercallno) {
02424          remove_by_transfercallno(pvt);
02425       }
02426 
02427       if (!owner) {
02428          ao2_ref(pvt, -1);
02429          pvt = NULL;
02430       }
02431    }
02432 
02433    if (owner) {
02434       ast_channel_unlock(owner);
02435    }
02436 
02437    if (callno & 0x4000) {
02438       update_max_trunk();
02439    }
02440 }
02441 
02442 static int update_packet(struct iax_frame *f)
02443 {
02444    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02445    struct ast_iax2_full_hdr *fh = f->data;
02446    struct ast_frame af;
02447 
02448    /* if frame is encrypted. decrypt before updating it. */
02449    if (f->encmethods) {
02450       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02451    }
02452    /* Mark this as a retransmission */
02453    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02454    /* Update iseqno */
02455    f->iseqno = iaxs[f->callno]->iseqno;
02456    fh->iseqno = f->iseqno;
02457 
02458    /* Now re-encrypt the frame */
02459    if (f->encmethods) {
02460    /* since this is a retransmit frame, create a new random padding
02461     * before re-encrypting. */
02462       build_rand_pad(f->semirand, sizeof(f->semirand));
02463       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02464    }
02465    return 0;
02466 }
02467 
02468 static int attempt_transmit(const void *data);
02469 static void __attempt_transmit(const void *data)
02470 {
02471    /* Attempt to transmit the frame to the remote peer...
02472       Called without iaxsl held. */
02473    struct iax_frame *f = (struct iax_frame *)data;
02474    int freeme = 0;
02475    int callno = f->callno;
02476    /* Make sure this call is still active */
02477    if (callno) 
02478       ast_mutex_lock(&iaxsl[callno]);
02479    if (callno && iaxs[callno]) {
02480       if ((f->retries < 0) /* Already ACK'd */ ||
02481           (f->retries >= max_retries) /* Too many attempts */) {
02482             /* Record an error if we've transmitted too many times */
02483             if (f->retries >= max_retries) {
02484                if (f->transfer) {
02485                   /* Transfer timeout */
02486                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02487                } else if (f->final) {
02488                   if (f->final) 
02489                      iax2_destroy(callno);
02490                } else {
02491                   if (iaxs[callno]->owner)
02492                      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);
02493                   iaxs[callno]->error = ETIMEDOUT;
02494                   if (iaxs[callno]->owner) {
02495                      struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
02496                      /* Hangup the fd */
02497                      iax2_queue_frame(callno, &fr); /* XXX */
02498                      /* Remember, owner could disappear */
02499                      if (iaxs[callno] && iaxs[callno]->owner)
02500                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02501                   } else {
02502                      if (iaxs[callno]->reg) {
02503                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02504                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02505                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02506                      }
02507                      iax2_destroy(callno);
02508                   }
02509                }
02510 
02511             }
02512             freeme = 1;
02513       } else {
02514          /* Update it if it needs it */
02515          update_packet(f);
02516          /* Attempt transmission */
02517          send_packet(f);
02518          f->retries++;
02519          /* Try again later after 10 times as long */
02520          f->retrytime *= 10;
02521          if (f->retrytime > MAX_RETRY_TIME)
02522             f->retrytime = MAX_RETRY_TIME;
02523          /* Transfer messages max out at one second */
02524          if (f->transfer && (f->retrytime > 1000))
02525             f->retrytime = 1000;
02526          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02527       }
02528    } else {
02529       /* Make sure it gets freed */
02530       f->retries = -1;
02531       freeme = 1;
02532    }
02533    if (callno)
02534       ast_mutex_unlock(&iaxsl[callno]);
02535    /* Do not try again */
02536    if (freeme) {
02537       /* Don't attempt delivery, just remove it from the queue */
02538       AST_LIST_LOCK(&frame_queue);
02539       AST_LIST_REMOVE(&frame_queue, f, list);
02540       AST_LIST_UNLOCK(&frame_queue);
02541       f->retrans = -1;
02542       /* Free the IAX frame */
02543       iax2_frame_free(f);
02544    }
02545 }
02546 
02547 static int attempt_transmit(const void *data)
02548 {
02549 #ifdef SCHED_MULTITHREADED
02550    if (schedule_action(__attempt_transmit, data))
02551 #endif      
02552       __attempt_transmit(data);
02553    return 0;
02554 }
02555 
02556 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02557 {
02558    struct iax2_peer *peer = NULL;
02559    struct iax2_user *user = NULL;
02560 
02561    switch (cmd) {
02562    case CLI_INIT:
02563       e->command = "iax2 prune realtime";
02564       e->usage =
02565          "Usage: iax2 prune realtime [<peername>|all]\n"
02566          "       Prunes object(s) from the cache\n";
02567       return NULL;
02568    case CLI_GENERATE:
02569       if (a->pos == 3)
02570          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
02571       return NULL;
02572    }
02573    if (a->argc != 4)
02574         return CLI_SHOWUSAGE;
02575    if (!strcmp(a->argv[3], "all")) {
02576       prune_users();
02577       prune_peers();
02578       ast_cli(a->fd, "Cache flushed successfully.\n");
02579       return CLI_SUCCESS;
02580    }
02581    peer = find_peer(a->argv[3], 0);
02582    user = find_user(a->argv[3]);
02583    if (peer || user) {
02584       if (peer) {
02585          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02586             ast_set_flag(peer, IAX_RTAUTOCLEAR);
02587             expire_registry(peer_ref(peer));
02588             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
02589          } else {
02590             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
02591          }
02592          peer_unref(peer);
02593       }
02594       if (user) {
02595          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02596             ast_set_flag(user, IAX_RTAUTOCLEAR);
02597             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
02598          } else {
02599             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
02600          }
02601          ao2_unlink(users,user);
02602          user_unref(user);
02603       }
02604    } else {
02605       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
02606    }
02607 
02608    return CLI_SUCCESS;
02609 }
02610 
02611 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02612 {
02613    switch (cmd) {
02614    case CLI_INIT:
02615       e->command = "iax2 test losspct";
02616       e->usage =
02617          "Usage: iax2 test losspct <percentage>\n"
02618          "       For testing, throws away <percentage> percent of incoming packets\n";
02619       return NULL;
02620    case CLI_GENERATE:
02621       return NULL;
02622    }
02623    if (a->argc != 4)
02624       return CLI_SHOWUSAGE;
02625 
02626    test_losspct = atoi(a->argv[3]);
02627 
02628    return CLI_SUCCESS;
02629 }
02630 
02631 #ifdef IAXTESTS
02632 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02633 {
02634    switch (cmd) {
02635    case CLI_INIT:
02636       e->command = "iax2 test late";
02637       e->usage =
02638          "Usage: iax2 test late <ms>\n"
02639          "       For testing, count the next frame as <ms> ms late\n";
02640       return NULL;
02641    case CLI_GENERATE:
02642       return NULL;
02643    }
02644 
02645    if (a->argc != 4)
02646       return CLI_SHOWUSAGE;
02647 
02648    test_late = atoi(a->argv[3]);
02649 
02650    return CLI_SUCCESS;
02651 }
02652 
02653 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02654 {
02655    switch (cmd) {
02656    case CLI_INIT:
02657       e->command = "iax2 test resync";
02658       e->usage =
02659          "Usage: iax2 test resync <ms>\n"
02660          "       For testing, adjust all future frames by <ms> ms\n";
02661       return NULL;
02662    case CLI_GENERATE:
02663       return NULL;
02664    }
02665 
02666    if (a->argc != 4)
02667       return CLI_SHOWUSAGE;
02668 
02669    test_resync = atoi(a->argv[3]);
02670 
02671    return CLI_SUCCESS;
02672 }
02673 
02674 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02675 {
02676    switch (cmd) {
02677    case CLI_INIT:
02678       e->command = "iax2 test jitter";
02679       e->usage =
02680          "Usage: iax2 test jitter <ms> <pct>\n"
02681          "       For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
02682          "       percentage of packets. If <pct> is not specified, adds\n"
02683          "       jitter to all packets.\n";
02684       return NULL;
02685    case CLI_GENERATE:
02686       return NULL;
02687    }
02688 
02689    if (a->argc < 4 || a->argc > 5)
02690       return CLI_SHOWUSAGE;
02691 
02692    test_jit = atoi(a->argv[3]);
02693    if (a->argc == 5)
02694       test_jitpct = atoi(a->argv[4]);
02695 
02696    return CLI_SUCCESS;
02697 }
02698 #endif /* IAXTESTS */
02699 
02700 /*! \brief  peer_status: Report Peer status in character string */
02701 /*    returns 1 if peer is online, -1 if unmonitored */
02702 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02703 {
02704    int res = 0;
02705    if (peer->maxms) {
02706       if (peer->lastms < 0) {
02707          ast_copy_string(status, "UNREACHABLE", statuslen);
02708       } else if (peer->lastms > peer->maxms) {
02709          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02710          res = 1;
02711       } else if (peer->lastms) {
02712          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02713          res = 1;
02714       } else {
02715          ast_copy_string(status, "UNKNOWN", statuslen);
02716       }
02717    } else { 
02718       ast_copy_string(status, "Unmonitored", statuslen);
02719       res = -1;
02720    }
02721    return res;
02722 }
02723 
02724 /*! \brief Show one peer in detail */
02725 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02726 {
02727    char status[30];
02728    char cbuf[256];
02729    struct iax2_peer *peer;
02730    char codec_buf[512];
02731    int x = 0, codec = 0, load_realtime = 0;
02732 
02733    switch (cmd) {
02734    case CLI_INIT:
02735       e->command = "iax2 show peer";
02736       e->usage =
02737          "Usage: iax2 show peer <name>\n"
02738          "       Display details on specific IAX peer\n";
02739       return NULL;
02740    case CLI_GENERATE:
02741       if (a->pos == 3)
02742          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
02743       return NULL;
02744    }
02745 
02746    if (a->argc < 4)
02747       return CLI_SHOWUSAGE;
02748 
02749    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
02750 
02751    peer = find_peer(a->argv[3], load_realtime);
02752    if (peer) {
02753       ast_cli(a->fd, "\n\n");
02754       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
02755       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
02756       ast_cli(a->fd, "  Context      : %s\n", peer->context);
02757       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
02758       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
02759       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
02760       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02761       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
02762       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
02763       ast_cli(a->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));
02764       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02765       ast_cli(a->fd, "  Username     : %s\n", peer->username);
02766       ast_cli(a->fd, "  Codecs       : ");
02767       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02768       ast_cli(a->fd, "%s\n", codec_buf);
02769 
02770       ast_cli(a->fd, "  Codec Order  : (");
02771       for(x = 0; x < 32 ; x++) {
02772          codec = ast_codec_pref_index(&peer->prefs,x);
02773          if(!codec)
02774             break;
02775          ast_cli(a->fd, "%s", ast_getformatname(codec));
02776          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02777             ast_cli(a->fd, "|");
02778       }
02779 
02780       if (!x)
02781          ast_cli(a->fd, "none");
02782       ast_cli(a->fd, ")\n");
02783 
02784       ast_cli(a->fd, "  Status       : ");
02785       peer_status(peer, status, sizeof(status));   
02786       ast_cli(a->fd, "%s\n",status);
02787       ast_cli(a->fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02788       ast_cli(a->fd, "\n");
02789       peer_unref(peer);
02790    } else {
02791       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
02792       ast_cli(a->fd, "\n");
02793    }
02794 
02795    return CLI_SUCCESS;
02796 }
02797 
02798 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state)
02799 {
02800    int which = 0;
02801    struct iax2_peer *peer;
02802    char *res = NULL;
02803    int wordlen = strlen(word);
02804    struct ao2_iterator i;
02805 
02806    i = ao2_iterator_init(peers, 0);
02807    while ((peer = ao2_iterator_next(&i))) {
02808       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02809          res = ast_strdup(peer->name);
02810          peer_unref(peer);
02811          break;
02812       }
02813       peer_unref(peer);
02814    }
02815 
02816    return res;
02817 }
02818 
02819 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02820 {
02821    struct iax_frame *cur;
02822    int cnt = 0, dead = 0, final = 0;
02823 
02824    switch (cmd) {
02825    case CLI_INIT:
02826       e->command = "iax2 show stats";
02827       e->usage =
02828          "Usage: iax2 show stats\n"
02829          "       Display statistics on IAX channel driver.\n";
02830       return NULL;
02831    case CLI_GENERATE:
02832       return NULL;
02833    }
02834 
02835    if (a->argc != 3)
02836       return CLI_SHOWUSAGE;
02837 
02838    AST_LIST_LOCK(&frame_queue);
02839    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
02840       if (cur->retries < 0)
02841          dead++;
02842       if (cur->final)
02843          final++;
02844       cnt++;
02845    }
02846    AST_LIST_UNLOCK(&frame_queue);
02847 
02848    ast_cli(a->fd, "    IAX Statistics\n");
02849    ast_cli(a->fd, "---------------------\n");
02850    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02851    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
02852       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
02853    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02854 
02855    trunk_timed = trunk_untimed = 0;
02856    if (trunk_maxmtu > trunk_nmaxmtu)
02857       trunk_nmaxmtu = trunk_maxmtu;
02858 
02859    return CLI_SUCCESS;
02860 }
02861 
02862 /*! \brief Set trunk MTU from CLI */
02863 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02864 {
02865    int mtuv;
02866 
02867    switch (cmd) {
02868    case CLI_INIT:
02869       e->command = "iax2 set mtu";
02870       e->usage =
02871          "Usage: iax2 set mtu <value>\n"
02872          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
02873          "       zero to disable. Disabling means that the operating system\n"
02874          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
02875          "       packet exceeds the UDP payload size. This is substantially\n"
02876          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
02877          "       greater for G.711 samples.\n";
02878       return NULL;
02879    case CLI_GENERATE:
02880       return NULL;
02881    }
02882 
02883    if (a->argc != 4)
02884       return CLI_SHOWUSAGE; 
02885    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
02886       mtuv = MAX_TRUNK_MTU;
02887    else
02888       mtuv = atoi(a->argv[3]);
02889 
02890    if (mtuv == 0) {
02891       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
02892       global_max_trunk_mtu = 0; 
02893       return CLI_SUCCESS; 
02894    }
02895    if (mtuv < 172 || mtuv > 4000) {
02896       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
02897       return CLI_SHOWUSAGE; 
02898    }
02899    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
02900    global_max_trunk_mtu = mtuv; 
02901    return CLI_SUCCESS;
02902 }
02903 
02904 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02905 {
02906    struct iax2_dpcache *dp = NULL;
02907    char tmp[1024], *pc = NULL;
02908    int s, x, y;
02909    struct timeval now = ast_tvnow();
02910 
02911    switch (cmd) {
02912    case CLI_INIT:
02913       e->command = "iax2 show cache";
02914       e->usage =
02915          "Usage: iax2 show cache\n"
02916          "       Display currently cached IAX Dialplan results.\n";
02917       return NULL;
02918    case CLI_GENERATE:
02919       return NULL;
02920    }
02921 
02922    AST_LIST_LOCK(&dpcache);
02923 
02924    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02925 
02926    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
02927       s = dp->expiry.tv_sec - now.tv_sec;
02928       tmp[0] = '\0';
02929       if (dp->flags & CACHE_FLAG_EXISTS)
02930          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02931       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02932          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02933       if (dp->flags & CACHE_FLAG_CANEXIST)
02934          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02935       if (dp->flags & CACHE_FLAG_PENDING)
02936          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02937       if (dp->flags & CACHE_FLAG_TIMEOUT)
02938          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02939       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02940          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02941       if (dp->flags & CACHE_FLAG_MATCHMORE)
02942          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02943       if (dp->flags & CACHE_FLAG_UNKNOWN)
02944          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02945       /* Trim trailing pipe */
02946       if (!ast_strlen_zero(tmp)) {
02947          tmp[strlen(tmp) - 1] = '\0';
02948       } else {
02949          ast_copy_string(tmp, "(none)", sizeof(tmp));
02950       }
02951       y = 0;
02952       pc = strchr(dp->peercontext, '@');
02953       if (!pc) {
02954          pc = dp->peercontext;
02955       } else {
02956          pc++;
02957       }
02958       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
02959          if (dp->waiters[x] > -1)
02960             y++;
02961       }
02962       if (s > 0) {
02963          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02964       } else {
02965          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02966       }
02967    }
02968 
02969    AST_LIST_LOCK(&dpcache);
02970 
02971    return CLI_SUCCESS;
02972 }
02973 
02974 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02975 
02976 static void unwrap_timestamp(struct iax_frame *fr)
02977 {
02978    /* Video mini frames only encode the lower 15 bits of the session
02979     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
02980    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02981    const int lower_mask = (1 << ts_shift) - 1;
02982    const int upper_mask = ~lower_mask;
02983    const int last_upper = iaxs[fr->callno]->last & upper_mask;
02984 
02985    if ( (fr->ts & upper_mask) == last_upper ) {
02986       const int x = fr->ts - iaxs[fr->callno]->last;
02987       const int threshold = (ts_shift == 15) ? 25000 : 50000;
02988 
02989       if (x < -threshold) {
02990          /* Sudden big jump backwards in timestamp:
02991             What likely happened here is that miniframe timestamp has circled but we haven't
02992             gotten the update from the main packet.  We'll just pretend that we did, and
02993             update the timestamp appropriately. */
02994          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02995          if (iaxdebug)
02996             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
02997       } else if (x > threshold) {
02998          /* Sudden apparent big jump forwards in timestamp:
02999             What's likely happened is this is an old miniframe belonging to the previous
03000             top 15 or 16-bit timestamp that has turned up out of order.
03001             Adjust the timestamp appropriately. */
03002          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03003          if (iaxdebug)
03004             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03005       }
03006    }
03007 }
03008 
03009 static int get_from_jb(const void *p);
03010 
03011 static void update_jbsched(struct chan_iax2_pvt *pvt)
03012 {
03013    int when;
03014    
03015    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03016    
03017    when = jb_next(pvt->jb) - when;
03018 
03019    if (when <= 0) {
03020       /* XXX should really just empty until when > 0.. */
03021       when = 1;
03022    }
03023    
03024    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
03025       CALLNO_TO_PTR(pvt->callno));
03026 }
03027 
03028 static void __get_from_jb(const void *p) 
03029 {
03030    int callno = PTR_TO_CALLNO(p);
03031    struct chan_iax2_pvt *pvt = NULL;
03032    struct iax_frame *fr;
03033    jb_frame frame;
03034    int ret;
03035    long ms;
03036    long next;
03037    struct timeval now = ast_tvnow();
03038    
03039    /* Make sure we have a valid private structure before going on */
03040    ast_mutex_lock(&iaxsl[callno]);
03041    pvt = iaxs[callno];
03042    if (!pvt) {
03043       /* No go! */
03044       ast_mutex_unlock(&iaxsl[callno]);
03045       return;
03046    }
03047 
03048    pvt->jbid = -1;
03049    
03050    /* round up a millisecond since ast_sched_runq does; */
03051    /* prevents us from spinning while waiting for our now */
03052    /* to catch up with runq's now */
03053    now.tv_usec += 1000;
03054    
03055    ms = ast_tvdiff_ms(now, pvt->rxcore);
03056    
03057    if(ms >= (next = jb_next(pvt->jb))) {
03058       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03059       switch(ret) {
03060       case JB_OK:
03061          fr = frame.data;
03062          __do_deliver(fr);
03063          /* __do_deliver() can cause the call to disappear */
03064          pvt = iaxs[callno];
03065          break;
03066       case JB_INTERP:
03067       {
03068          struct ast_frame af = { 0, };
03069          
03070          /* create an interpolation frame */
03071          af.frametype = AST_FRAME_VOICE;
03072          af.subclass = pvt->voiceformat;
03073          af.samples  = frame.ms * 8;
03074          af.src  = "IAX2 JB interpolation";
03075          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03076          af.offset = AST_FRIENDLY_OFFSET;
03077          
03078          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03079           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03080          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03081             iax2_queue_frame(callno, &af);
03082             /* iax2_queue_frame() could cause the call to disappear */
03083             pvt = iaxs[callno];
03084          }
03085       }
03086          break;
03087       case JB_DROP:
03088          iax2_frame_free(frame.data);
03089          break;
03090       case JB_NOFRAME:
03091       case JB_EMPTY:
03092          /* do nothing */
03093          break;
03094       default:
03095          /* shouldn't happen */
03096          break;
03097       }
03098    }
03099    if (pvt)
03100       update_jbsched(pvt);
03101    ast_mutex_unlock(&iaxsl[callno]);
03102 }
03103 
03104 static int get_from_jb(const void *data)
03105 {
03106 #ifdef SCHED_MULTITHREADED
03107    if (schedule_action(__get_from_jb, data))
03108 #endif      
03109       __get_from_jb(data);
03110    return 0;
03111 }
03112 
03113 /*!
03114  * \note This function assumes fr->callno is locked
03115  *
03116  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
03117  * was valid before calling it, it may no longer be valid after calling it.
03118  */
03119 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03120 {
03121    int type, len;
03122    int ret;
03123    int needfree = 0;
03124    struct ast_channel *owner = NULL;
03125    struct ast_channel *bridge = NULL;
03126    
03127    /* Attempt to recover wrapped timestamps */
03128    unwrap_timestamp(fr);
03129 
03130    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
03131    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03132       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03133    else {
03134 #if 0
03135       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03136 #endif
03137       fr->af.delivery = ast_tv(0,0);
03138    }
03139 
03140    type = JB_TYPE_CONTROL;
03141    len = 0;
03142 
03143    if(fr->af.frametype == AST_FRAME_VOICE) {
03144       type = JB_TYPE_VOICE;
03145       len = ast_codec_get_samples(&fr->af) / 8;
03146    } else if(fr->af.frametype == AST_FRAME_CNG) {
03147       type = JB_TYPE_SILENCE;
03148    }
03149 
03150    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03151       if (tsout)
03152          *tsout = fr->ts;
03153       __do_deliver(fr);
03154       return -1;
03155    }
03156 
03157    if ((owner = iaxs[fr->callno]->owner))
03158       bridge = ast_bridged_channel(owner);
03159 
03160    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
03161     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
03162    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03163       jb_frame frame;
03164 
03165       /* deliver any frames in the jb */
03166       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03167          __do_deliver(frame.data);
03168          /* __do_deliver() can make the call disappear */
03169          if (!iaxs[fr->callno])
03170             return -1;
03171       }
03172 
03173       jb_reset(iaxs[fr->callno]->jb);
03174 
03175       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03176 
03177       /* deliver this frame now */
03178       if (tsout)
03179          *tsout = fr->ts;
03180       __do_deliver(fr);
03181       return -1;
03182    }
03183 
03184    /* insert into jitterbuffer */
03185    /* TODO: Perhaps we could act immediately if it's not droppable and late */
03186    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03187          calc_rxstamp(iaxs[fr->callno],fr->ts));
03188    if (ret == JB_DROP) {
03189       needfree++;
03190    } else if (ret == JB_SCHED) {
03191       update_jbsched(iaxs[fr->callno]);
03192    }
03193    if (tsout)
03194       *tsout = fr->ts;
03195    if (needfree) {
03196       /* Free our iax frame */
03197       iax2_frame_free(fr);
03198       return -1;
03199    }
03200    return 0;
03201 }
03202 
03203 static int iax2_transmit(struct iax_frame *fr)
03204 {
03205    /* Lock the queue and place this packet at the end */
03206    /* By setting this to 0, the network thread will send it for us, and
03207       queue retransmission if necessary */
03208    fr->sentyet = 0;
03209    AST_LIST_LOCK(&frame_queue);
03210    AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03211    AST_LIST_UNLOCK(&frame_queue);
03212    /* Wake up the network and scheduler thread */
03213    if (netthreadid != AST_PTHREADT_NULL)
03214       pthread_kill(netthreadid, SIGURG);
03215    signal_condition(&sched_lock, &sched_cond);
03216    return 0;
03217 }
03218 
03219 
03220 
03221 static int iax2_digit_begin(struct ast_channel *c, char digit)
03222 {
03223    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03224 }
03225 
03226 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03227 {
03228    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03229 }
03230 
03231 static int iax2_sendtext(struct ast_channel *c, const char *text)
03232 {
03233    
03234    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03235       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03236 }
03237 
03238 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03239 {
03240    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03241 }
03242 
03243 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03244 {
03245    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03246 }
03247 
03248 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03249 {
03250    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03251    ast_mutex_lock(&iaxsl[callno]);
03252    if (iaxs[callno])
03253       iaxs[callno]->owner = newchan;
03254    else
03255       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03256    ast_mutex_unlock(&iaxsl[callno]);
03257    return 0;
03258 }
03259 
03260 /*!
03261  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
03262  *       so do not call this with a pvt lock held.
03263  */
03264 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03265 {
03266    struct ast_variable *var = NULL;
03267    struct ast_variable *tmp;
03268    struct iax2_peer *peer=NULL;
03269    time_t regseconds = 0, nowtime;
03270    int dynamic=0;
03271 
03272    if (peername) {
03273       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
03274       if (!var && sin)
03275          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
03276    } else if (sin) {
03277       char porta[25];
03278       sprintf(porta, "%d", ntohs(sin->sin_port));
03279       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03280       if (var) {
03281          /* We'll need the peer name in order to build the structure! */
03282          for (tmp = var; tmp; tmp = tmp->next) {
03283             if (!strcasecmp(tmp->name, "name"))
03284                peername = tmp->value;
03285          }
03286       }
03287    }
03288    if (!var && peername) { /* Last ditch effort */
03289       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
03290       /*!\note
03291        * If this one loaded something, then we need to ensure that the host
03292        * field matched.  The only reason why we can't have this as a criteria
03293        * is because we only have the IP address and the host field might be
03294        * set as a name (and the reverse PTR might not match).
03295        */
03296       if (var && sin) {
03297          for (tmp = var; tmp; tmp = tmp->next) {
03298             if (!strcasecmp(tmp->name, "host")) {
03299                struct ast_hostent ahp;
03300                struct hostent *hp;
03301                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03302                   /* No match */
03303                   ast_variables_destroy(var);
03304                   var = NULL;
03305                }
03306                break;
03307             }
03308          }
03309       }
03310    }
03311    if (!var)
03312       return NULL;
03313 
03314    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03315    
03316    if (!peer) {
03317       ast_variables_destroy(var);
03318       return NULL;
03319    }
03320 
03321    for (tmp = var; tmp; tmp = tmp->next) {
03322       /* Make sure it's not a user only... */
03323       if (!strcasecmp(tmp->name, "type")) {
03324          if (strcasecmp(tmp->value, "friend") &&
03325              strcasecmp(tmp->value, "peer")) {
03326             /* Whoops, we weren't supposed to exist! */
03327             peer = peer_unref(peer);
03328             break;
03329          } 
03330       } else if (!strcasecmp(tmp->name, "regseconds")) {
03331          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
03332       } else if (!strcasecmp(tmp->name, "ipaddr")) {
03333          inet_aton(tmp->value, &(peer->addr.sin_addr));
03334       } else if (!strcasecmp(tmp->name, "port")) {
03335          peer->addr.sin_port = htons(atoi(tmp->value));
03336       } else if (!strcasecmp(tmp->name, "host")) {
03337          if (!strcasecmp(tmp->value, "dynamic"))
03338             dynamic = 1;
03339       }
03340    }
03341 
03342    ast_variables_destroy(var);
03343 
03344    if (!peer)
03345       return NULL;
03346 
03347    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03348       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03349       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03350          if (peer->expire > -1) {
03351             if (!ast_sched_del(sched, peer->expire)) {
03352                peer->expire = -1;
03353                peer_unref(peer);
03354             }
03355          }
03356          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03357          if (peer->expire == -1)
03358             peer_unref(peer);
03359       }
03360       ao2_link(peers, peer);
03361       if (ast_test_flag(peer, IAX_DYNAMIC))
03362          reg_source_db(peer);
03363    } else {
03364       ast_set_flag(peer, IAX_TEMPONLY);   
03365    }
03366 
03367    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03368       time(&nowtime);
03369       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03370          memset(&peer->addr, 0, sizeof(peer->addr));
03371          realtime_update_peer(peer->name, &peer->addr, 0);
03372          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03373             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03374       }
03375       else {
03376          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03377             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03378       }
03379    }
03380 
03381    return peer;
03382 }
03383 
03384 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03385 {
03386    struct ast_variable *var;
03387    struct ast_variable *tmp;
03388    struct iax2_user *user=NULL;
03389 
03390    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
03391    if (!var)
03392       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
03393    if (!var && sin) {
03394       char porta[6];
03395       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03396       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03397       if (!var)
03398          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03399    }
03400    if (!var) { /* Last ditch effort */
03401       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
03402       /*!\note
03403        * If this one loaded something, then we need to ensure that the host
03404        * field matched.  The only reason why we can't have this as a criteria
03405        * is because we only have the IP address and the host field might be
03406        * set as a name (and the reverse PTR might not match).
03407        */
03408       if (var) {
03409          for (tmp = var; tmp; tmp = tmp->next) {
03410             if (!strcasecmp(tmp->name, "host")) {
03411                struct ast_hostent ahp;
03412                struct hostent *hp;
03413                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03414                   /* No match */
03415                   ast_variables_destroy(var);
03416                   var = NULL;
03417                }
03418                break;
03419             }
03420          }
03421       }
03422    }
03423    if (!var)
03424       return NULL;
03425 
03426    tmp = var;
03427    while(tmp) {
03428       /* Make sure it's not a peer only... */
03429       if (!strcasecmp(tmp->name, "type")) {
03430          if (strcasecmp(tmp->value, "friend") &&
03431              strcasecmp(tmp->value, "user")) {
03432             return NULL;
03433          } 
03434       }
03435       tmp = tmp->next;
03436    }
03437 
03438    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03439 
03440    ast_variables_destroy(var);
03441 
03442    if (!user)
03443       return NULL;
03444 
03445    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03446       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03447       ao2_link(users, user);
03448    } else {
03449       ast_set_flag(user, IAX_TEMPONLY);   
03450    }
03451 
03452    return user;
03453 }
03454 
03455 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03456 {
03457    char port[10];
03458    char regseconds[20];
03459    
03460    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03461    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03462    ast_update_realtime("iaxpeers", "name", peername, 
03463       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03464       "regseconds", regseconds, SENTINEL);
03465 }
03466 
03467 struct create_addr_info {
03468    int capability;
03469    unsigned int flags;
03470    int maxtime;
03471    int encmethods;
03472    int found;
03473    int sockfd;
03474    int adsi;
03475    char username[80];
03476    char secret[80];
03477    char outkey[80];
03478    char timezone[80];
03479    char prefs[32];
03480    char context[AST_MAX_CONTEXT];
03481    char peercontext[AST_MAX_CONTEXT];
03482    char mohinterpret[MAX_MUSICCLASS];
03483    char mohsuggest[MAX_MUSICCLASS];
03484 };
03485 
03486 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03487 {
03488    struct iax2_peer *peer;
03489    int res = -1;
03490    struct ast_codec_pref ourprefs;
03491 
03492    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03493    cai->sockfd = defaultsockfd;
03494    cai->maxtime = 0;
03495    sin->sin_family = AF_INET;
03496 
03497    if (!(peer = find_peer(peername, 1))) {
03498       cai->found = 0;
03499       if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
03500          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03501          return -1;
03502       }
03503       sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03504       /* use global iax prefs for unknown peer/user */
03505       /* But move the calling channel's native codec to the top of the preference list */
03506       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03507       if (c)
03508          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03509       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03510       return 0;
03511    }
03512 
03513    cai->found = 1;
03514    
03515    /* if the peer has no address (current or default), return failure */
03516    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03517       goto return_unref;
03518 
03519    /* if the peer is being monitored and is currently unreachable, return failure */
03520    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03521       goto return_unref;
03522 
03523    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03524    cai->maxtime = peer->maxms;
03525    cai->capability = peer->capability;
03526    cai->encmethods = peer->encmethods;
03527    cai->sockfd = peer->sockfd;
03528    cai->adsi = peer->adsi;
03529    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03530    /* Move the calling channel's native codec to the top of the preference list */
03531    if (c) {
03532       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03533       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03534    }
03535    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03536    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03537    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03538    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03539    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03540    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03541    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03542    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03543    if (ast_strlen_zero(peer->dbsecret)) {
03544       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03545    } else {
03546       char *family;
03547       char *key = NULL;
03548 
03549       family = ast_strdupa(peer->dbsecret);
03550       key = strchr(family, '/');
03551       if (key)
03552          *key++ = '\0';
03553       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03554          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03555          goto return_unref;
03556       }
03557    }
03558 
03559    if (peer->addr.sin_addr.s_addr) {
03560       sin->sin_addr = peer->addr.sin_addr;
03561       sin->sin_port = peer->addr.sin_port;
03562    } else {
03563       sin->sin_addr = peer->defaddr.sin_addr;
03564       sin->sin_port = peer->defaddr.sin_port;
03565    }
03566 
03567    res = 0;
03568 
03569 return_unref:
03570    peer_unref(peer);
03571 
03572    return res;
03573 }
03574 
03575 static void __auto_congest(const void *nothing)
03576 {
03577    int callno = PTR_TO_CALLNO(nothing);
03578    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03579    ast_mutex_lock(&iaxsl[callno]);
03580    if (iaxs[callno]) {
03581       iaxs[callno]->initid = -1;
03582       iax2_queue_frame(callno, &f);
03583       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03584    }
03585    ast_mutex_unlock(&iaxsl[callno]);
03586 }
03587 
03588 static int auto_congest(const void *data)
03589 {
03590 #ifdef SCHED_MULTITHREADED
03591    if (schedule_action(__auto_congest, data))
03592 #endif      
03593       __auto_congest(data);
03594    return 0;
03595 }
03596 
03597 static unsigned int iax2_datetime(const char *tz)
03598 {
03599    struct timeval t = ast_tvnow();
03600    struct ast_tm tm;
03601    unsigned int tmp;
03602    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
03603    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03604    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03605    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03606    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03607    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03608    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03609    return tmp;
03610 }
03611 
03612 struct parsed_dial_string {
03613    char *username;
03614    char *password;
03615    char *key;
03616    char *peer;
03617    char *port;
03618    char *exten;
03619    char *context;
03620    char *options;
03621 };
03622 
03623 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03624 {
03625    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03626       .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03627       .csub = compress_subclass(command) };
03628 
03629    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03630 }
03631 
03632 /*!
03633  * \brief Parses an IAX dial string into its component parts.
03634  * \param data the string to be parsed
03635  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03636  * \return nothing
03637  *
03638  * This function parses the string and fills the structure
03639  * with pointers to its component parts. The input string
03640  * will be modified.
03641  *
03642  * \note This function supports both plaintext passwords and RSA
03643  * key names; if the password string is formatted as '[keyname]',
03644  * then the keyname will be placed into the key field, and the
03645  * password field will be set to NULL.
03646  *
03647  * \note The dial string format is:
03648  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03649  */
03650 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03651 {
03652    if (ast_strlen_zero(data))
03653       return;
03654 
03655    pds->peer = strsep(&data, "/");
03656    pds->exten = strsep(&data, "/");
03657    pds->options = data;
03658 
03659    if (pds->exten) {
03660       data = pds->exten;
03661       pds->exten = strsep(&data, "@");
03662       pds->context = data;
03663    }
03664 
03665    if (strchr(pds->peer, '@')) {
03666       data = pds->peer;
03667       pds->username = strsep(&data, "@");
03668       pds->peer = data;
03669    }
03670 
03671    if (pds->username) {
03672       data = pds->username;
03673       pds->username = strsep(&data, ":");
03674       pds->password = data;
03675    }
03676 
03677    data = pds->peer;
03678    pds->peer = strsep(&data, ":");
03679    pds->port = data;
03680 
03681    /* check for a key name wrapped in [] in the secret position, if found,
03682       move it to the key field instead
03683    */
03684    if (pds->password && (pds->password[0] == '[')) {
03685       pds->key = ast_strip_quoted(pds->password, "[", "]");
03686       pds->password = NULL;
03687    }
03688 }
03689 
03690 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03691 {
03692    struct sockaddr_in sin;
03693    char *l=NULL, *n=NULL, *tmpstr;
03694    struct iax_ie_data ied;
03695    char *defaultrdest = "s";
03696    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03697    struct parsed_dial_string pds;
03698    struct create_addr_info cai;
03699    struct ast_var_t *var;
03700    struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
03701    const char* osp_token_ptr;
03702    unsigned int osp_token_length;
03703    unsigned char osp_block_index;
03704    unsigned int osp_block_length;
03705    unsigned char osp_buffer[256];
03706 
03707    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03708       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03709       return -1;
03710    }
03711 
03712    memset(&cai, 0, sizeof(cai));
03713    cai.encmethods = iax2_encryption;
03714 
03715    memset(&pds, 0, sizeof(pds));
03716    tmpstr = ast_strdupa(dest);
03717    parse_dial_string(tmpstr, &pds);
03718 
03719    if (ast_strlen_zero(pds.peer)) {
03720       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03721       return -1;
03722    }
03723 
03724    if (!pds.exten) {
03725       pds.exten = defaultrdest;
03726    }
03727 
03728    if (create_addr(pds.peer, c, &sin, &cai)) {
03729       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03730       return -1;
03731    }
03732 
03733    if (!pds.username && !ast_strlen_zero(cai.username))
03734       pds.username = cai.username;
03735    if (!pds.password && !ast_strlen_zero(cai.secret))
03736       pds.password = cai.secret;
03737    if (!pds.key && !ast_strlen_zero(cai.outkey))
03738       pds.key = cai.outkey;
03739    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03740       pds.context = cai.peercontext;
03741 
03742    /* Keep track of the context for outgoing calls too */
03743    ast_copy_string(c->context, cai.context, sizeof(c->context));
03744 
03745    if (pds.port)
03746       sin.sin_port = htons(atoi(pds.port));
03747 
03748    l = c->cid.cid_num;
03749    n = c->cid.cid_name;
03750 
03751    /* Now build request */ 
03752    memset(&ied, 0, sizeof(ied));
03753 
03754    /* On new call, first IE MUST be IAX version of caller */
03755    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03756    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03757    if (pds.options && strchr(pds.options, 'a')) {
03758       /* Request auto answer */
03759       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03760    }
03761 
03762    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03763 
03764    if (l) {
03765       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03766       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03767    } else {
03768       if (n)
03769          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03770       else
03771          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03772    }
03773 
03774    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03775    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03776 
03777    if (n)
03778       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03779    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03780       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03781 
03782    if (!ast_strlen_zero(c->language))
03783       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03784    if (!ast_strlen_zero(c->cid.cid_dnid))
03785       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03786    if (!ast_strlen_zero(c->cid.cid_rdnis))
03787       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03788 
03789    if (pds.context)
03790       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03791 
03792    if (pds.username)
03793       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03794 
03795    if (cai.encmethods)
03796       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03797 
03798    ast_mutex_lock(&iaxsl[callno]);
03799 
03800    if (!ast_strlen_zero(c->context))
03801       ast_string_field_set(iaxs[callno], context, c->context);
03802 
03803    if (pds.username)
03804       ast_string_field_set(iaxs[callno], username, pds.username);
03805 
03806    iaxs[callno]->encmethods = cai.encmethods;
03807 
03808    iaxs[callno]->adsi = cai.adsi;
03809    
03810    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03811    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03812 
03813    if (pds.key)
03814       ast_string_field_set(iaxs[callno], outkey, pds.key);
03815    if (pds.password)
03816       ast_string_field_set(iaxs[callno], secret, pds.password);
03817 
03818    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03819    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03820    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03821    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03822 
03823    if (iaxs[callno]->maxtime) {
03824       /* Initialize pingtime and auto-congest time */
03825       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03826       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03827    } else if (autokill) {
03828       iaxs[callno]->pingtime = autokill / 2;
03829       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03830    }
03831 
03832    /* Check if there is an OSP token set by IAXCHANINFO function */
03833    osp_token_ptr = iaxs[callno]->osptoken;
03834    if (!ast_strlen_zero(osp_token_ptr)) {
03835       if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
03836          osp_block_index = 0;
03837          while (osp_token_length > 0) {
03838             osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
03839             osp_buffer[0] = osp_block_index;
03840             memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
03841             iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
03842             osp_block_index++;
03843             osp_token_ptr += osp_block_length;
03844             osp_token_length -= osp_block_length;
03845          } 
03846       } else
03847          ast_log(LOG_WARNING, "OSP token is too long\n");
03848    } else if (iaxdebug)
03849       ast_debug(1, "OSP token is undefined\n");
03850 
03851    /* send the command using the appropriate socket for this peer */
03852    iaxs[callno]->sockfd = cai.sockfd;
03853 
03854    /* Add remote vars */
03855    if (variablestore) {
03856       AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
03857       ast_debug(1, "Found an IAX variable store on this channel\n");
03858       AST_LIST_LOCK(variablelist);
03859       AST_LIST_TRAVERSE(variablelist, var, entries) {
03860          char tmp[256];
03861          int i;
03862          ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
03863          /* Automatically divide the value up into sized chunks */
03864          for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
03865             snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
03866             iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
03867          }
03868       }
03869       AST_LIST_UNLOCK(variablelist);
03870    }
03871 
03872    /* Transmit the string in a "NEW" request */
03873    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03874 
03875    ast_mutex_unlock(&iaxsl[callno]);
03876    ast_setstate(c, AST_STATE_RINGING);
03877 
03878    return 0;
03879 }
03880 
03881 static int iax2_hangup(struct ast_channel *c) 
03882 {
03883    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03884    struct iax_ie_data ied;
03885    int alreadygone;
03886    memset(&ied, 0, sizeof(ied));
03887    ast_mutex_lock(&iaxsl[callno]);
03888    if (callno && iaxs[callno]) {
03889       ast_debug(1, "We're hanging up %s now...\n", c->name);
03890       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03891       /* Send the hangup unless we have had a transmission error or are already gone */
03892       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03893       if (!iaxs[callno]->error && !alreadygone) {
03894          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03895             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03896          }
03897          if (!iaxs[callno]) {
03898             ast_mutex_unlock(&iaxsl[callno]);
03899             return 0;
03900          }
03901       }
03902       /* Explicitly predestroy it */
03903       iax2_predestroy(callno);
03904       /* If we were already gone to begin with, destroy us now */
03905       if (iaxs[callno] && alreadygone) {
03906          ast_debug(1, "Really destroying %s now...\n", c->name);
03907          iax2_destroy(callno);
03908       } else if (iaxs[callno]) {
03909          if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
03910             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
03911             iax2_destroy(callno);
03912          }
03913       }
03914    } else if (c->tech_pvt) {
03915       /* If this call no longer exists, but the channel still
03916        * references it we need to set the channel's tech_pvt to null
03917        * to avoid ast_channel_free() trying to free it.
03918        */
03919       c->tech_pvt = NULL;
03920    }
03921    ast_mutex_unlock(&iaxsl[callno]);
03922    ast_verb(3, "Hungup '%s'\n", c->name);
03923    return 0;
03924 }
03925 
03926 /*!
03927  * \note expects the pvt to be locked
03928  */
03929 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03930 {
03931    unsigned short callno = pvt->callno;
03932 
03933    if (!pvt->peercallno) {
03934       /* We don't know the remote side's call number, yet.  :( */
03935       int count = 10;
03936       while (count-- && pvt && !pvt->peercallno) {
03937          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03938          pvt = iaxs[callno];
03939       }
03940       if (!pvt->peercallno) {
03941          return -1;
03942       }
03943    }
03944 
03945    return 0;
03946 }
03947 
03948 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03949 {
03950    struct ast_option_header *h;
03951    int res;
03952 
03953    switch (option) {
03954    case AST_OPTION_TXGAIN:
03955    case AST_OPTION_RXGAIN:
03956       /* these two cannot be sent, because they require a result */
03957       errno = ENOSYS;
03958       return -1;
03959    default:
03960    {
03961       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03962       struct chan_iax2_pvt *pvt;
03963 
03964       ast_mutex_lock(&iaxsl[callno]);
03965       pvt = iaxs[callno];
03966 
03967       if (wait_for_peercallno(pvt)) {
03968          ast_mutex_unlock(&iaxsl[callno]);
03969          return -1;
03970       }
03971 
03972       ast_mutex_unlock(&iaxsl[callno]);
03973 
03974       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03975          return -1;
03976       }
03977 
03978       h->flag = AST_OPTION_FLAG_REQUEST;
03979       h->option = htons(option);
03980       memcpy(h->data, data, datalen);
03981       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03982                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03983                  datalen + sizeof(*h), -1);
03984       ast_free(h);
03985       return res;
03986    }
03987    }
03988 }
03989 
03990 static struct ast_frame *iax2_read(struct ast_channel *c) 
03991 {
03992    ast_log(LOG_NOTICE, "I should never be called!\n");
03993    return &ast_null_frame;
03994 }
03995 
03996 static int iax2_key_rotate(const void *vpvt)
03997 {
03998    int res = 0;
03999    struct chan_iax2_pvt *pvt = (void *) vpvt;
04000    struct MD5Context md5;
04001    char key[17] = "";
04002    struct iax_ie_data ied = {
04003       .pos = 0,   
04004    };
04005    
04006    ast_mutex_lock(&iaxsl[pvt->callno]);
04007    pvt->keyrotateid = 
04008       ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04009 
04010    snprintf(key, sizeof(key), "%lX", ast_random());
04011 
04012    MD5Init(&md5);
04013    MD5Update(&md5, (unsigned char *) key, strlen(key));
04014    MD5Final((unsigned char *) key, &md5);
04015 
04016    IAX_DEBUGDIGEST("Sending", key);
04017 
04018    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
04019 
04020    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
04021 
04022    build_ecx_key((unsigned char *) key, pvt);
04023 
04024    ast_mutex_unlock(&iaxsl[pvt->callno]);
04025 
04026    return res;
04027 }
04028 
04029 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
04030 {
04031    int res;
04032    struct iax_ie_data ied0;
04033    struct iax_ie_data ied1;
04034    unsigned int transferid = (unsigned int)ast_random();
04035 
04036    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
04037       ast_debug(1, "transfers are not supported for encrypted calls at this time");
04038       ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
04039       ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
04040       return 0;
04041    }
04042 
04043    memset(&ied0, 0, sizeof(ied0));
04044    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04045    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04046    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04047 
04048    memset(&ied1, 0, sizeof(ied1));
04049    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04050    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04051    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04052    
04053    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04054    if (res)
04055       return -1;
04056    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04057    if (res)
04058       return -1;
04059    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04060    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04061    return 0;
04062 }
04063 
04064 static void lock_both(unsigned short callno0, unsigned short callno1)
04065 {
04066    ast_mutex_lock(&iaxsl[callno0]);
04067    while (ast_mutex_trylock(&iaxsl[callno1])) {
04068       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04069    }
04070 }
04071 
04072 static void unlock_both(unsigned short callno0, unsigned short callno1)
04073 {
04074    ast_mutex_unlock(&iaxsl[callno1]);
04075    ast_mutex_unlock(&iaxsl[callno0]);
04076 }
04077 
04078 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)
04079 {
04080    struct ast_channel *cs[3];
04081    struct ast_channel *who, *other;
04082    int to = -1;
04083    int res = -1;
04084    int transferstarted=0;
04085    struct ast_frame *f;
04086    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
04087    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
04088    struct timeval waittimer = {0, 0};
04089 
04090    /* We currently do not support native bridging if a timeoutms value has been provided */
04091    if (timeoutms > 0) {
04092       return AST_BRIDGE_FAILED;
04093    }
04094 
04095    timeoutms = 0;
04096 
04097    lock_both(callno0, callno1);
04098    if (!iaxs[callno0] || !iaxs[callno1]) {
04099       unlock_both(callno0, callno1);
04100       return AST_BRIDGE_FAILED;
04101    }
04102    /* Put them in native bridge mode */
04103    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04104       iaxs[callno0]->bridgecallno = callno1;
04105       iaxs[callno1]->bridgecallno = callno0;
04106    }
04107    unlock_both(callno0, callno1);
04108 
04109    /* If not, try to bridge until we can execute a transfer, if we can */
04110    cs[0] = c0;
04111    cs[1] = c1;
04112    for (/* ever */;;) {
04113       /* Check in case we got masqueraded into */
04114       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04115          ast_verb(3, "Can't masquerade, we're different...\n");
04116          /* Remove from native mode */
04117          if (c0->tech == &iax2_tech) {
04118             ast_mutex_lock(&iaxsl[callno0]);
04119             iaxs[callno0]->bridgecallno = 0;
04120             ast_mutex_unlock(&iaxsl[callno0]);
04121          }
04122          if (c1->tech == &iax2_tech) {
04123             ast_mutex_lock(&iaxsl[callno1]);
04124             iaxs[callno1]->bridgecallno = 0;
04125             ast_mutex_unlock(&iaxsl[callno1]);
04126          }
04127          return AST_BRIDGE_FAILED_NOWARN;
04128       }
04129       if (c0->nativeformats != c1->nativeformats) {
04130             char buf0[255];
04131             char buf1[255];
04132             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04133             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04134          ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04135          /* Remove from native mode */
04136          lock_both(callno0, callno1);
04137          if (iaxs[callno0])
04138             iaxs[callno0]->bridgecallno = 0;
04139          if (iaxs[callno1])
04140             iaxs[callno1]->bridgecallno = 0;
04141          unlock_both(callno0, callno1);
04142          return AST_BRIDGE_FAILED_NOWARN;
04143       }
04144       /* check if transfered and if we really want native bridging */
04145       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04146          /* Try the transfer */
04147          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04148                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04149             ast_log(LOG_WARNING, "Unable to start the transfer\n");
04150          transferstarted = 1;
04151       }
04152       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04153          /* Call has been transferred.  We're no longer involved */
04154          struct timeval now = ast_tvnow();
04155          if (ast_tvzero(waittimer)) {
04156             waittimer = now;
04157          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04158             c0->_softhangup |= AST_SOFTHANGUP_DEV;
04159             c1->_softhangup |= AST_SOFTHANGUP_DEV;
04160             *fo = NULL;
04161             *rc = c0;
04162             res = AST_BRIDGE_COMPLETE;
04163             break;
04164          }
04165       }
04166       to = 1000;
04167       who = ast_waitfor_n(cs, 2, &to);
04168       if (timeoutms > -1) {
04169          timeoutms -= (1000 - to);
04170          if (timeoutms < 0)
04171             timeoutms = 0;
04172       }
04173       if (!who) {
04174          if (!timeoutms) {
04175             res = AST_BRIDGE_RETRY;
04176             break;
04177          }
04178          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04179             res = AST_BRIDGE_FAILED;
04180             break;
04181          }
04182          continue;
04183       }
04184       f = ast_read(who);
04185       if (!f) {
04186          *fo = NULL;
04187          *rc = who;
04188          res = AST_BRIDGE_COMPLETE;
04189          break;
04190       }
04191       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04192          *fo = f;
04193          *rc = who;
04194          res =  AST_BRIDGE_COMPLETE;
04195          break;
04196       }
04197       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
04198       if ((f->frametype == AST_FRAME_VOICE) ||
04199          (f->frametype == AST_FRAME_TEXT) ||
04200          (f->frametype == AST_FRAME_VIDEO) || 
04201          (f->frametype == AST_FRAME_IMAGE) ||
04202          (f->frametype == AST_FRAME_DTMF) ||
04203          (f->frametype == AST_FRAME_CONTROL)) {
04204          /* monitored dtmf take out of the bridge.
04205           * check if we monitor the specific source.
04206           */
04207          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04208          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04209             *rc = who;
04210             *fo = f;
04211             res = AST_BRIDGE_COMPLETE;
04212             /* Remove from native mode */
04213             break;
04214          }
04215          /* everything else goes to the other side */
04216          ast_write(other, f);
04217       }
04218       ast_frfree(f);
04219       /* Swap who gets priority */
04220       cs[2] = cs[0];
04221       cs[0] = cs[1];
04222       cs[1] = cs[2];
04223    }
04224    lock_both(callno0, callno1);
04225    if(iaxs[callno0])
04226       iaxs[callno0]->bridgecallno = 0;
04227    if(iaxs[callno1])
04228       iaxs[callno1]->bridgecallno = 0;
04229    unlock_both(callno0, callno1);
04230    return res;
04231 }
04232 
04233 static int iax2_answer(struct ast_channel *c)
04234 {
04235    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04236    ast_debug(1, "Answering IAX2 call\n");
04237    ast_mutex_lock(&iaxsl[callno]);
04238    if (iaxs[callno])
04239       iax2_ami_channelupdate(iaxs[callno]);
04240    ast_mutex_unlock(&iaxsl[callno]);
04241    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04242 }
04243 
04244 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
04245 {
04246    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04247    struct chan_iax2_pvt *pvt;
04248    int res = 0;
04249 
04250    if (iaxdebug)
04251       ast_debug(1, "Indicating condition %d\n", condition);
04252 
04253    ast_mutex_lock(&iaxsl[callno]);
04254    pvt = iaxs[callno];
04255 
04256    if (wait_for_peercallno(pvt)) {
04257       res = -1;
04258       goto done;
04259    }
04260 
04261    switch (condition) {
04262    case AST_CONTROL_HOLD:
04263       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04264          ast_moh_start(c, data, pvt->mohinterpret);
04265          goto done;
04266       }
04267       break;
04268    case AST_CONTROL_UNHOLD:
04269       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04270          ast_moh_stop(c);
04271          goto done;
04272       }
04273    }
04274 
04275    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04276 
04277 done:
04278    ast_mutex_unlock(&iaxsl[callno]);
04279 
04280    return res;
04281 }
04282    
04283 static int iax2_transfer(struct ast_channel *c, const char *dest)
04284 {
04285    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04286    struct iax_ie_data ied = { "", };
04287    char tmp[256], *context;
04288    ast_copy_string(tmp, dest, sizeof(tmp));
04289    context = strchr(tmp, '@');
04290    if (context) {
04291       *context = '\0';
04292       context++;
04293    }
04294    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04295    if (context)
04296       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04297    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
04298    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04299 }
04300    
04301 static int iax2_getpeertrunk(struct sockaddr_in sin)
04302 {
04303    struct iax2_peer *peer;
04304    int res = 0;
04305    struct ao2_iterator i;
04306 
04307    i = ao2_iterator_init(peers, 0);
04308    while ((peer = ao2_iterator_next(&i))) {
04309       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04310           (peer->addr.sin_port == sin.sin_port)) {
04311          res = ast_test_flag(peer, IAX_TRUNK);
04312          peer_unref(peer);
04313          break;
04314       }
04315       peer_unref(peer);
04316    }
04317 
04318    return res;
04319 }
04320 
04321 /*! \brief  Create new call, interface with the PBX core */
04322 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
04323 {
04324    struct ast_channel *tmp;
04325    struct chan_iax2_pvt *i;
04326    struct ast_variable *v = NULL;
04327 
04328    if (!(i = iaxs[callno])) {
04329       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04330       return NULL;
04331    }
04332 
04333    /* Don't hold call lock */
04334    ast_mutex_unlock(&iaxsl[callno]);
04335    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);
04336    ast_mutex_lock(&iaxsl[callno]);
04337    if (i != iaxs[callno]) {
04338       if (tmp) {
04339          /* unlock and relock iaxsl[callno] to preserve locking order */
04340          ast_mutex_unlock(&iaxsl[callno]);
04341          ast_channel_free(tmp);
04342          ast_mutex_lock(&iaxsl[callno]);
04343       }
04344       return NULL;
04345    }
04346    iax2_ami_channelupdate(i);
04347    if (!tmp)
04348       return NULL;
04349    tmp->tech = &iax2_tech;
04350    /* We can support any format by default, until we get restricted */
04351    tmp->nativeformats = capability;
04352    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04353    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04354    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04355 
04356    if (!ast_strlen_zero(i->parkinglot))
04357       ast_string_field_set(tmp, parkinglot, i->parkinglot);
04358    /* Don't use ast_set_callerid() here because it will
04359     * generate a NewCallerID event before the NewChannel event */
04360    if (!ast_strlen_zero(i->ani))
04361       tmp->cid.cid_ani = ast_strdup(i->ani);
04362    else
04363       tmp->cid.cid_ani = ast_strdup(i->cid_num);
04364    tmp->cid.cid_dnid = ast_strdup(i->dnid);
04365    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04366    tmp->cid.cid_pres = i->calling_pres;
04367    tmp->cid.cid_ton = i->calling_ton;
04368    tmp->cid.cid_tns = i->calling_tns;
04369    if (!ast_strlen_zero(i->language))
04370       ast_string_field_set(tmp, language, i->language);
04371    if (!ast_strlen_zero(i->accountcode))
04372       ast_string_field_set(tmp, accountcode, i->accountcode);
04373    if (i->amaflags)
04374       tmp->amaflags = i->amaflags;
04375    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04376    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04377    if (i->adsi)
04378       tmp->adsicpe = i->peeradsicpe;
04379    else
04380       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04381    i->owner = tmp;
04382    i->capability = capability;
04383 
04384    /* Set inherited variables */
04385    if (i->vars) {
04386       for (v = i->vars ; v ; v = v->next)
04387          pbx_builtin_setvar_helper(tmp, v->name, v->value);
04388    }
04389    if (i->iaxvars) {
04390       struct ast_datastore *variablestore;
04391       struct ast_variable *var, *prev = NULL;
04392       AST_LIST_HEAD(, ast_var_t) *varlist;
04393       ast_debug(1, "Loading up the channel with IAXVARs\n");
04394       varlist = ast_calloc(1, sizeof(*varlist));
04395       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
04396       if (variablestore && varlist) {
04397          variablestore->data = varlist;
04398          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
04399          AST_LIST_HEAD_INIT(varlist);
04400          for (var = i->iaxvars; var; var = var->next) {
04401             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
04402             if (prev)
04403                ast_free(prev);
04404             prev = var;
04405             if (!newvar) {
04406                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
04407                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
04408             } else {
04409                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
04410             }
04411          }
04412          if (prev)
04413             ast_free(prev);
04414          i->iaxvars = NULL;
04415          ast_channel_datastore_add(i->owner, variablestore);
04416       } else {
04417          if (variablestore) {
04418             ast_datastore_free(variablestore);
04419          }
04420          if (varlist) {
04421             ast_free(varlist);
04422          }
04423       }
04424    }
04425 
04426    if (state != AST_STATE_DOWN) {
04427       if (ast_pbx_start(tmp)) {
04428          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04429          ast_hangup(tmp);
04430          i->owner = NULL;
04431          return NULL;
04432       }
04433    }
04434 
04435    ast_module_ref(ast_module_info->self);
04436    return tmp;
04437 }
04438 
04439 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
04440 {
04441    unsigned long int mssincetx; /* unsigned to handle overflows */
04442    long int ms, pred;
04443 
04444    tpeer->trunkact = *now;
04445    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
04446    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04447       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
04448       tpeer->txtrunktime = *now;
04449       tpeer->lastsent = 999999;
04450    }
04451    /* Update last transmit time now */
04452    tpeer->lasttxtime = *now;
04453    
04454    /* Calculate ms offset */
04455    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
04456    /* Predict from last value */
04457    pred = tpeer->lastsent + sampms;
04458    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04459       ms = pred;
04460    
04461    /* We never send the same timestamp twice, so fudge a little if we must */
04462    if (ms == tpeer->lastsent)
04463       ms = tpeer->lastsent + 1;
04464    tpeer->lastsent = ms;
04465    return ms;
04466 }
04467 
04468 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
04469 {
04470    long ms; /* NOT unsigned */
04471    if (ast_tvzero(iaxs[callno]->rxcore)) {
04472       /* Initialize rxcore time if appropriate */
04473       iaxs[callno]->rxcore = ast_tvnow();
04474       /* Round to nearest 20ms so traces look pretty */
04475       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04476    }
04477    /* Calculate difference between trunk and channel */
04478    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
04479    /* Return as the sum of trunk time and the difference between trunk and real time */
04480    return ms + ts;
04481 }
04482 
04483 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04484 {
04485    int ms;
04486    int voice = 0;
04487    int genuine = 0;
04488    int adjust;
04489    struct timeval *delivery = NULL;
04490 
04491 
04492    /* What sort of frame do we have?: voice is self-explanatory
04493       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
04494       non-genuine frames are CONTROL frames [ringing etc], DTMF
04495       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
04496       the others need a timestamp slaved to the voice frames so that they go in sequence
04497    */
04498    if (f) {
04499       if (f->frametype == AST_FRAME_VOICE) {
04500          voice = 1;
04501          delivery = &f->delivery;
04502       } else if (f->frametype == AST_FRAME_IAX) {
04503          genuine = 1;
04504       } else if (f->frametype == AST_FRAME_CNG) {
04505          p->notsilenttx = 0;  
04506       }
04507    }
04508    if (ast_tvzero(p->offset)) {
04509       p->offset = ast_tvnow();
04510       /* Round to nearest 20ms for nice looking traces */
04511       p->offset.tv_usec -= p->offset.tv_usec % 20000;
04512    }
04513    /* If the timestamp is specified, just send it as is */
04514    if (ts)
04515       return ts;
04516    /* If we have a time that the frame arrived, always use it to make our timestamp */
04517    if (delivery && !ast_tvzero(*delivery)) {
04518       ms = ast_tvdiff_ms(*delivery, p->offset);
04519       if (iaxdebug)
04520          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04521    } else {
04522       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04523       if (ms < 0)
04524          ms = 0;
04525       if (voice) {
04526          /* On a voice frame, use predicted values if appropriate */
04527          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04528             /* Adjust our txcore, keeping voice and non-voice synchronized */
04529             /* AN EXPLANATION:
04530                When we send voice, we usually send "calculated" timestamps worked out
04531                on the basis of the number of samples sent. When we send other frames,
04532                we usually send timestamps worked out from the real clock.
04533                The problem is that they can tend to drift out of step because the 
04534                   source channel's clock and our clock may not be exactly at the same rate.
04535                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
04536                for this call.  Moving it adjusts timestamps for non-voice frames.
04537                We make the adjustment in the style of a moving average.  Each time we
04538                adjust p->offset by 10% of the difference between our clock-derived
04539                timestamp and the predicted timestamp.  That's why you see "10000"
04540                below even though IAX2 timestamps are in milliseconds.
04541                The use of a moving average avoids offset moving too radically.
04542                Generally, "adjust" roams back and forth around 0, with offset hardly
04543                changing at all.  But if a consistent different starts to develop it
04544                will be eliminated over the course of 10 frames (200-300msecs) 
04545             */
04546             adjust = (ms - p->nextpred);
04547             if (adjust < 0)
04548                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04549             else if (adjust > 0)
04550                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04551 
04552             if (!p->nextpred) {
04553                p->nextpred = ms; /*f->samples / 8;*/
04554                if (p->nextpred <= p->lastsent)
04555                   p->nextpred = p->lastsent + 3;
04556             }
04557             ms = p->nextpred;
04558          } else {
04559                 /* in this case, just use the actual
04560             * time, since we're either way off
04561             * (shouldn't happen), or we're  ending a
04562             * silent period -- and seed the next
04563             * predicted time.  Also, round ms to the
04564             * next multiple of frame size (so our
04565             * silent periods are multiples of
04566             * frame size too) */
04567 
04568             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04569                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04570                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04571 
04572             if (f->samples >= 8) /* check to make sure we dont core dump */
04573             {
04574                int diff = ms % (f->samples / 8);
04575                if (diff)
04576                    ms += f->samples/8 - diff;
04577             }
04578 
04579             p->nextpred = ms;
04580             p->notsilenttx = 1;
04581          }
04582       } else if ( f->frametype == AST_FRAME_VIDEO ) {
04583          /*
04584          * IAX2 draft 03 says that timestamps MUST be in order.
04585          * It does not say anything about several frames having the same timestamp
04586          * When transporting video, we can have a frame that spans multiple iax packets
04587          * (so called slices), so it would make sense to use the same timestamp for all of
04588          * them
04589          * We do want to make sure that frames don't go backwards though
04590          */
04591          if ( (unsigned int)ms < p->lastsent )
04592             ms = p->lastsent;
04593       } else {
04594          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
04595             it's a genuine frame */
04596          if (genuine) {
04597             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
04598             if (ms <= p->lastsent)
04599                ms = p->lastsent + 3;
04600          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04601             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
04602             ms = p->lastsent + 3;
04603          }
04604       }
04605    }
04606    p->lastsent = ms;
04607    if (voice)
04608       p->nextpred = p->nextpred + f->samples / 8;
04609    return ms;
04610 }
04611 
04612 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04613 {
04614    /* Returns where in "receive time" we are.  That is, how many ms
04615       since we received (or would have received) the frame with timestamp 0 */
04616    int ms;
04617 #ifdef IAXTESTS
04618    int jit;
04619 #endif /* IAXTESTS */
04620    /* Setup rxcore if necessary */
04621    if (ast_tvzero(p->rxcore)) {
04622       p->rxcore = ast_tvnow();
04623       if (iaxdebug)
04624          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04625                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04626       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04627 #if 1
04628       if (iaxdebug)
04629          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04630                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04631 #endif
04632    }
04633 
04634    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04635 #ifdef IAXTESTS
04636    if (test_jit) {
04637       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04638          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04639          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04640             jit = -jit;
04641          ms += jit;
04642       }
04643    }
04644    if (test_late) {
04645       ms += test_late;
04646       test_late = 0;
04647    }
04648 #endif /* IAXTESTS */
04649    return ms;
04650 }
04651 
04652 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04653 {
04654    struct iax2_trunk_peer *tpeer = NULL;
04655    
04656    /* Finds and locks trunk peer */
04657    AST_LIST_LOCK(&tpeers);
04658 
04659    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
04660       if (!inaddrcmp(&tpeer->addr, sin)) {
04661          ast_mutex_lock(&tpeer->lock);
04662          break;
04663       }
04664    }
04665 
04666    if (!tpeer) {
04667       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04668          ast_mutex_init(&tpeer->lock);
04669          tpeer->lastsent = 9999;
04670          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04671          tpeer->trunkact = ast_tvnow();
04672          ast_mutex_lock(&tpeer->lock);
04673          tpeer->sockfd = fd;
04674 #ifdef SO_NO_CHECK
04675          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04676 #endif
04677          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04678          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
04679       }
04680    }
04681 
04682    AST_LIST_UNLOCK(&tpeers);
04683 
04684    return tpeer;
04685 }
04686 
04687 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04688 {
04689    struct ast_frame *f;
04690    struct iax2_trunk_peer *tpeer;
04691    void *tmp, *ptr;
04692    struct timeval now;
04693    int res; 
04694    struct ast_iax2_meta_trunk_entry *met;
04695    struct ast_iax2_meta_trunk_mini *mtm;
04696 
04697    f = &fr->af;
04698    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04699    if (tpeer) {
04700       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04701          /* Need to reallocate space */
04702          if (tpeer->trunkdataalloc < trunkmaxsize) {
04703             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04704                ast_mutex_unlock(&tpeer->lock);
04705                return -1;
04706             }
04707             
04708             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04709             tpeer->trunkdata = tmp;
04710             ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
04711          } else {
04712             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));
04713             ast_mutex_unlock(&tpeer->lock);
04714             return -1;
04715          }
04716       }
04717 
04718       /* Append to meta frame */
04719       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04720       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04721          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04722          mtm->len = htons(f->datalen);
04723          mtm->mini.callno = htons(pvt->callno);
04724          mtm->mini.ts = htons(0xffff & fr->ts);
04725          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04726          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04727       } else {
04728          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04729          /* Store call number and length in meta header */
04730          met->callno = htons(pvt->callno);
04731          met->len = htons(f->datalen);
04732          /* Advance pointers/decrease length past trunk entry header */
04733          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04734          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04735       }
04736       /* Copy actual trunk data */
04737       memcpy(ptr, f->data.ptr, f->datalen);
04738       tpeer->trunkdatalen += f->datalen;
04739 
04740       tpeer->calls++;
04741 
04742       /* track the largest mtu we actually have sent */
04743       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
04744          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
04745 
04746       /* if we have enough for a full MTU, ship it now without waiting */
04747       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
04748          now = ast_tvnow();
04749          res = send_trunk(tpeer, &now); 
04750          trunk_untimed ++; 
04751       }
04752 
04753       ast_mutex_unlock(&tpeer->lock);
04754    }
04755    return 0;
04756 }
04757 
04758 /* IAX2 encryption requires 16 to 32 bytes of random padding to be present
04759  * before the encryption data.  This function randomizes that data. */
04760 static void build_rand_pad(unsigned char *buf, ssize_t len)
04761 {
04762    long tmp;
04763    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
04764       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
04765       buf += sizeof(tmp);
04766       len -= sizeof(tmp);
04767    }
04768 }
04769 
04770 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04771 {
04772    build_ecx_key(digest, pvt);
04773    ast_aes_decrypt_key(digest, &pvt->dcx);
04774 }
04775 
04776 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04777 {
04778    /* it is required to hold the corresponding decrypt key to our encrypt key
04779     * in the pvt struct because queued frames occasionally need to be decrypted and
04780     * re-encrypted when updated for a retransmission */
04781    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
04782    ast_aes_encrypt_key(digest, &pvt->ecx);
04783    ast_aes_decrypt_key(digest, &pvt->mydcx);
04784 }
04785 
04786 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
04787 {
04788 #if 0
04789    /* Debug with "fake encryption" */
04790    int x;
04791    if (len % 16)
04792       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04793    for (x=0;x<len;x++)
04794       dst[x] = src[x] ^ 0xff;
04795 #else 
04796    unsigned char lastblock[16] = { 0 };
04797    int x;
04798    while(len > 0) {
04799       ast_aes_decrypt(src, dst, dcx);
04800       for (x=0;x<16;x++)
04801          dst[x] ^= lastblock[x];
04802       memcpy(lastblock, src, sizeof(lastblock));
04803       dst += 16;
04804       src += 16;
04805       len -= 16;
04806    }
04807 #endif
04808 }
04809 
04810 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
04811 {
04812 #if 0
04813    /* Debug with "fake encryption" */
04814    int x;
04815    if (len % 16)
04816       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04817    for (x=0;x<len;x++)
04818       dst[x] = src[x] ^ 0xff;
04819 #else
04820    unsigned char curblock[16] = { 0 };
04821    int x;
04822    while(len > 0) {
04823       for (x=0;x<16;x++)
04824          curblock[x] ^= src[x];
04825       ast_aes_encrypt(curblock, dst, ecx);
04826       memcpy(curblock, dst, sizeof(curblock)); 
04827       dst += 16;
04828       src += 16;
04829       len -= 16;
04830    }
04831 #endif
04832 }
04833 
04834 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04835 {
04836    int padding;
04837    unsigned char *workspace;
04838 
04839    workspace = alloca(*datalen);
04840    memset(f, 0, sizeof(*f));
04841    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04842       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04843       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04844          return -1;
04845       /* Decrypt */
04846       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04847 
04848       padding = 16 + (workspace[15] & 0x0f);
04849       if (iaxdebug)
04850          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04851       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04852          return -1;
04853 
04854       *datalen -= padding;
04855       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04856       f->frametype = fh->type;
04857       if (f->frametype == AST_FRAME_VIDEO) {
04858          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04859       } else {
04860          f->subclass = uncompress_subclass(fh->csub);
04861       }
04862    } else {
04863       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04864       if (iaxdebug)
04865          ast_debug(1, "Decoding mini with length %d\n", *datalen);
04866       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04867          return -1;
04868       /* Decrypt */
04869       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04870       padding = 16 + (workspace[15] & 0x0f);
04871       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04872          return -1;
04873       *datalen -= padding;
04874       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04875    }
04876    return 0;
04877 }
04878 
04879 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04880 {
04881    int padding;
04882    unsigned char *workspace;
04883    workspace = alloca(*datalen + 32);
04884    if (!workspace)
04885       return -1;
04886    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04887       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04888       if (iaxdebug)
04889          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04890       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04891       padding = 16 + (padding & 0xf);
04892       memcpy(workspace, poo, padding);
04893       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04894       workspace[15] &= 0xf0;
04895       workspace[15] |= (padding & 0xf);
04896       if (iaxdebug)
04897          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04898       *datalen += padding;
04899       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04900       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04901          memcpy(poo, workspace + *datalen - 32, 32);
04902    } else {
04903       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04904       if (iaxdebug)
04905          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
04906       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04907       padding = 16 + (padding & 0xf);
04908       memcpy(workspace, poo, padding);
04909       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04910       workspace[15] &= 0xf0;
04911       workspace[15] |= (padding & 0x0f);
04912       *datalen += padding;
04913       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04914       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04915          memcpy(poo, workspace + *datalen - 32, 32);
04916    }
04917    return 0;
04918 }
04919 
04920 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04921 {
04922    int res=-1;
04923    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04924       /* Search for possible keys, given secrets */
04925       struct MD5Context md5;
04926       unsigned char digest[16];
04927       char *tmppw, *stringp;
04928       
04929       tmppw = ast_strdupa(iaxs[callno]->secret);
04930       stringp = tmppw;
04931       while ((tmppw = strsep(&stringp, ";"))) {
04932          MD5Init(&md5);
04933          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04934          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04935          MD5Final(digest, &md5);
04936          build_encryption_keys(digest, iaxs[callno]);
04937          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04938          if (!res) {
04939             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04940             break;
04941          }
04942       }
04943    } else 
04944       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04945    return res;
04946 }
04947 
04948 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04949 {
04950    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04951       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04952       or delayed, with retransmission */
04953    struct ast_iax2_full_hdr *fh;
04954    struct ast_iax2_mini_hdr *mh;
04955    struct ast_iax2_video_hdr *vh;
04956    struct {
04957       struct iax_frame fr2;
04958       unsigned char buffer[4096];
04959    } frb;
04960    struct iax_frame *fr;
04961    int res;
04962    int sendmini=0;
04963    unsigned int lastsent;
04964    unsigned int fts;
04965 
04966    frb.fr2.afdatalen = sizeof(frb.buffer);
04967 
04968    if (!pvt) {
04969       ast_log(LOG_WARNING, "No private structure for packet?\n");
04970       return -1;
04971    }
04972    
04973    lastsent = pvt->lastsent;
04974 
04975    /* Calculate actual timestamp */
04976    fts = calc_timestamp(pvt, ts, f);
04977 
04978    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04979     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04980     * increment the "predicted timestamps" for voice, if we're predicting */
04981    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04982       return 0;
04983 #if 0
04984    ast_log(LOG_NOTICE, 
04985       "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
04986       *("=!" + (f->frametype == AST_FRAME_VOICE)),
04987       IAX_CALLENCRYPTED(pvt) ? "" : "not ",
04988       pvt->keyrotateid != -1 ? "" : "no "
04989    );
04990 #endif
04991    if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
04992       iax2_key_rotate(pvt);
04993    }
04994 
04995    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04996          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04997          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04998       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04999        (f->frametype == AST_FRAME_VOICE) 
05000       /* is a voice frame */ &&
05001       (f->subclass == pvt->svoiceformat) 
05002       /* is the same type */ ) {
05003          /* Force immediate rather than delayed transmission */
05004          now = 1;
05005          /* Mark that mini-style frame is appropriate */
05006          sendmini = 1;
05007    }
05008    if ( f->frametype == AST_FRAME_VIDEO ) {
05009       /*
05010        * If the lower 15 bits of the timestamp roll over, or if
05011        * the video format changed then send a full frame.
05012        * Otherwise send a mini video frame
05013        */
05014       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05015           ((f->subclass & ~0x1) == pvt->svideoformat)
05016          ) {
05017          now = 1;
05018          sendmini = 1;
05019       } else {
05020          now = 0;
05021          sendmini = 0;
05022       }
05023       pvt->lastvsent = fts;
05024    }
05025    /* Allocate an iax_frame */
05026    if (now) {
05027       fr = &frb.fr2;
05028    } else
05029       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));
05030    if (!fr) {
05031       ast_log(LOG_WARNING, "Out of memory\n");
05032       return -1;
05033    }
05034    /* Copy our prospective frame into our immediate or retransmitted wrapper */
05035    iax_frame_wrap(fr, f);
05036 
05037    fr->ts = fts;
05038    fr->callno = pvt->callno;
05039    fr->transfer = transfer;
05040    fr->final = final;
05041    fr->encmethods = 0;
05042    if (!sendmini) {
05043       /* We need a full frame */
05044       if (seqno > -1)
05045          fr->oseqno = seqno;
05046       else
05047          fr->oseqno = pvt->oseqno++;
05048       fr->iseqno = pvt->iseqno;
05049       fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
05050       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05051       fh->ts = htonl(fr->ts);
05052       fh->oseqno = fr->oseqno;
05053       if (transfer) {
05054          fh->iseqno = 0;
05055       } else
05056          fh->iseqno = fr->iseqno;
05057       /* Keep track of the last thing we've acknowledged */
05058       if (!transfer)
05059          pvt->aseqno = fr->iseqno;
05060       fh->type = fr->af.frametype & 0xFF;
05061       if (fr->af.frametype == AST_FRAME_VIDEO)
05062          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05063       else
05064          fh->csub = compress_subclass(fr->af.subclass);
05065       if (transfer) {
05066          fr->dcallno = pvt->transfercallno;
05067       } else
05068          fr->dcallno = pvt->peercallno;
05069       fh->dcallno = htons(fr->dcallno);
05070       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05071       fr->data = fh;
05072       fr->retries = 0;
05073       /* Retry after 2x the ping time has passed */
05074       fr->retrytime = pvt->pingtime * 2;
05075       if (fr->retrytime < MIN_RETRY_TIME)
05076          fr->retrytime = MIN_RETRY_TIME;
05077       if (fr->retrytime > MAX_RETRY_TIME)
05078          fr->retrytime = MAX_RETRY_TIME;
05079       /* Acks' don't get retried */
05080       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
05081          fr->retries = -1;
05082       else if (f->frametype == AST_FRAME_VOICE)
05083          pvt->svoiceformat = f->subclass;
05084       else if (f->frametype == AST_FRAME_VIDEO)
05085          pvt->svideoformat = f->subclass & ~0x1;
05086       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05087          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05088             if (fr->transfer)
05089                iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05090             else
05091                iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05092             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05093             fr->encmethods = pvt->encmethods;
05094             fr->ecx = pvt->ecx;
05095             fr->mydcx = pvt->mydcx;
05096             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05097          } else
05098             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05099       }
05100    
05101       if (now) {
05102          res = send_packet(fr);
05103       } else
05104          res = iax2_transmit(fr);
05105    } else {
05106       if (ast_test_flag(pvt, IAX_TRUNK)) {
05107          iax2_trunk_queue(pvt, fr);
05108          res = 0;
05109       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05110          /* Video frame have no sequence number */
05111          fr->oseqno = -1;
05112          fr->iseqno = -1;
05113          vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
05114          vh->zeros = 0;
05115          vh->callno = htons(0x8000 | fr->callno);
05116          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05117          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05118          fr->data = vh;
05119          fr->retries = -1;
05120          res = send_packet(fr);        
05121       } else {
05122          /* Mini-frames have no sequence number */
05123          fr->oseqno = -1;
05124          fr->iseqno = -1;
05125          /* Mini frame will do */
05126          mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
05127          mh->callno = htons(fr->callno);
05128          mh->ts = htons(fr->ts & 0xFFFF);
05129          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05130          fr->data = mh;
05131          fr->retries = -1;
05132          if (pvt->transferring == TRANSFER_MEDIAPASS)
05133             fr->transfer = 1;
05134          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05135             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05136                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05137             } else
05138                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05139          }
05140          res = send_packet(fr);
05141       }
05142    }
05143    return res;
05144 }
05145 
05146 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05147 {
05148    regex_t regexbuf;
05149    int havepattern = 0;
05150 
05151 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
05152 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
05153 
05154    struct iax2_user *user = NULL;
05155    char auth[90];
05156    char *pstr = "";
05157    struct ao2_iterator i;
05158 
05159    switch (cmd) {
05160    case CLI_INIT:
05161       e->command = "iax2 show users [like]";
05162       e->usage =
05163          "Usage: iax2 show users [like <pattern>]\n"
05164          "       Lists all known IAX2 users.\n"
05165          "       Optional regular expression pattern is used to filter the user list.\n";
05166       return NULL;
05167    case CLI_GENERATE:
05168       return NULL;
05169    }
05170 
05171    switch (a->argc) {
05172    case 5:
05173       if (!strcasecmp(a->argv[3], "like")) {
05174          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
05175             return CLI_SHOWUSAGE;
05176          havepattern = 1;
05177       } else
05178          return CLI_SHOWUSAGE;
05179    case 3:
05180       break;
05181    default:
05182       return CLI_SHOWUSAGE;
05183    }
05184 
05185    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05186    i = ao2_iterator_init(users, 0);
05187    for (user = ao2_iterator_next(&i); user; 
05188       user_unref(user), user = ao2_iterator_next(&i)) {
05189       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
05190          continue;
05191       
05192       if (!ast_strlen_zero(user->secret)) {
05193          ast_copy_string(auth,user->secret, sizeof(auth));
05194       } else if (!ast_strlen_zero(user->inkeys)) {
05195          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05196       } else
05197          ast_copy_string(auth, "-no secret-", sizeof(auth));
05198       
05199       if(ast_test_flag(user,IAX_CODEC_NOCAP))
05200          pstr = "REQ Only";
05201       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05202          pstr = "Disabled";
05203       else
05204          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05205       
05206       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
05207          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
05208          user->ha ? "Yes" : "No", pstr);
05209    }
05210 
05211    if (havepattern)
05212       regfree(&regexbuf);
05213 
05214    return CLI_SUCCESS;
05215 #undef FORMAT
05216 #undef FORMAT2
05217 }
05218 
05219 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
05220 {
05221    regex_t regexbuf;
05222    int havepattern = 0;
05223    int total_peers = 0;
05224    int online_peers = 0;
05225    int offline_peers = 0;
05226    int unmonitored_peers = 0;
05227    struct ao2_iterator i;
05228 
05229 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
05230 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
05231 
05232    struct iax2_peer *peer = NULL;
05233    char name[256];
05234    int registeredonly=0;
05235    char *term = manager ? "\r\n" : "\n";
05236    char idtext[256] = "";
05237    switch (argc) {
05238    case 6:
05239       if (!strcasecmp(argv[3], "registered"))
05240          registeredonly = 1;
05241       else
05242          return RESULT_SHOWUSAGE;
05243       if (!strcasecmp(argv[4], "like")) {
05244          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05245             return RESULT_SHOWUSAGE;
05246          havepattern = 1;
05247       } else
05248          return RESULT_SHOWUSAGE;
05249       break;
05250    case 5:
05251       if (!strcasecmp(argv[3], "like")) {
05252          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05253             return RESULT_SHOWUSAGE;
05254          havepattern = 1;
05255       } else
05256          return RESULT_SHOWUSAGE;
05257       break;
05258    case 4:
05259       if (!strcasecmp(argv[3], "registered"))
05260          registeredonly = 1;
05261       else
05262          return RESULT_SHOWUSAGE;
05263       break;
05264    case 3:
05265       break;
05266    default:
05267       return RESULT_SHOWUSAGE;
05268    }
05269 
05270 
05271    if (!s)
05272       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05273 
05274    i = ao2_iterator_init(peers, 0);
05275    for (peer = ao2_iterator_next(&i); peer; 
05276       peer_unref(peer), peer = ao2_iterator_next(&i)) {
05277       char nm[20];
05278       char status[20];
05279       char srch[2000];
05280       int retstatus;
05281 
05282       if (registeredonly && !peer->addr.sin_addr.s_addr)
05283          continue;
05284       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
05285          continue;
05286 
05287       if (!ast_strlen_zero(peer->username))
05288          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05289       else
05290          ast_copy_string(name, peer->name, sizeof(name));
05291       
05292       retstatus = peer_status(peer, status, sizeof(status));
05293       if (retstatus > 0)
05294          online_peers++;
05295       else if (!retstatus)
05296          offline_peers++;
05297       else
05298          unmonitored_peers++;
05299       
05300       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05301       
05302       snprintf(srch, sizeof(srch), FORMAT, name, 
05303           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05304           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05305           nm,
05306           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05307           peer->encmethods ? "(E)" : "   ", status, term);
05308       
05309       if (s)
05310          astman_append(s, 
05311             "Event: PeerEntry\r\n%s"
05312             "Channeltype: IAX2\r\n"
05313             "ChanObjectType: peer\r\n"
05314             "ObjectName: %s\r\n"
05315             "IPaddress: %s\r\n"
05316             "IPport: %d\r\n"
05317             "Dynamic: %s\r\n"
05318             "Status: %s\r\n\r\n",
05319             idtext,
05320             name,
05321             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
05322             ntohs(peer->addr.sin_port),
05323             ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
05324             status);
05325       
05326       else
05327          ast_cli(fd, FORMAT, name, 
05328             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05329             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05330             nm,
05331             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05332             peer->encmethods ? "(E)" : "   ", status, term);
05333       total_peers++;
05334    }
05335 
05336    if (!s)
05337       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05338 
05339    if (havepattern)
05340       regfree(&regexbuf);
05341 
05342    return RESULT_SUCCESS;
05343 #undef FORMAT
05344 #undef FORMAT2
05345 }
05346 
05347 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05348 {
05349    struct iax2_thread *thread = NULL;
05350    time_t t;
05351    int threadcount = 0, dynamiccount = 0;
05352    char type;
05353 
05354    switch (cmd) {
05355    case CLI_INIT:
05356       e->command = "iax2 show threads";
05357       e->usage =
05358          "Usage: iax2 show threads\n"
05359          "       Lists status of IAX helper threads\n";
05360       return NULL;
05361    case CLI_GENERATE:
05362       return NULL;
05363    }
05364    if (a->argc != 3)
05365       return CLI_SHOWUSAGE;
05366       
05367    ast_cli(a->fd, "IAX2 Thread Information\n");
05368    time(&t);
05369    ast_cli(a->fd, "Idle Threads:\n");
05370    AST_LIST_LOCK(&idle_list);
05371    AST_LIST_TRAVERSE(&idle_list, thread, list) {
05372 #ifdef DEBUG_SCHED_MULTITHREAD
05373       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
05374          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05375 #else
05376       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
05377          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05378 #endif
05379       threadcount++;
05380    }
05381    AST_LIST_UNLOCK(&idle_list);
05382    ast_cli(a->fd, "Active Threads:\n");
05383    AST_LIST_LOCK(&active_list);
05384    AST_LIST_TRAVERSE(&active_list, thread, list) {
05385       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
05386          type = 'D';
05387       else
05388          type = 'P';
05389 #ifdef DEBUG_SCHED_MULTITHREAD
05390       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
05391          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05392 #else
05393       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
05394          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05395 #endif
05396       threadcount++;
05397    }
05398    AST_LIST_UNLOCK(&active_list);
05399    ast_cli(a->fd, "Dynamic Threads:\n");
05400    AST_LIST_LOCK(&dynamic_list);
05401    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05402 #ifdef DEBUG_SCHED_MULTITHREAD
05403       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05404          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05405 #else
05406       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05407          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05408 #endif
05409       dynamiccount++;
05410    }
05411    AST_LIST_UNLOCK(&dynamic_list);
05412    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05413    return CLI_SUCCESS;
05414 }
05415 
05416 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05417 {
05418    struct iax2_peer *p;
05419 
05420    switch (cmd) {
05421    case CLI_INIT:
05422       e->command = "iax2 unregister";
05423       e->usage =
05424          "Usage: iax2 unregister <peername>\n"
05425          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
05426       return NULL;
05427    case CLI_GENERATE:
05428       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
05429    }
05430 
05431    if (a->argc != 3)
05432       return CLI_SHOWUSAGE;
05433 
05434    p = find_peer(a->argv[2], 1);
05435    if (p) {
05436       if (p->expire > 0) {
05437          struct iax2_peer tmp_peer = {
05438             .name = a->argv[2],
05439          };
05440          struct iax2_peer *peer;
05441 
05442          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
05443          if (peer) {
05444             expire_registry(peer_ref(peer)); /* will release its own reference when done */
05445             peer_unref(peer); /* ref from ao2_find() */
05446             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
05447          } else {
05448             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
05449          }
05450       } else {
05451          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
05452       }
05453    } else {
05454       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
05455    }
05456    return CLI_SUCCESS;
05457 }
05458 
05459 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
05460 {
05461    int which = 0;
05462    struct iax2_peer *p = NULL;
05463    char *res = NULL;
05464    int wordlen = strlen(word);
05465 
05466    /* 0 - iax2; 1 - unregister; 2 - <peername> */
05467    if (pos == 2) {
05468       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05469       while ((p = ao2_iterator_next(&i))) {
05470          if (!strncasecmp(p->name, word, wordlen) && 
05471             ++which > state && p->expire > 0) {
05472             res = ast_strdup(p->name);
05473             peer_unref(p);
05474             break;
05475          }
05476          peer_unref(p);
05477       }
05478    }
05479 
05480    return res;
05481 }
05482 
05483 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05484 {
05485    switch (cmd) {
05486    case CLI_INIT:
05487       e->command = "iax2 show peers";
05488       e->usage =
05489          "Usage: iax2 show peers [registered] [like <pattern>]\n"
05490          "       Lists all known IAX2 peers.\n"
05491          "       Optional 'registered' argument lists only peers with known addresses.\n"
05492          "       Optional regular expression pattern is used to filter the peer list.\n";
05493       return NULL;
05494    case CLI_GENERATE:
05495       return NULL;
05496    }
05497 
05498    switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
05499    case RESULT_SHOWUSAGE:
05500       return CLI_SHOWUSAGE;
05501    case RESULT_FAILURE:
05502       return CLI_FAILURE;
05503    default:
05504       return CLI_SUCCESS;
05505    }
05506 }
05507 
05508 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
05509 {
05510    ast_cli_netstats(s, -1, 0);
05511    astman_append(s, "\r\n");
05512    return RESULT_SUCCESS;
05513 }
05514 
05515 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05516 {
05517    struct iax_firmware *cur = NULL;
05518 
05519    switch (cmd) {
05520    case CLI_INIT:
05521       e->command = "iax2 show firmware";
05522       e->usage =
05523          "Usage: iax2 show firmware\n"
05524          "       Lists all known IAX firmware images.\n";
05525       return NULL;
05526    case CLI_GENERATE:
05527       return NULL;
05528    }
05529 
05530    if (a->argc != 3 && a->argc != 4)
05531       return CLI_SHOWUSAGE;
05532 
05533    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
05534    AST_LIST_LOCK(&firmwares);
05535    AST_LIST_TRAVERSE(&firmwares, cur, list) {
05536       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
05537          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
05538             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
05539       }
05540    }
05541    AST_LIST_UNLOCK(&firmwares);
05542 
05543    return CLI_SUCCESS;
05544 }
05545 
05546 /*! \brief callback to display iax peers in manager */
05547 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05548 {
05549    char *a[] = { "iax2", "show", "users" };
05550    const char *id = astman_get_header(m,"ActionID");
05551    char idtext[256] = "";
05552 
05553    if (!ast_strlen_zero(id))
05554       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05555    astman_send_ack(s, m, "Peer status list will follow");
05556    return __iax2_show_peers(1, -1, s, 3, a );
05557 } 
05558 
05559 /*! \brief callback to display iax peers in manager format */
05560 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
05561 {
05562    struct iax2_peer *peer = NULL;
05563    int peer_count = 0;
05564    char nm[20];
05565    char status[20];
05566    const char *id = astman_get_header(m,"ActionID");
05567    char idtext[256] = "";
05568    struct ao2_iterator i;
05569 
05570    if (!ast_strlen_zero(id))
05571       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05572 
05573    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
05574 
05575 
05576    i = ao2_iterator_init(peers, 0);
05577    for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
05578 
05579       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
05580       if (!ast_strlen_zero(peer->username)) {
05581          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
05582       } else {
05583          astman_append(s, "ObjectName: %s\r\n", peer->name);
05584       }
05585       astman_append(s, "ChanObjectType: peer\r\n");
05586       astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
05587       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05588       astman_append(s, "Mask: %s\r\n", nm);
05589       astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
05590       astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
05591       peer_status(peer, status, sizeof(status));
05592       astman_append(s, "Status: %s\r\n\r\n", status);
05593       peer_count++;
05594    }
05595 
05596    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
05597    return RESULT_SUCCESS;
05598 }
05599 
05600 
05601 static char *regstate2str(int regstate)
05602 {
05603    switch(regstate) {
05604    case REG_STATE_UNREGISTERED:
05605       return "Unregistered";
05606    case REG_STATE_REGSENT:
05607       return "Request Sent";
05608    case REG_STATE_AUTHSENT:
05609       return "Auth. Sent";
05610    case REG_STATE_REGISTERED:
05611       return "Registered";
05612    case REG_STATE_REJECTED:
05613       return "Rejected";
05614    case REG_STATE_TIMEOUT:
05615       return "Timeout";
05616    case REG_STATE_NOAUTH:
05617       return "No Authentication";
05618    default:
05619       return "Unknown";
05620    }
05621 }
05622 
05623 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05624 {
05625 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
05626 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
05627    struct iax2_registry *reg = NULL;
05628    char host[80];
05629    char perceived[80];
05630    int counter = 0;
05631 
05632    switch (cmd) {
05633    case CLI_INIT:
05634       e->command = "iax2 show registry";
05635       e->usage =
05636          "Usage: iax2 show registry\n"
05637          "       Lists all registration requests and status.\n";
05638       return NULL;
05639    case CLI_GENERATE:
05640       return NULL;
05641    }
05642    if (a->argc != 3)
05643       return CLI_SHOWUSAGE;
05644    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05645    AST_LIST_LOCK(&registrations);
05646    AST_LIST_TRAVERSE(&registrations, reg, entry) {
05647       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05648       if (reg->us.sin_addr.s_addr) 
05649          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05650       else
05651          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05652       ast_cli(a->fd, FORMAT, host, 
05653                (reg->dnsmgr) ? "Y" : "N", 
05654                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05655       counter++;
05656    }
05657    AST_LIST_UNLOCK(&registrations);
05658    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
05659    return CLI_SUCCESS;
05660 #undef FORMAT
05661 #undef FORMAT2
05662 }
05663 
05664 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05665 {
05666 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
05667 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
05668 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
05669    int x;
05670    int numchans = 0;
05671 
05672    switch (cmd) {
05673    case CLI_INIT:
05674       e->command = "iax2 show channels";
05675       e->usage =
05676          "Usage: iax2 show channels\n"
05677          "       Lists all currently active IAX channels.\n";
05678       return NULL;
05679    case CLI_GENERATE:
05680       return NULL;
05681    }
05682 
05683    if (a->argc != 3)
05684       return CLI_SHOWUSAGE;
05685    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
05686    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05687       ast_mutex_lock(&iaxsl[x]);
05688       if (iaxs[x]) {
05689          int lag, jitter, localdelay;
05690          jb_info jbinfo;
05691          
05692          if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05693             jb_getinfo(iaxs[x]->jb, &jbinfo);
05694             jitter = jbinfo.jitter;
05695             localdelay = jbinfo.current - jbinfo.min;
05696          } else {
05697             jitter = -1;
05698             localdelay = 0;
05699          }
05700          lag = iaxs[x]->remote_rr.delay;
05701          ast_cli(a->fd, FORMAT,
05702             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05703             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
05704             S_OR(iaxs[x]->username, "(None)"),
05705             iaxs[x]->callno, iaxs[x]->peercallno,
05706             iaxs[x]->oseqno, iaxs[x]->iseqno,
05707             lag,
05708             jitter,
05709             localdelay,
05710             ast_getformatname(iaxs[x]->voiceformat) );
05711          numchans++;
05712       }
05713       ast_mutex_unlock(&iaxsl[x]);
05714    }
05715    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05716    return CLI_SUCCESS;
05717 #undef FORMAT
05718 #undef FORMAT2
05719 #undef FORMATB
05720 }
05721 
05722 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05723 {
05724    int x;
05725    int numchans = 0;
05726 #define ACN_FORMAT1 "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"
05727 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"
05728    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05729       ast_mutex_lock(&iaxsl[x]);
05730       if (iaxs[x]) {
05731          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05732          jb_info jbinfo;
05733          
05734          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05735             jb_getinfo(iaxs[x]->jb, &jbinfo);
05736             localjitter = jbinfo.jitter;
05737             localdelay = jbinfo.current - jbinfo.min;
05738             locallost = jbinfo.frames_lost;
05739             locallosspct = jbinfo.losspct/1000;
05740             localdropped = jbinfo.frames_dropped;
05741             localooo = jbinfo.frames_ooo;
05742          } else {
05743             localjitter = -1;
05744             localdelay = 0;
05745             locallost = -1;
05746             locallosspct = -1;
05747             localdropped = 0;
05748             localooo = -1;
05749          }
05750          if (s)
05751             
05752             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05753                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05754                      iaxs[x]->pingtime,
05755                      localjitter, 
05756                      localdelay,
05757                      locallost,
05758                      locallosspct,
05759                      localdropped,
05760                      localooo,
05761                      iaxs[x]->frames_received/1000,
05762                      iaxs[x]->remote_rr.jitter,
05763                      iaxs[x]->remote_rr.delay,
05764                      iaxs[x]->remote_rr.losscnt,
05765                      iaxs[x]->remote_rr.losspct,
05766                      iaxs[x]->remote_rr.dropped,
05767                      iaxs[x]->remote_rr.ooo,
05768                      iaxs[x]->remote_rr.packets/1000);
05769          else
05770             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05771                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05772                iaxs[x]->pingtime,
05773                localjitter, 
05774                localdelay,
05775                locallost,
05776                locallosspct,
05777                localdropped,
05778                localooo,
05779                iaxs[x]->frames_received/1000,
05780                iaxs[x]->remote_rr.jitter,
05781                iaxs[x]->remote_rr.delay,
05782                iaxs[x]->remote_rr.losscnt,
05783                iaxs[x]->remote_rr.losspct,
05784                iaxs[x]->remote_rr.dropped,
05785                iaxs[x]->remote_rr.ooo,
05786                iaxs[x]->remote_rr.packets/1000
05787                );
05788          numchans++;
05789       }
05790       ast_mutex_unlock(&iaxsl[x]);
05791    }
05792 
05793    return numchans;
05794 }
05795 
05796 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05797 {
05798    int numchans = 0;
05799 
05800    switch (cmd) {
05801    case CLI_INIT:
05802       e->command = "iax2 show netstats";
05803       e->usage =
05804          "Usage: iax2 show netstats\n"
05805          "       Lists network status for all currently active IAX channels.\n";
05806       return NULL;
05807    case CLI_GENERATE:
05808       return NULL;
05809    }
05810    if (a->argc != 3)
05811       return CLI_SHOWUSAGE;
05812    ast_cli(a->fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
05813    ast_cli(a->fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
05814    numchans = ast_cli_netstats(NULL, a->fd, 1);
05815    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05816    return CLI_SUCCESS;
05817 }
05818 
05819 
05820 
05821 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05822 {
05823    switch (cmd) {
05824    case CLI_INIT:
05825       e->command = "iax2 set debug {on|off|peer}";
05826       e->usage =
05827          "Usage: iax2 set debug {on|off|peer peername}\n"
05828          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
05829       return NULL;
05830    case CLI_GENERATE:
05831       if (a->pos == 4)
05832          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
05833       return NULL;
05834    }
05835 
05836    if (a->argc < e->args  || a->argc > e->args + 1)
05837       return CLI_SHOWUSAGE;
05838 
05839    if (!strcasecmp(a->argv[3], "peer")) {
05840       struct iax2_peer *peer;
05841 
05842       if (a->argc != e->args + 1)
05843          return CLI_SHOWUSAGE;
05844 
05845       peer = find_peer(a->argv[4], 1);
05846 
05847       if (!peer) {
05848          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
05849          return CLI_FAILURE;
05850       }
05851 
05852       debugaddr.sin_addr = peer->addr.sin_addr;
05853       debugaddr.sin_port = peer->addr.sin_port;
05854 
05855       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
05856          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
05857 
05858       ao2_ref(peer, -1);
05859    } else if (!strncasecmp(a->argv[3], "on", 2)) {
05860       iaxdebug = 1;
05861       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05862    } else {
05863       iaxdebug = 0;
05864       memset(&debugaddr, 0, sizeof(debugaddr));
05865       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05866    }
05867    return CLI_SUCCESS;
05868 }
05869 
05870 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05871 {
05872    switch (cmd) {
05873    case CLI_INIT:
05874       e->command = "iax2 set debug trunk {on|off}";
05875       e->usage =
05876          "Usage: iax2 set debug trunk {on|off}\n"
05877          "       Enables/Disables debugging of IAX trunking\n";
05878       return NULL;
05879    case CLI_GENERATE:
05880       return NULL;
05881    }
05882 
05883    if (a->argc != e->args)
05884       return CLI_SHOWUSAGE;
05885 
05886    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
05887       iaxtrunkdebug = 1;
05888       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05889    } else {
05890       iaxtrunkdebug = 0;
05891       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05892    }
05893    return CLI_SUCCESS;
05894 }
05895 
05896 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05897 {
05898    switch (cmd) {
05899    case CLI_INIT:
05900       e->command = "iax2 set debug jb {on|off}";
05901       e->usage =
05902          "Usage: iax2 set debug jb {on|off}\n"
05903          "       Enables/Disables jitterbuffer debugging information\n";
05904       return NULL;
05905    case CLI_GENERATE:
05906       return NULL;
05907    }
05908 
05909    if (a->argc != e->args)
05910       return CLI_SHOWUSAGE;
05911    
05912    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05913       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05914       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05915    } else {
05916       jb_setoutput(jb_error_output, jb_warning_output, NULL);
05917       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05918    }
05919    return CLI_SUCCESS;
05920 }
05921 
05922 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05923 {
05924    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05925    int res = -1;
05926    ast_mutex_lock(&iaxsl[callno]);
05927    if (iaxs[callno]) {
05928    /* If there's an outstanding error, return failure now */
05929       if (!iaxs[callno]->error) {
05930          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05931             res = 0;
05932             /* Don't waste bandwidth sending null frames */
05933          else if (f->frametype == AST_FRAME_NULL)
05934             res = 0;
05935          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05936             res = 0;
05937          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05938             res = 0;
05939          else
05940          /* Simple, just queue for transmission */
05941             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05942       } else {
05943          ast_debug(1, "Write error: %s\n", strerror(errno));
05944       }
05945    }
05946    /* If it's already gone, just return */
05947    ast_mutex_unlock(&iaxsl[callno]);
05948    return res;
05949 }
05950 
05951 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05952       int now, int transfer, int final)
05953 {
05954    struct ast_frame f = { 0, };
05955 
05956    f.frametype = type;
05957    f.subclass = command;
05958    f.datalen = datalen;
05959    f.src = __FUNCTION__;
05960    f.data.ptr = (void *) data;
05961 
05962    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05963 }
05964 
05965 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05966 {
05967    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05968 }
05969 
05970 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05971 {
05972    int res;
05973    ast_mutex_lock(&iaxsl[callno]);
05974    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05975    ast_mutex_unlock(&iaxsl[callno]);
05976    return res;
05977 }
05978 
05979 /*!
05980  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05981  *       the pvt struct for the given call number may disappear during its 
05982  *       execution.
05983  */
05984 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)
05985 {
05986    int call_num = i->callno;
05987    /* It is assumed that the callno has already been locked */
05988    iax2_predestroy(i->callno);
05989    if (!iaxs[call_num])
05990       return -1;
05991    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05992 }
05993 
05994 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)
05995 {
05996    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05997 }
05998 
05999 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
06000 {
06001    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06002 }
06003 
06004 static int apply_context(struct iax2_context *con, const char *context)
06005 {
06006    while(con) {
06007       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06008          return -1;
06009       con = con->next;
06010    }
06011    return 0;
06012 }
06013 
06014 
06015 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06016 {
06017    /* Start pessimistic */
06018    int res = -1;
06019    int version = 2;
06020    struct iax2_user *user = NULL, *best = NULL;
06021    int bestscore = 0;
06022    int gotcapability = 0;
06023    struct ast_variable *v = NULL, *tmpvar = NULL;
06024    struct ao2_iterator i;
06025 
06026    if (!iaxs[callno])
06027       return res;
06028    if (ies->called_number)
06029       ast_string_field_set(iaxs[callno], exten, ies->called_number);
06030    if (ies->calling_number) {
06031       ast_shrink_phone_number(ies->calling_number);
06032       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06033    }
06034    if (ies->calling_name)
06035       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06036    if (ies->calling_ani)
06037       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06038    if (ies->dnid)
06039       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06040    if (ies->rdnis)
06041       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06042    if (ies->called_context)
06043       ast_string_field_set(iaxs[callno], context, ies->called_context);
06044    if (ies->language)
06045       ast_string_field_set(iaxs[callno], language, ies->language);
06046    if (ies->username)
06047       ast_string_field_set(iaxs[callno], username, ies->username);
06048    if (ies->calling_ton > -1)
06049       iaxs[callno]->calling_ton = ies->calling_ton;
06050    if (ies->calling_tns > -1)
06051       iaxs[callno]->calling_tns = ies->calling_tns;
06052    if (ies->calling_pres > -1)
06053       iaxs[callno]->calling_pres = ies->calling_pres;
06054    if (ies->format)
06055       iaxs[callno]->peerformat = ies->format;
06056    if (ies->adsicpe)
06057       iaxs[callno]->peeradsicpe = ies->adsicpe;
06058    if (ies->capability) {
06059       gotcapability = 1;
06060       iaxs[callno]->peercapability = ies->capability;
06061    } 
06062    if (ies->version)
06063       version = ies->version;
06064 
06065    /* Use provided preferences until told otherwise for actual preferences */
06066    if(ies->codec_prefs) {
06067       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06068       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06069    }
06070 
06071    if (!gotcapability) 
06072       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06073    if (version > IAX_PROTO_VERSION) {
06074       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
06075          ast_inet_ntoa(sin->sin_addr), version);
06076       return res;
06077    }
06078    /* Search the userlist for a compatible entry, and fill in the rest */
06079    i = ao2_iterator_init(users, 0);
06080    while ((user = ao2_iterator_next(&i))) {
06081       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
06082          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
06083          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
06084          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
06085               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
06086          if (!ast_strlen_zero(iaxs[callno]->username)) {
06087             /* Exact match, stop right now. */
06088             if (best)
06089                user_unref(best);
06090             best = user;
06091             break;
06092          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06093             /* No required authentication */
06094             if (user->ha) {
06095                /* There was host authentication and we passed, bonus! */
06096                if (bestscore < 4) {
06097                   bestscore = 4;
06098                   if (best)
06099                      user_unref(best);
06100                   best = user;
06101                   continue;
06102                }
06103             } else {
06104                /* No host access, but no secret, either, not bad */
06105                if (bestscore < 3) {
06106                   bestscore = 3;
06107                   if (best)
06108                      user_unref(best);
06109                   best = user;
06110                   continue;
06111                }
06112             }
06113          } else {
06114             if (user->ha) {
06115                /* Authentication, but host access too, eh, it's something.. */
06116                if (bestscore < 2) {
06117                   bestscore = 2;
06118                   if (best)
06119                      user_unref(best);
06120                   best = user;
06121                   continue;
06122                }
06123             } else {
06124                /* Authentication and no host access...  This is our baseline */
06125                if (bestscore < 1) {
06126                   bestscore = 1;
06127                   if (best)
06128                      user_unref(best);
06129                   best = user;
06130                   continue;
06131                }
06132             }
06133          }
06134       }
06135       user_unref(user);
06136    }
06137    user = best;
06138    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06139       user = realtime_user(iaxs[callno]->username, sin);
06140       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
06141           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
06142          user = user_unref(user);
06143       }
06144    }
06145    if (user) {
06146       /* We found our match (use the first) */
06147       /* copy vars */
06148       for (v = user->vars ; v ; v = v->next) {
06149          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
06150             tmpvar->next = iaxs[callno]->vars; 
06151             iaxs[callno]->vars = tmpvar;
06152          }
06153       }
06154       /* If a max AUTHREQ restriction is in place, activate it */
06155       if (user->maxauthreq > 0)
06156          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06157       iaxs[callno]->prefs = user->prefs;
06158       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06159       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06160       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06161       iaxs[callno]->encmethods = user->encmethods;
06162       /* Store the requested username if not specified */
06163       if (ast_strlen_zero(iaxs[callno]->username))
06164          ast_string_field_set(iaxs[callno], username, user->name);
06165       /* Store whether this is a trunked call, too, of course, and move if appropriate */
06166       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06167       iaxs[callno]->capability = user->capability;
06168       /* And use the default context */
06169       if (ast_strlen_zero(iaxs[callno]->context)) {
06170          if (user->contexts)
06171             ast_string_field_set(iaxs[callno], context, user->contexts->context);
06172          else
06173             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
06174       }
06175       /* And any input keys */
06176       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06177       /* And the permitted authentication methods */
06178       iaxs[callno]->authmethods = user->authmethods;
06179       iaxs[callno]->adsi = user->adsi;
06180       /* If the user has callerid, override the remote caller id. */
06181       if (ast_test_flag(user, IAX_HASCALLERID)) {
06182          iaxs[callno]->calling_tns = 0;
06183          iaxs[callno]->calling_ton = 0;
06184          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06185          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06186          ast_string_field_set(iaxs[callno], ani, user->cid_num);
06187          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06188       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06189          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06190       } /* else user is allowed to set their own CID settings */
06191       if (!ast_strlen_zero(user->accountcode))
06192          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06193       if (!ast_strlen_zero(user->mohinterpret))
06194          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06195       if (!ast_strlen_zero(user->mohsuggest))
06196          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06197       if (!ast_strlen_zero(user->parkinglot))
06198          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
06199       if (user->amaflags)
06200          iaxs[callno]->amaflags = user->amaflags;
06201       if (!ast_strlen_zero(user->language))
06202          ast_string_field_set(iaxs[callno], language, user->language);
06203       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
06204       /* Keep this check last */
06205       if (!ast_strlen_zero(user->dbsecret)) {
06206          char *family, *key=NULL;
06207          char buf[80];
06208          family = ast_strdupa(user->dbsecret);
06209          key = strchr(family, '/');
06210          if (key) {
06211             *key = '\0';
06212             key++;
06213          }
06214          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06215             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06216          else
06217             ast_string_field_set(iaxs[callno], secret, buf);
06218       } else
06219          ast_string_field_set(iaxs[callno], secret, user->secret);
06220       res = 0;
06221       user = user_unref(user);
06222    } else {
06223        /* user was not found, but we should still fake an AUTHREQ.
06224         * Set authmethods to the last known authmethod used by the system
06225         * Set a fake secret, it's not looked at, just required to attempt authentication.
06226         * Set authrej so the AUTHREP is rejected without even looking at its contents */
06227       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06228       ast_string_field_set(iaxs[callno], secret, "badsecret");
06229       iaxs[callno]->authrej = 1;
06230       if (!ast_strlen_zero(iaxs[callno]->username)) {
06231          /* only send the AUTHREQ if a username was specified. */
06232          res = 0;
06233       }
06234    }
06235    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
06236    return res;
06237 }
06238 
06239 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
06240 {
06241    struct ast_iax2_full_hdr fh;
06242    fh.scallno = htons(src | IAX_FLAG_FULL);
06243    fh.dcallno = htons(dst);
06244    fh.ts = 0;
06245    fh.oseqno = 0;
06246    fh.iseqno = 0;
06247    fh.type = AST_FRAME_IAX;
06248    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06249    iax_outputframe(NULL, &fh, 0, sin, 0);
06250 #if 0
06251    if (option_debug)
06252 #endif   
06253       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06254          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06255    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06256 }
06257 
06258 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
06259 {
06260    /* Select exactly one common encryption if there are any */
06261    p->encmethods &= enc;
06262    if (p->encmethods) {
06263       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
06264          p->keyrotateid = -2;
06265       }
06266       if (p->encmethods & IAX_ENCRYPT_AES128)
06267          p->encmethods = IAX_ENCRYPT_AES128;
06268       else
06269          p->encmethods = 0;
06270    }
06271 }
06272 
06273 /*!
06274  * \pre iaxsl[call_num] is locked
06275  *
06276  * \note Since this function calls send_command_final(), the pvt struct for the given
06277  *       call number may disappear while executing this function.
06278  */
06279 static int authenticate_request(int call_num)
06280 {
06281    struct iax_ie_data ied;
06282    int res = -1, authreq_restrict = 0;
06283    char challenge[10];
06284    struct chan_iax2_pvt *p = iaxs[call_num];
06285 
06286    memset(&ied, 0, sizeof(ied));
06287 
06288    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
06289    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06290       struct iax2_user *user, tmp_user = {
06291          .name = p->username, 
06292       };
06293 
06294       user = ao2_find(users, &tmp_user, OBJ_POINTER);
06295       if (user) {
06296          if (user->curauthreq == user->maxauthreq)
06297             authreq_restrict = 1;
06298          else
06299             user->curauthreq++;
06300          user = user_unref(user);
06301       }
06302    }
06303 
06304    /* If the AUTHREQ limit test failed, send back an error */
06305    if (authreq_restrict) {
06306       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06307       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06308       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06309       return 0;
06310    }
06311 
06312    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06313    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06314       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06315       ast_string_field_set(p, challenge, challenge);
06316       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
06317       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06318    }
06319    if (p->encmethods)
06320       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06321 
06322    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06323 
06324    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06325 
06326    if (p->encmethods)
06327       ast_set_flag(p, IAX_ENCRYPTED);
06328 
06329    return res;
06330 }
06331 
06332 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
06333 {
06334    char requeststr[256];
06335    char md5secret[256] = "";
06336    char secret[256] = "";
06337    char rsasecret[256] = "";
06338    int res = -1; 
06339    int x;
06340    struct iax2_user *user, tmp_user = {
06341       .name = p->username, 
06342    };
06343 
06344    if (p->authrej) {
06345       return res;
06346    }
06347    user = ao2_find(users, &tmp_user, OBJ_POINTER);
06348    if (user) {
06349       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06350          ast_atomic_fetchadd_int(&user->curauthreq, -1);
06351          ast_clear_flag(p, IAX_MAXAUTHREQ);
06352       }
06353       ast_string_field_set(p, host, user->name);
06354       user = user_unref(user);
06355    }
06356 
06357    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06358       return res;
06359    if (ies->password)
06360       ast_copy_string(secret, ies->password, sizeof(secret));
06361    if (ies->md5_result)
06362       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06363    if (ies->rsa_result)
06364       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06365    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06366       struct ast_key *key;
06367       char *keyn;
06368       char tmpkey[256];
06369       char *stringp=NULL;
06370       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06371       stringp=tmpkey;
06372       keyn = strsep(&stringp, ":");
06373       while(keyn) {
06374          key = ast_key_get(keyn, AST_KEY_PUBLIC);
06375          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06376             res = 0;
06377             break;
06378          } else if (!key)
06379             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06380          keyn = strsep(&stringp, ":");
06381       }
06382    } else if (p->authmethods & IAX_AUTH_MD5) {
06383       struct MD5Context md5;
06384       unsigned char digest[16];
06385       char *tmppw, *stringp;
06386       
06387       tmppw = ast_strdupa(p->secret);
06388       stringp = tmppw;
06389       while((tmppw = strsep(&stringp, ";"))) {
06390          MD5Init(&md5);
06391          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06392          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06393          MD5Final(digest, &md5);
06394          /* If they support md5, authenticate with it.  */
06395          for (x=0;x<16;x++)
06396             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06397          if (!strcasecmp(requeststr, md5secret)) {
06398             res = 0;
06399             break;
06400          }
06401       }
06402    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06403       if (!strcmp(secret, p->secret))
06404          res = 0;
06405    }
06406    return res;
06407 }
06408 
06409 /*! \brief Verify inbound registration */
06410 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06411 {
06412    char requeststr[256] = "";
06413    char peer[256] = "";
06414    char md5secret[256] = "";
06415    char rsasecret[256] = "";
06416    char secret[256] = "";
06417    struct iax2_peer *p = NULL;
06418    struct ast_key *key;
06419    char *keyn;
06420    int x;
06421    int expire = 0;
06422    int res = -1;
06423 
06424    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06425    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
06426    if (ies->username)
06427       ast_copy_string(peer, ies->username, sizeof(peer));
06428    if (ies->password)
06429       ast_copy_string(secret, ies->password, sizeof(secret));
06430    if (ies->md5_result)
06431       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06432    if (ies->rsa_result)
06433       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06434    if (ies->refresh)
06435       expire = ies->refresh;
06436 
06437    if (ast_strlen_zero(peer)) {
06438       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06439       return -1;
06440    }
06441 
06442    /* SLD: first call to lookup peer during registration */
06443    ast_mutex_unlock(&iaxsl[callno]);
06444    p = find_peer(peer, 1);
06445    ast_mutex_lock(&iaxsl[callno]);
06446    if (!p || !iaxs[callno]) {
06447       if (iaxs[callno]) {
06448          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06449          /* Anything, as long as it's non-blank */
06450          ast_string_field_set(iaxs[callno], secret, "badsecret");
06451          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
06452           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
06453           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
06454           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
06455           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
06456           *
06457           * If none of these cases exist, res will be returned as 0 without authentication indicating
06458           * an AUTHREQ needs to be sent out. */
06459 
06460          if (ast_strlen_zero(iaxs[callno]->challenge) &&
06461             !(!ast_strlen_zero(secret) && plaintext)) {
06462             /* by setting res to 0, an REGAUTH will be sent */
06463             res = 0;
06464          }
06465       }
06466       if (authdebug && !p)
06467          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06468       goto return_unref;
06469    }
06470 
06471    if (!ast_test_flag(p, IAX_DYNAMIC)) {
06472       if (authdebug)
06473          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06474       goto return_unref;
06475    }
06476 
06477    if (!ast_apply_ha(p->ha, sin)) {
06478       if (authdebug)
06479          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06480       goto return_unref;
06481    }
06482    ast_string_field_set(iaxs[callno], secret, p->secret);
06483    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06484    /* Check secret against what we have on file */
06485    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06486       if (!ast_strlen_zero(p->inkeys)) {
06487          char tmpkeys[256];
06488          char *stringp=NULL;
06489          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06490          stringp=tmpkeys;
06491          keyn = strsep(&stringp, ":");
06492          while(keyn) {
06493             key = ast_key_get(keyn, AST_KEY_PUBLIC);
06494             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06495                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06496                break;
06497             } else if (!key)
06498                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06499             keyn = strsep(&stringp, ":");
06500          }
06501          if (!keyn) {
06502             if (authdebug)
06503                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06504             goto return_unref;
06505          }
06506       } else {
06507          if (authdebug)
06508             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06509          goto return_unref;
06510       }
06511    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06512       struct MD5Context md5;
06513       unsigned char digest[16];
06514       char *tmppw, *stringp;
06515 
06516       tmppw = ast_strdupa(p->secret);
06517       stringp = tmppw;
06518       while((tmppw = strsep(&stringp, ";"))) {
06519          MD5Init(&md5);
06520          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06521          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06522          MD5Final(digest, &md5);
06523          for (x=0;x<16;x++)
06524             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06525          if (!strcasecmp(requeststr, md5secret))
06526             break;
06527       }
06528       if (tmppw) {
06529          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06530       } else {
06531          if (authdebug)
06532             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06533          goto return_unref;
06534       }
06535    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06536       /* They've provided a plain text password and we support that */
06537       if (strcmp(secret, p->secret)) {
06538          if (authdebug)
06539             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06540          goto return_unref;
06541       } else
06542          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06543    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06544       /* if challenge has been sent, but no challenge response if given, reject. */
06545       goto return_unref;
06546    }
06547    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
06548 
06549    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
06550    res = 0;
06551 
06552 return_unref:
06553    if (iaxs[callno]) {
06554       ast_string_field_set(iaxs[callno], peer, peer);
06555 
06556       /* Choose lowest expiry number */
06557       if (expire && (expire < iaxs[callno]->expiry)) {
06558          iaxs[callno]->expiry = expire;
06559       }
06560    }
06561 
06562    if (p) {
06563       peer_unref(p);
06564    }
06565    return res;
06566 }
06567 
06568 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)
06569 {
06570    int res = -1;
06571    int x;
06572    if (!ast_strlen_zero(keyn)) {
06573       if (!(authmethods & IAX_AUTH_RSA)) {
06574          if (ast_strlen_zero(secret)) 
06575             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));
06576       } else if (ast_strlen_zero(challenge)) {
06577          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06578       } else {
06579          char sig[256];
06580          struct ast_key *key;
06581          key = ast_key_get(keyn, AST_KEY_PRIVATE);
06582          if (!key) {
06583             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06584          } else {
06585             if (ast_sign(key, (char*)challenge, sig)) {
06586                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06587                res = -1;
06588             } else {
06589                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06590                res = 0;
06591             }
06592          }
06593       }
06594    } 
06595    /* Fall back */
06596    if (res && !ast_strlen_zero(secret)) {
06597       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06598          struct MD5Context md5;
06599          unsigned char digest[16];
06600          char digres[128];
06601          MD5Init(&md5);
06602          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06603          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06604          MD5Final(digest, &md5);
06605          /* If they support md5, authenticate with it.  */
06606          for (x=0;x<16;x++)
06607             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
06608          if (pvt) {
06609             build_encryption_keys(digest, pvt);
06610          }
06611          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06612          res = 0;
06613       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06614          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06615          res = 0;
06616       } else
06617          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06618    }
06619    return res;
06620 }
06621 
06622 /*!
06623  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
06624  *       so do not call this function with a pvt lock held.
06625  */
06626 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
06627 {
06628    struct iax2_peer *peer = NULL;
06629    /* Start pessimistic */
06630    int res = -1;
06631    int authmethods = 0;
06632    struct iax_ie_data ied;
06633    uint16_t callno = p->callno;
06634 
06635    memset(&ied, 0, sizeof(ied));
06636    
06637    if (ies->username)
06638       ast_string_field_set(p, username, ies->username);
06639    if (ies->challenge)
06640       ast_string_field_set(p, challenge, ies->challenge);
06641    if (ies->authmethods)
06642       authmethods = ies->authmethods;
06643    if (authmethods & IAX_AUTH_MD5)
06644       merge_encryption(p, ies->encmethods);
06645    else
06646       p->encmethods = 0;
06647 
06648    /* Check for override RSA authentication first */
06649    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06650       /* Normal password authentication */
06651       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06652    } else {
06653       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06654       while ((peer = ao2_iterator_next(&i))) {
06655          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
06656              /* No peer specified at our end, or this is the peer */
06657              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06658              /* No username specified in peer rule, or this is the right username */
06659              && (!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)))
06660              /* No specified host, or this is our host */
06661             ) {
06662             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06663             if (!res) {
06664                peer_unref(peer);
06665                break;
06666             }
06667          }
06668          peer_unref(peer);
06669       }
06670       if (!peer) {
06671          /* We checked our list and didn't find one.  It's unlikely, but possible, 
06672             that we're trying to authenticate *to* a realtime peer */
06673          const char *peer_name = ast_strdupa(p->peer);
06674          ast_mutex_unlock(&iaxsl[callno]);
06675          if ((peer = realtime_peer(peer_name, NULL))) {
06676             ast_mutex_lock(&iaxsl[callno]);
06677             if (!(p = iaxs[callno])) {
06678                peer_unref(peer);
06679                return -1;
06680             }
06681             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06682             peer_unref(peer);
06683          }
06684          if (!peer) {
06685             ast_mutex_lock(&iaxsl[callno]);
06686             if (!(p = iaxs[callno]))
06687                return -1;
06688          }
06689       }
06690    }
06691    if (ies->encmethods)
06692       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06693    if (!res) {
06694       struct ast_datastore *variablestore;
06695       struct ast_variable *var, *prev = NULL;
06696       AST_LIST_HEAD(, ast_var_t) *varlist;
06697       varlist = ast_calloc(1, sizeof(*varlist));
06698       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
06699       if (variablestore && varlist && p->owner) {
06700          variablestore->data = varlist;
06701          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
06702          AST_LIST_HEAD_INIT(varlist);
06703          for (var = ies->vars; var; var = var->next) {
06704             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
06705             if (prev)
06706                ast_free(prev);
06707             prev = var;
06708             if (!newvar) {
06709                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
06710                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06711             } else {
06712                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
06713             }
06714          }
06715          if (prev)
06716             ast_free(prev);
06717          ies->vars = NULL;
06718          ast_channel_datastore_add(p->owner, variablestore);
06719       } else {
06720          if (p->owner)
06721             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06722          if (variablestore)
06723             ast_datastore_free(variablestore);
06724          if (varlist)
06725             ast_free(varlist);
06726       }
06727    }
06728 
06729    if (!res)
06730       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06731    return res;
06732 }
06733 
06734 static int iax2_do_register(struct iax2_registry *reg);
06735 
06736 static void __iax2_do_register_s(const void *data)
06737 {
06738    struct iax2_registry *reg = (struct iax2_registry *)data;
06739    reg->expire = -1;
06740    iax2_do_register(reg);
06741 }
06742 
06743 static int iax2_do_register_s(const void *data)
06744 {
06745 #ifdef SCHED_MULTITHREADED
06746    if (schedule_action(__iax2_do_register_s, data))
06747 #endif      
06748       __iax2_do_register_s(data);
06749    return 0;
06750 }
06751 
06752 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06753 {
06754    int newcall = 0;
06755    char newip[256];
06756    struct iax_ie_data ied;
06757    struct sockaddr_in new;
06758    
06759    
06760    memset(&ied, 0, sizeof(ied));
06761    if (ies->apparent_addr)
06762       memmove(&new, ies->apparent_addr, sizeof(new));
06763    if (ies->callno)
06764       newcall = ies->callno;
06765    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
06766       ast_log(LOG_WARNING, "Invalid transfer request\n");
06767       return -1;
06768    }
06769    pvt->transfercallno = newcall;
06770    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
06771    inet_aton(newip, &pvt->transfer.sin_addr);
06772    pvt->transfer.sin_family = AF_INET;
06773    pvt->transferring = TRANSFER_BEGIN;
06774    pvt->transferid = ies->transferid;
06775    store_by_transfercallno(pvt);
06776    if (ies->transferid)
06777       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
06778    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
06779    return 0;
06780 }
06781 
06782 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06783 {
06784    char exten[256] = "";
06785    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
06786    struct iax2_dpcache *dp = NULL;
06787    
06788    if (ies->called_number)
06789       ast_copy_string(exten, ies->called_number, sizeof(exten));
06790    
06791    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
06792       status = CACHE_FLAG_EXISTS;
06793    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
06794       status = CACHE_FLAG_CANEXIST;
06795    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
06796       status = CACHE_FLAG_NONEXISTENT;
06797 
06798    if (ies->refresh)
06799       expiry = ies->refresh;
06800    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
06801       matchmore = CACHE_FLAG_MATCHMORE;
06802    
06803    AST_LIST_LOCK(&dpcache);
06804    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
06805       if (strcmp(dp->exten, exten))
06806          continue;
06807       AST_LIST_REMOVE_CURRENT(peer_list);
06808       dp->callno = 0;
06809       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06810       if (dp->flags & CACHE_FLAG_PENDING) {
06811          dp->flags &= ~CACHE_FLAG_PENDING;
06812          dp->flags |= status;
06813          dp->flags |= matchmore;
06814       }
06815       /* Wake up waiters */
06816       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06817          if (dp->waiters[x] > -1) {
06818             if (write(dp->waiters[x], "asdf", 4) < 0) {
06819             }
06820          }
06821       }
06822    }
06823    AST_LIST_TRAVERSE_SAFE_END;
06824    AST_LIST_UNLOCK(&dpcache);
06825 
06826    return 0;
06827 }
06828 
06829 static int complete_transfer(int callno, struct iax_ies *ies)
06830 {
06831    int peercallno = 0;
06832    struct chan_iax2_pvt *pvt = iaxs[callno];
06833    struct iax_frame *cur;
06834    jb_frame frame;
06835 
06836    if (ies->callno)
06837       peercallno = ies->callno;
06838 
06839    if (peercallno < 1) {
06840       ast_log(LOG_WARNING, "Invalid transfer request\n");
06841       return -1;
06842    }
06843    remove_by_transfercallno(pvt);
06844    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06845    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06846    /* Reset sequence numbers */
06847    pvt->oseqno = 0;
06848    pvt->rseqno = 0;
06849    pvt->iseqno = 0;
06850    pvt->aseqno = 0;
06851 
06852    if (pvt->peercallno) {
06853       remove_by_peercallno(pvt);
06854    }
06855    pvt->peercallno = peercallno;
06856    /*this is where the transfering call swiches hash tables */
06857    store_by_peercallno(pvt);
06858    pvt->transferring = TRANSFER_NONE;
06859    pvt->svoiceformat = -1;
06860    pvt->voiceformat = 0;
06861    pvt->svideoformat = -1;
06862    pvt->videoformat = 0;
06863    pvt->transfercallno = -1;
06864    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06865    memset(&pvt->offset, 0, sizeof(pvt->offset));
06866    /* reset jitterbuffer */
06867    while(jb_getall(pvt->jb,&frame) == JB_OK)
06868       iax2_frame_free(frame.data);
06869    jb_reset(pvt->jb);
06870    pvt->lag = 0;
06871    pvt->last = 0;
06872    pvt->lastsent = 0;
06873    pvt->nextpred = 0;
06874    pvt->pingtime = DEFAULT_RETRY_TIME;
06875    AST_LIST_LOCK(&frame_queue);
06876    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
06877       /* We must cancel any packets that would have been transmitted
06878          because now we're talking to someone new.  It's okay, they
06879          were transmitted to someone that didn't care anyway. */
06880       if (callno == cur->callno) 
06881          cur->retries = -1;
06882    }
06883    AST_LIST_UNLOCK(&frame_queue);
06884    return 0; 
06885 }
06886 
06887 /*! \brief Acknowledgment received for OUR registration */
06888 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06889 {
06890    struct iax2_registry *reg;
06891    /* Start pessimistic */
06892    char peer[256] = "";
06893    char msgstatus[60];
06894    int refresh = 60;
06895    char ourip[256] = "<Unspecified>";
06896    struct sockaddr_in oldus;
06897    struct sockaddr_in us;
06898    int oldmsgs;
06899 
06900    memset(&us, 0, sizeof(us));
06901    if (ies->apparent_addr)
06902       memmove(&us, ies->apparent_addr, sizeof(us));
06903    if (ies->username)
06904       ast_copy_string(peer, ies->username, sizeof(peer));
06905    if (ies->refresh)
06906       refresh = ies->refresh;
06907    if (ies->calling_number) {
06908       /* We don't do anything with it really, but maybe we should */
06909    }
06910    reg = iaxs[callno]->reg;
06911    if (!reg) {
06912       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06913       return -1;
06914    }
06915    memcpy(&oldus, &reg->us, sizeof(oldus));
06916    oldmsgs = reg->messages;
06917    if (inaddrcmp(&reg->addr, sin)) {
06918       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06919       return -1;
06920    }
06921    memcpy(&reg->us, &us, sizeof(reg->us));
06922    if (ies->msgcount >= 0)
06923       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
06924    /* always refresh the registration at the interval requested by the server
06925       we are registering to
06926    */
06927    reg->refresh = refresh;
06928    reg->expire = iax2_sched_replace(reg->expire, sched, 
06929       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06930    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
06931          if (reg->messages > 255)
06932             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06933          else if (reg->messages > 1)
06934             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06935          else if (reg->messages > 0)
06936             ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
06937          else
06938             ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
06939          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06940       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06941       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06942    }
06943    reg->regstate = REG_STATE_REGISTERED;
06944    return 0;
06945 }
06946 
06947 static int iax2_append_register(const char *hostname, const char *username,
06948    const char *secret, const char *porta)
06949 {
06950    struct iax2_registry *reg;
06951 
06952    if (!(reg = ast_calloc(1, sizeof(*reg))))
06953       return -1;
06954 
06955    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
06956       ast_free(reg);
06957       return -1;
06958    }
06959 
06960    ast_copy_string(reg->username, username, sizeof(reg->username));
06961 
06962    if (secret)
06963       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06964 
06965    reg->expire = -1;
06966    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06967    reg->addr.sin_family = AF_INET;
06968    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06969 
06970    AST_LIST_LOCK(&registrations);
06971    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06972    AST_LIST_UNLOCK(&registrations);
06973    
06974    return 0;
06975 }
06976 
06977 static int iax2_register(const char *value, int lineno)
06978 {
06979    char copy[256];
06980    char *username, *hostname, *secret;
06981    char *porta;
06982    char *stringp=NULL;
06983    
06984    if (!value)
06985       return -1;
06986 
06987    ast_copy_string(copy, value, sizeof(copy));
06988    stringp = copy;
06989    username = strsep(&stringp, "@");
06990    hostname = strsep(&stringp, "@");
06991 
06992    if (!hostname) {
06993       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06994       return -1;
06995    }
06996 
06997    stringp = username;
06998    username = strsep(&stringp, ":");
06999    secret = strsep(&stringp, ":");
07000    stringp = hostname;
07001    hostname = strsep(&stringp, ":");
07002    porta = strsep(&stringp, ":");
07003    
07004    if (porta && !atoi(porta)) {
07005       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07006       return -1;
07007    }
07008 
07009    return iax2_append_register(hostname, username, secret, porta);
07010 }
07011 
07012 
07013 static void register_peer_exten(struct iax2_peer *peer, int onoff)
07014 {
07015    char multi[256];
07016    char *stringp, *ext;
07017    if (!ast_strlen_zero(regcontext)) {
07018       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07019       stringp = multi;
07020       while((ext = strsep(&stringp, "&"))) {
07021          if (onoff) {
07022             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07023                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07024                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07025          } else
07026             ast_context_remove_extension(regcontext, ext, 1, NULL);
07027       }
07028    }
07029 }
07030 static void prune_peers(void);
07031 
07032 static void unlink_peer(struct iax2_peer *peer)
07033 {
07034    if (peer->expire > -1) {
07035       if (!ast_sched_del(sched, peer->expire)) {
07036          peer->expire = -1;
07037          peer_unref(peer);
07038       }
07039    }
07040 
07041    if (peer->pokeexpire > -1) {
07042       if (!ast_sched_del(sched, peer->pokeexpire)) {
07043          peer->pokeexpire = -1;
07044          peer_unref(peer);
07045       }
07046    }
07047 
07048    ao2_unlink(peers, peer);
07049 }
07050 
07051 static void __expire_registry(const void *data)
07052 {
07053    struct iax2_peer *peer = (struct iax2_peer *) data;
07054 
07055    if (!peer)
07056       return;
07057 
07058    peer->expire = -1;
07059 
07060    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
07061    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07062       realtime_update_peer(peer->name, &peer->addr, 0);
07063    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07064    /* Reset the address */
07065    memset(&peer->addr, 0, sizeof(peer->addr));
07066    /* Reset expiry value */
07067    peer->expiry = min_reg_expire;
07068    if (!ast_test_flag(peer, IAX_TEMPONLY))
07069       ast_db_del("IAX/Registry", peer->name);
07070    register_peer_exten(peer, 0);
07071    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
07072    if (iax2_regfunk)
07073       iax2_regfunk(peer->name, 0);
07074 
07075    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07076       unlink_peer(peer);
07077 
07078    peer_unref(peer);
07079 }
07080 
07081 static int expire_registry(const void *data)
07082 {
07083 #ifdef SCHED_MULTITHREADED
07084    if (schedule_action(__expire_registry, data))
07085 #endif      
07086       __expire_registry(data);
07087    return 0;
07088 }
07089 
07090 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
07091 
07092 static void reg_source_db(struct iax2_peer *p)
07093 {
07094    char data[80];
07095    struct in_addr in;
07096    char *c, *d;
07097    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07098       c = strchr(data, ':');
07099       if (c) {
07100          *c = '\0';
07101          c++;
07102          if (inet_aton(data, &in)) {
07103             d = strchr(c, ':');
07104             if (d) {
07105                *d = '\0';
07106                d++;
07107                ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
07108                   ast_inet_ntoa(in), atoi(c), atoi(d));
07109                iax2_poke_peer(p, 0);
07110                p->expiry = atoi(d);
07111                memset(&p->addr, 0, sizeof(p->addr));
07112                p->addr.sin_family = AF_INET;
07113                p->addr.sin_addr = in;
07114                p->addr.sin_port = htons(atoi(c));
07115                if (p->expire > -1) {
07116                   if (!ast_sched_del(sched, p->expire)) {
07117                      p->expire = -1;
07118                      peer_unref(p);
07119                   }
07120                }
07121                ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
07122                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07123                if (p->expire == -1)
07124                   peer_unref(p);
07125                if (iax2_regfunk)
07126                   iax2_regfunk(p->name, 1);
07127                register_peer_exten(p, 1);
07128             }              
07129                
07130          }
07131       }
07132    }
07133 }
07134 
07135 /*!
07136  * \pre iaxsl[callno] is locked
07137  *
07138  * \note Since this function calls send_command_final(), the pvt struct for
07139  *       the given call number may disappear while executing this function.
07140  */
07141 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
07142 {
07143    /* Called from IAX thread only, with proper iaxsl lock */
07144    struct iax_ie_data ied;
07145    struct iax2_peer *p;
07146    int msgcount;
07147    char data[80];
07148    int version;
07149    const char *peer_name;
07150    int res = -1;
07151 
07152    memset(&ied, 0, sizeof(ied));
07153 
07154    peer_name = ast_strdupa(iaxs[callno]->peer);
07155 
07156    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
07157    ast_mutex_unlock(&iaxsl[callno]);
07158    if (!(p = find_peer(peer_name, 1))) {
07159       ast_mutex_lock(&iaxsl[callno]);
07160       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07161       return -1;
07162    }
07163    ast_mutex_lock(&iaxsl[callno]);
07164    if (!iaxs[callno])
07165       goto return_unref;
07166 
07167    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07168       if (sin->sin_addr.s_addr) {
07169          time_t nowtime;
07170          time(&nowtime);
07171          realtime_update_peer(peer_name, sin, nowtime);
07172       } else {
07173          realtime_update_peer(peer_name, sin, 0);
07174       }
07175    }
07176    if (inaddrcmp(&p->addr, sin)) {
07177       if (iax2_regfunk)
07178          iax2_regfunk(p->name, 1);
07179       /* Stash the IP address from which they registered */
07180       memcpy(&p->addr, sin, sizeof(p->addr));
07181       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07182       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07183          ast_db_put("IAX/Registry", p->name, data);
07184          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
07185                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07186          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07187          register_peer_exten(p, 1);
07188          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
07189       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07190          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
07191                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07192          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07193          register_peer_exten(p, 0);
07194          ast_db_del("IAX/Registry", p->name);
07195          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
07196       }
07197       /* Update the host */
07198       /* Verify that the host is really there */
07199       iax2_poke_peer(p, callno);
07200    }     
07201 
07202    /* Make sure our call still exists, an INVAL at the right point may make it go away */
07203    if (!iaxs[callno]) {
07204       res = -1;
07205       goto return_unref;
07206    }
07207 
07208    /* Store socket fd */
07209    p->sockfd = fd;
07210    /* Setup the expiry */
07211    if (p->expire > -1) {
07212       if (!ast_sched_del(sched, p->expire)) {
07213          p->expire = -1;
07214          peer_unref(p);
07215       }
07216    }
07217    /* treat an unspecified refresh interval as the minimum */
07218    if (!refresh)
07219       refresh = min_reg_expire;
07220    if (refresh > max_reg_expire) {
07221       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07222          p->name, max_reg_expire, refresh);
07223       p->expiry = max_reg_expire;
07224    } else if (refresh < min_reg_expire) {
07225       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07226          p->name, min_reg_expire, refresh);
07227       p->expiry = min_reg_expire;
07228    } else {
07229       p->expiry = refresh;
07230    }
07231    if (p->expiry && sin->sin_addr.s_addr) {
07232       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07233       if (p->expire == -1)
07234          peer_unref(p);
07235    }
07236    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07237    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07238    if (sin->sin_addr.s_addr) {
07239       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07240       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07241       if (!ast_strlen_zero(p->mailbox)) {
07242          struct ast_event *event;
07243          int new, old;
07244          char *mailbox, *context;
07245 
07246          context = mailbox = ast_strdupa(p->mailbox);
07247          strsep(&context, "@");
07248          if (ast_strlen_zero(context))
07249             context = "default";
07250 
07251          event = ast_event_get_cached(AST_EVENT_MWI,
07252             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
07253             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
07254             AST_EVENT_IE_END);
07255          if (event) {
07256             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07257             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
07258             ast_event_destroy(event);
07259          } else { /* Fall back on checking the mailbox directly */
07260             ast_app_inboxcount(p->mailbox, &new, &old);
07261          }
07262 
07263          if (new > 255) {
07264             new = 255;
07265          }
07266          if (old > 255) {
07267             old = 255;
07268          }
07269          msgcount = (old << 8) | new;
07270 
07271          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07272       }
07273       if (ast_test_flag(p, IAX_HASCALLERID)) {
07274          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07275          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07276       }
07277    }
07278    version = iax_check_version(devtype);
07279    if (version) 
07280       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07281 
07282    res = 0;
07283 
07284 return_unref:
07285    peer_unref(p);
07286 
07287    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07288 }
07289 
07290 static int registry_authrequest(int callno)
07291 {
07292    struct iax_ie_data ied;
07293    struct iax2_peer *p;
07294    char challenge[10];
07295    const char *peer_name;
07296    int sentauthmethod;
07297 
07298    peer_name = ast_strdupa(iaxs[callno]->peer);
07299 
07300    /* SLD: third call to find_peer in registration */
07301    ast_mutex_unlock(&iaxsl[callno]);
07302    if ((p = find_peer(peer_name, 1))) {
07303       last_authmethod = p->authmethods;
07304    }
07305 
07306    ast_mutex_lock(&iaxsl[callno]);
07307    if (!iaxs[callno])
07308       goto return_unref;
07309 
07310    memset(&ied, 0, sizeof(ied));
07311    /* The selection of which delayed reject is sent may leak information,
07312     * if it sets a static response.  For example, if a host is known to only
07313     * use MD5 authentication, then an RSA response would indicate that the
07314     * peer does not exist, and vice-versa.
07315     * Therefore, we use whatever the last peer used (which may vary over the
07316     * course of a server, which should leak minimal information). */
07317    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07318    if (!p) {
07319       iaxs[callno]->authmethods = sentauthmethod;
07320    }
07321    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07322    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07323       /* Build the challenge */
07324       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07325       ast_string_field_set(iaxs[callno], challenge, challenge);
07326       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07327    }
07328    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07329 
07330 return_unref:
07331    if (p) {
07332       peer_unref(p);
07333    }
07334 
07335    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07336 }
07337 
07338 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
07339 {
07340    struct iax2_registry *reg;
07341    /* Start pessimistic */
07342    struct iax_ie_data ied;
07343    char peer[256] = "";
07344    char challenge[256] = "";
07345    int res;
07346    int authmethods = 0;
07347    if (ies->authmethods)
07348       authmethods = ies->authmethods;
07349    if (ies->username)
07350       ast_copy_string(peer, ies->username, sizeof(peer));
07351    if (ies->challenge)
07352       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07353    memset(&ied, 0, sizeof(ied));
07354    reg = iaxs[callno]->reg;
07355    if (reg) {
07356          if (inaddrcmp(&reg->addr, sin)) {
07357             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07358             return -1;
07359          }
07360          if (ast_strlen_zero(reg->secret)) {
07361             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07362             reg->regstate = REG_STATE_NOAUTH;
07363             return -1;
07364          }
07365          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07366          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07367          if (reg->secret[0] == '[') {
07368             char tmpkey[256];
07369             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07370             tmpkey[strlen(tmpkey) - 1] = '\0';
07371             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07372          } else
07373             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07374          if (!res) {
07375             reg->regstate = REG_STATE_AUTHSENT;
07376             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07377          } else
07378             return -1;
07379          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07380    } else   
07381       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07382    return -1;
07383 }
07384 
07385 static void stop_stuff(int callno)
07386 {
07387    iax2_destroy_helper(iaxs[callno]);
07388 }
07389 
07390 static void __auth_reject(const void *nothing)
07391 {
07392    /* Called from IAX thread only, without iaxs lock */
07393    int callno = (int)(long)(nothing);
07394    struct iax_ie_data ied;
07395    ast_mutex_lock(&iaxsl[callno]);
07396    if (iaxs[callno]) {
07397       memset(&ied, 0, sizeof(ied));
07398       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07399          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07400          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07401       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07402          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07403          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07404       }
07405       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07406    }
07407    ast_mutex_unlock(&iaxsl[callno]);
07408 }
07409 
07410 static int auth_reject(const void *data)
07411 {
07412    int callno = (int)(long)(data);
07413    ast_mutex_lock(&iaxsl[callno]);
07414    if (iaxs[callno])
07415       iaxs[callno]->authid = -1;
07416    ast_mutex_unlock(&iaxsl[callno]);
07417 #ifdef SCHED_MULTITHREADED
07418    if (schedule_action(__auth_reject, data))
07419 #endif      
07420       __auth_reject(data);
07421    return 0;
07422 }
07423 
07424 static int auth_fail(int callno, int failcode)
07425 {
07426    /* Schedule sending the authentication failure in one second, to prevent
07427       guessing */
07428    if (iaxs[callno]) {
07429       iaxs[callno]->authfail = failcode;
07430       if (delayreject) {
07431          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
07432             sched, 1000, auth_reject, (void *)(long)callno);
07433       } else
07434          auth_reject((void *)(long)callno);
07435    }
07436    return 0;
07437 }
07438 
07439 static void __auto_hangup(const void *nothing)
07440 {
07441    /* Called from IAX thread only, without iaxs lock */
07442    int callno = (int)(long)(nothing);
07443    struct iax_ie_data ied;
07444    ast_mutex_lock(&iaxsl[callno]);
07445    if (iaxs[callno]) {
07446       memset(&ied, 0, sizeof(ied));
07447       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07448       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07449       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07450    }
07451    ast_mutex_unlock(&iaxsl[callno]);
07452 }
07453 
07454 static int auto_hangup(const void *data)
07455 {
07456    int callno = (int)(long)(data);
07457    ast_mutex_lock(&iaxsl[callno]);
07458    if (iaxs[callno]) {
07459       iaxs[callno]->autoid = -1;
07460    }
07461    ast_mutex_unlock(&iaxsl[callno]);
07462 #ifdef SCHED_MULTITHREADED
07463    if (schedule_action(__auto_hangup, data))
07464 #endif      
07465       __auto_hangup(data);
07466    return 0;
07467 }
07468 
07469 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
07470 {
07471    struct iax_ie_data ied;
07472    /* Auto-hangup with 30 seconds of inactivity */
07473    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
07474       sched, 30000, auto_hangup, (void *)(long)callno);
07475    memset(&ied, 0, sizeof(ied));
07476    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07477    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07478    dp->flags |= CACHE_FLAG_TRANSMITTED;
07479 }
07480 
07481 static int iax2_vnak(int callno)
07482 {
07483    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07484 }
07485 
07486 static void vnak_retransmit(int callno, int last)
07487 {
07488    struct iax_frame *f;
07489 
07490    AST_LIST_LOCK(&frame_queue);
07491    AST_LIST_TRAVERSE(&frame_queue, f, list) {
07492       /* Send a copy immediately */
07493       if ((f->callno == callno) && iaxs[f->callno] &&
07494          ((unsigned char ) (f->oseqno - last) < 128) &&
07495          (f->retries >= 0)) {
07496          send_packet(f);
07497       }
07498    }
07499    AST_LIST_UNLOCK(&frame_queue);
07500 }
07501 
07502 static void __iax2_poke_peer_s(const void *data)
07503 {
07504    struct iax2_peer *peer = (struct iax2_peer *)data;
07505    iax2_poke_peer(peer, 0);
07506    peer_unref(peer);
07507 }
07508 
07509 static int iax2_poke_peer_s(const void *data)
07510 {
07511    struct iax2_peer *peer = (struct iax2_peer *)data;
07512    peer->pokeexpire = -1;
07513 #ifdef SCHED_MULTITHREADED
07514    if (schedule_action(__iax2_poke_peer_s, data))
07515 #endif      
07516       __iax2_poke_peer_s(data);
07517    return 0;
07518 }
07519 
07520 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
07521 {
07522    int res = 0;
07523    struct iax_frame *fr;
07524    struct ast_iax2_meta_hdr *meta;
07525    struct ast_iax2_meta_trunk_hdr *mth;
07526    int calls = 0;
07527    
07528    /* Point to frame */
07529    fr = (struct iax_frame *)tpeer->trunkdata;
07530    /* Point to meta data */
07531    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07532    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07533    if (tpeer->trunkdatalen) {
07534       /* We're actually sending a frame, so fill the meta trunk header and meta header */
07535       meta->zeros = 0;
07536       meta->metacmd = IAX_META_TRUNK;
07537       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07538          meta->cmddata = IAX_META_TRUNK_MINI;
07539       else
07540          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07541       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07542       /* And the rest of the ast_iax2 header */
07543       fr->direction = DIRECTION_OUTGRESS;
07544       fr->retrans = -1;
07545       fr->transfer = 0;
07546       /* Any appropriate call will do */
07547       fr->data = fr->afdata;
07548       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07549       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07550       calls = tpeer->calls;
07551 #if 0
07552       ast_debug(1, "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));
07553 #endif      
07554       /* Reset transmit trunk side data */
07555       tpeer->trunkdatalen = 0;
07556       tpeer->calls = 0;
07557    }
07558    if (res < 0)
07559       return res;
07560    return calls;
07561 }
07562 
07563 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
07564 {
07565    /* Drop when trunk is about 5 seconds idle */
07566    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
07567       return 1;
07568    return 0;
07569 }
07570 
07571 static int timing_read(int *id, int fd, short events, void *cbdata)
07572 {
07573    int res, processed = 0, totalcalls = 0;
07574    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
07575    struct timeval now = ast_tvnow();
07576 
07577    if (iaxtrunkdebug)
07578       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
07579 
07580    if (timer) { 
07581       ast_timer_ack(timer, 1);
07582    }
07583 
07584    /* For each peer that supports trunking... */
07585    AST_LIST_LOCK(&tpeers);
07586    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
07587       processed++;
07588       res = 0;
07589       ast_mutex_lock(&tpeer->lock);
07590       /* We can drop a single tpeer per pass.  That makes all this logic
07591          substantially easier */
07592       if (!drop && iax2_trunk_expired(tpeer, &now)) {
07593          /* Take it out of the list, but don't free it yet, because it
07594             could be in use */
07595          AST_LIST_REMOVE_CURRENT(list);
07596          drop = tpeer;
07597       } else {
07598          res = send_trunk(tpeer, &now);
07599          trunk_timed++; 
07600          if (iaxtrunkdebug)
07601             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);
07602       }     
07603       totalcalls += res;   
07604       res = 0;
07605       ast_mutex_unlock(&tpeer->lock);
07606    }
07607    AST_LIST_TRAVERSE_SAFE_END;
07608    AST_LIST_UNLOCK(&tpeers);
07609 
07610    if (drop) {
07611       ast_mutex_lock(&drop->lock);
07612       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
07613          because by the time they could get tpeerlock, we've already grabbed it */
07614       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07615       if (drop->trunkdata) {
07616          ast_free(drop->trunkdata);
07617          drop->trunkdata = NULL;
07618       }
07619       ast_mutex_unlock(&drop->lock);
07620       ast_mutex_destroy(&drop->lock);
07621       ast_free(drop);
07622       
07623    }
07624 
07625    if (iaxtrunkdebug)
07626       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07627    iaxtrunkdebug = 0;
07628 
07629    return 1;
07630 }
07631 
07632 struct dpreq_data {
07633    int callno;
07634    char context[AST_MAX_EXTENSION];
07635    char callednum[AST_MAX_EXTENSION];
07636    char *callerid;
07637 };
07638 
07639 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
07640 {
07641    unsigned short dpstatus = 0;
07642    struct iax_ie_data ied1;
07643    int mm;
07644 
07645    memset(&ied1, 0, sizeof(ied1));
07646    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07647    /* Must be started */
07648    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07649       dpstatus = IAX_DPSTATUS_EXISTS;
07650    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07651       dpstatus = IAX_DPSTATUS_CANEXIST;
07652    } else {
07653       dpstatus = IAX_DPSTATUS_NONEXISTENT;
07654    }
07655    if (ast_ignore_pattern(context, callednum))
07656       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07657    if (mm)
07658       dpstatus |= IAX_DPSTATUS_MATCHMORE;
07659    if (!skiplock)
07660       ast_mutex_lock(&iaxsl[callno]);
07661    if (iaxs[callno]) {
07662       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07663       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07664       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07665       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07666    }
07667    if (!skiplock)
07668       ast_mutex_unlock(&iaxsl[callno]);
07669 }
07670 
07671 static void *dp_lookup_thread(void *data)
07672 {
07673    /* Look up for dpreq */
07674    struct dpreq_data *dpr = data;
07675    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07676    if (dpr->callerid)
07677       ast_free(dpr->callerid);
07678    ast_free(dpr);
07679    return NULL;
07680 }
07681 
07682 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07683 {
07684    pthread_t newthread;
07685    struct dpreq_data *dpr;
07686    
07687    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07688       return;
07689 
07690    dpr->callno = callno;
07691    ast_copy_string(dpr->context, context, sizeof(dpr->context));
07692    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07693    if (callerid)
07694       dpr->callerid = ast_strdup(callerid);
07695    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
07696       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07697    }
07698 }
07699 
07700 struct iax_dual {
07701    struct ast_channel *chan1;
07702    struct ast_channel *chan2;
07703 };
07704 
07705 static void *iax_park_thread(void *stuff)
07706 {
07707    struct ast_channel *chan1, *chan2;
07708    struct iax_dual *d;
07709    struct ast_frame *f;
07710    int ext;
07711    int res;
07712    d = stuff;
07713    chan1 = d->chan1;
07714    chan2 = d->chan2;
07715    ast_free(d);
07716    f = ast_read(chan1);
07717    if (f)
07718       ast_frfree(f);
07719    res = ast_park_call(chan1, chan2, 0, &ext);
07720    ast_hangup(chan2);
07721    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07722    return NULL;
07723 }
07724 
07725 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07726 {
07727    struct iax_dual *d;
07728    struct ast_channel *chan1m, *chan2m;
07729    pthread_t th;
07730    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07731    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07732    if (chan2m && chan1m) {
07733       /* Make formats okay */
07734       chan1m->readformat = chan1->readformat;
07735       chan1m->writeformat = chan1->writeformat;
07736       ast_channel_masquerade(chan1m, chan1);
07737       /* Setup the extensions and such */
07738       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
07739       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
07740       chan1m->priority = chan1->priority;
07741       
07742       /* We make a clone of the peer channel too, so we can play
07743          back the announcement */
07744       /* Make formats okay */
07745       chan2m->readformat = chan2->readformat;
07746       chan2m->writeformat = chan2->writeformat;
07747       ast_channel_masquerade(chan2m, chan2);
07748       /* Setup the extensions and such */
07749       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
07750       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
07751       chan2m->priority = chan2->priority;
07752       if (ast_do_masquerade(chan2m)) {
07753          ast_log(LOG_WARNING, "Masquerade failed :(\n");
07754          ast_hangup(chan2m);
07755          return -1;
07756       }
07757    } else {
07758       if (chan1m)
07759          ast_hangup(chan1m);
07760       if (chan2m)
07761          ast_hangup(chan2m);
07762       return -1;
07763    }
07764    if ((d = ast_calloc(1, sizeof(*d)))) {
07765       d->chan1 = chan1m;
07766       d->chan2 = chan2m;
07767       if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
07768          return 0;
07769       }
07770       ast_free(d);
07771    }
07772    return -1;
07773 }
07774 
07775 
07776 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
07777 
07778 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
07779 {
07780    unsigned int ourver;
07781    char rsi[80];
07782    snprintf(rsi, sizeof(rsi), "si-%s", si);
07783    if (iax_provision_version(&ourver, rsi, 1))
07784       return 0;
07785    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
07786    if (ourver != ver) 
07787       iax2_provision(sin, sockfd, NULL, rsi, 1);
07788    return 0;
07789 }
07790 
07791 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
07792 {
07793    jb_info stats;
07794    jb_getinfo(pvt->jb, &stats);
07795    
07796    memset(iep, 0, sizeof(*iep));
07797 
07798    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
07799    if(stats.frames_in == 0) stats.frames_in = 1;
07800    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
07801    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
07802    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
07803    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
07804    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07805 }
07806 
07807 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
07808 {
07809    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07810    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07811    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07812    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07813    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07814    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07815    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07816 }
07817 
07818 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies) 
07819 {
07820    int i;
07821    unsigned int length, offset = 0;
07822    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
07823 
07824    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
07825       length = ies->ospblocklength[i];
07826       if (length != 0) {
07827          if (length > IAX_MAX_OSPBLOCK_SIZE) {
07828             /* OSP token block length wrong, clear buffer */
07829             offset = 0;
07830             break;
07831          } else {
07832             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
07833             offset += length;
07834          }
07835       } else {
07836          break;
07837       }
07838    }
07839    *(full_osptoken + offset) = '\0';
07840    if (strlen(full_osptoken) != offset) {
07841       /* OSP token length wrong, clear buffer */
07842       *full_osptoken = '\0';
07843    }
07844 
07845    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
07846 }
07847 
07848 static void log_jitterstats(unsigned short callno)
07849 {
07850    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
07851    jb_info jbinfo;
07852 
07853    ast_mutex_lock(&iaxsl[callno]);
07854    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
07855       if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
07856          jb_getinfo(iaxs[callno]->jb, &jbinfo);
07857          localjitter = jbinfo.jitter;
07858          localdelay = jbinfo.current - jbinfo.min;
07859          locallost = jbinfo.frames_lost;
07860          locallosspct = jbinfo.losspct/1000;
07861          localdropped = jbinfo.frames_dropped;
07862          localooo = jbinfo.frames_ooo;
07863          localpackets = jbinfo.frames_in;
07864       }
07865       ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
07866          iaxs[callno]->owner->name,
07867          iaxs[callno]->pingtime,
07868          localjitter,
07869          localdelay,
07870          locallost,
07871          locallosspct,
07872          localdropped,
07873          localooo,
07874          localpackets,
07875          iaxs[callno]->remote_rr.jitter,
07876          iaxs[callno]->remote_rr.delay,
07877          iaxs[callno]->remote_rr.losscnt,
07878          iaxs[callno]->remote_rr.losspct/1000,
07879          iaxs[callno]->remote_rr.dropped,
07880          iaxs[callno]->remote_rr.ooo,
07881          iaxs[callno]->remote_rr.packets);
07882       manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
07883          iaxs[callno]->owner->name,
07884          iaxs[callno]->pingtime,
07885          localjitter,
07886          localdelay,
07887          locallost,
07888          locallosspct,
07889          localdropped,
07890          localooo,
07891          localpackets,
07892          iaxs[callno]->remote_rr.jitter,
07893          iaxs[callno]->remote_rr.delay,
07894          iaxs[callno]->remote_rr.losscnt,
07895          iaxs[callno]->remote_rr.losspct/1000,
07896          iaxs[callno]->remote_rr.dropped,
07897          iaxs[callno]->remote_rr.ooo,
07898          iaxs[callno]->remote_rr.packets);
07899    }
07900    ast_mutex_unlock(&iaxsl[callno]);
07901 }
07902 
07903 static int socket_process(struct iax2_thread *thread);
07904 
07905 /*!
07906  * \brief Handle any deferred full frames for this thread
07907  */
07908 static void handle_deferred_full_frames(struct iax2_thread *thread)
07909 {
07910    struct iax2_pkt_buf *pkt_buf;
07911 
07912    ast_mutex_lock(&thread->lock);
07913 
07914    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07915       ast_mutex_unlock(&thread->lock);
07916 
07917       thread->buf = pkt_buf->buf;
07918       thread->buf_len = pkt_buf->len;
07919       thread->buf_size = pkt_buf->len + 1;
07920       
07921       socket_process(thread);
07922 
07923       thread->buf = NULL;
07924       ast_free(pkt_buf);
07925 
07926       ast_mutex_lock(&thread->lock);
07927    }
07928 
07929    ast_mutex_unlock(&thread->lock);
07930 }
07931 
07932 /*!
07933  * \brief Queue the last read full frame for processing by a certain thread
07934  *
07935  * If there are already any full frames queued, they are sorted
07936  * by sequence number.
07937  */
07938 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07939 {
07940    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07941    struct ast_iax2_full_hdr *fh, *cur_fh;
07942 
07943    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07944       return;
07945 
07946    pkt_buf->len = from_here->buf_len;
07947    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07948 
07949    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07950    ast_mutex_lock(&to_here->lock);
07951    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07952       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07953       if (fh->oseqno < cur_fh->oseqno) {
07954          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
07955          break;
07956       }
07957    }
07958    AST_LIST_TRAVERSE_SAFE_END
07959 
07960    if (!cur_pkt_buf)
07961       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07962    
07963    ast_mutex_unlock(&to_here->lock);
07964 }
07965 
07966 static int socket_read(int *id, int fd, short events, void *cbdata)
07967 {
07968    struct iax2_thread *thread;
07969    socklen_t len;
07970    time_t t;
07971    static time_t last_errtime = 0;
07972    struct ast_iax2_full_hdr *fh;
07973 
07974    if (!(thread = find_idle_thread())) {
07975       time(&t);
07976       if (t != last_errtime)
07977          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
07978       last_errtime = t;
07979       usleep(1);
07980       return 1;
07981    }
07982 
07983    len = sizeof(thread->iosin);
07984    thread->iofd = fd;
07985    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07986    thread->buf_size = sizeof(thread->readbuf);
07987    thread->buf = thread->readbuf;
07988    if (thread->buf_len < 0) {
07989       if (errno != ECONNREFUSED && errno != EAGAIN)
07990          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07991       handle_error();
07992       thread->iostate = IAX_IOSTATE_IDLE;
07993       signal_condition(&thread->lock, &thread->cond);
07994       return 1;
07995    }
07996    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
07997       thread->iostate = IAX_IOSTATE_IDLE;
07998       signal_condition(&thread->lock, &thread->cond);
07999       return 1;
08000    }
08001    
08002    /* Determine if this frame is a full frame; if so, and any thread is currently
08003       processing a full frame for the same callno from this peer, then drop this
08004       frame (and the peer will retransmit it) */
08005    fh = (struct ast_iax2_full_hdr *) thread->buf;
08006    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08007       struct iax2_thread *cur = NULL;
08008       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08009       
08010       AST_LIST_LOCK(&active_list);
08011       AST_LIST_TRAVERSE(&active_list, cur, list) {
08012          if ((cur->ffinfo.callno == callno) &&
08013              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08014             break;
08015       }
08016       if (cur) {
08017          /* we found another thread processing a full frame for this call,
08018             so queue it up for processing later. */
08019          defer_full_frame(thread, cur);
08020          AST_LIST_UNLOCK(&active_list);
08021          thread->iostate = IAX_IOSTATE_IDLE;
08022          signal_condition(&thread->lock, &thread->cond);
08023          return 1;
08024       } else {
08025          /* this thread is going to process this frame, so mark it */
08026          thread->ffinfo.callno = callno;
08027          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08028          thread->ffinfo.type = fh->type;
08029          thread->ffinfo.csub = fh->csub;
08030       }
08031       AST_LIST_UNLOCK(&active_list);
08032    }
08033    
08034    /* Mark as ready and send on its way */
08035    thread->iostate = IAX_IOSTATE_READY;
08036 #ifdef DEBUG_SCHED_MULTITHREAD
08037    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08038 #endif
08039    signal_condition(&thread->lock, &thread->cond);
08040 
08041    return 1;
08042 }
08043 
08044 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
08045    struct iax_frame *fr)
08046 {
08047    unsigned char metatype;
08048    struct ast_iax2_meta_trunk_mini *mtm;
08049    struct ast_iax2_meta_trunk_hdr *mth;
08050    struct ast_iax2_meta_trunk_entry *mte;
08051    struct iax2_trunk_peer *tpeer;
08052    unsigned int ts;
08053    void *ptr;
08054    struct timeval rxtrunktime;
08055    struct ast_frame f = { 0, };
08056 
08057    if (packet_len < sizeof(*meta)) {
08058       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
08059          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08060       return 1;
08061    }
08062 
08063    if (meta->metacmd != IAX_META_TRUNK)
08064       return 1;
08065 
08066    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
08067       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
08068          (int) (sizeof(*meta) + sizeof(*mth)));
08069       return 1;
08070    }
08071    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08072    ts = ntohl(mth->ts);
08073    metatype = meta->cmddata;
08074    packet_len -= (sizeof(*meta) + sizeof(*mth));
08075    ptr = mth->data;
08076    tpeer = find_tpeer(sin, sockfd);
08077    if (!tpeer) {
08078       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
08079          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08080       return 1;
08081    }
08082    tpeer->trunkact = ast_tvnow();
08083    if (!ts || ast_tvzero(tpeer->rxtrunktime))
08084       tpeer->rxtrunktime = tpeer->trunkact;
08085    rxtrunktime = tpeer->rxtrunktime;
08086    ast_mutex_unlock(&tpeer->lock);
08087    while (packet_len >= sizeof(*mte)) {
08088       /* Process channels */
08089       unsigned short callno, trunked_ts, len;
08090 
08091       if (metatype == IAX_META_TRUNK_MINI) {
08092          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
08093          ptr += sizeof(*mtm);
08094          packet_len -= sizeof(*mtm);
08095          len = ntohs(mtm->len);
08096          callno = ntohs(mtm->mini.callno);
08097          trunked_ts = ntohs(mtm->mini.ts);
08098       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08099          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08100          ptr += sizeof(*mte);
08101          packet_len -= sizeof(*mte);
08102          len = ntohs(mte->len);
08103          callno = ntohs(mte->callno);
08104          trunked_ts = 0;
08105       } else {
08106          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08107          break;
08108       }
08109       /* Stop if we don't have enough data */
08110       if (len > packet_len)
08111          break;
08112       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
08113       if (!fr->callno)
08114          continue;
08115 
08116       /* If it's a valid call, deliver the contents.  If not, we
08117          drop it, since we don't have a scallno to use for an INVAL */
08118       /* Process as a mini frame */
08119       memset(&f, 0, sizeof(f));
08120       f.frametype = AST_FRAME_VOICE;
08121       if (!iaxs[fr->callno]) {
08122          /* drop it */
08123       } else if (iaxs[fr->callno]->voiceformat == 0) {
08124          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08125          iax2_vnak(fr->callno);
08126       } else {
08127          f.subclass = iaxs[fr->callno]->voiceformat;
08128          f.datalen = len;
08129          if (f.datalen >= 0) {
08130             if (f.datalen)
08131                f.data.ptr = ptr;
08132             else
08133                f.data.ptr = NULL;
08134             if (trunked_ts)
08135                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08136             else
08137                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08138             /* Don't pass any packets until we're started */
08139             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08140                struct iax_frame *duped_fr;
08141 
08142                /* Common things */
08143                f.src = "IAX2";
08144                f.mallocd = 0;
08145                f.offset = 0;
08146                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
08147                   f.samples = ast_codec_get_samples(&f);
08148                else
08149                   f.samples = 0;
08150                fr->outoforder = 0;
08151                iax_frame_wrap(fr, &f);
08152                duped_fr = iaxfrdup2(fr);
08153                if (duped_fr)
08154                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
08155                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
08156                   iaxs[fr->callno]->last = fr->ts;
08157             }
08158          } else {
08159             ast_log(LOG_WARNING, "Datalen < 0?\n");
08160          }
08161       }
08162       ast_mutex_unlock(&iaxsl[fr->callno]);
08163       ptr += len;
08164       packet_len -= len;
08165    }
08166 
08167    return 1;
08168 }
08169 
08170 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
08171 {
08172    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08173    AST_LIST_HEAD(, ast_var_t) *varlist;
08174    struct ast_var_t *var;
08175 
08176    if (!variablestore) {
08177       *buf = '\0';
08178       return 0;
08179    }
08180    varlist = variablestore->data;
08181 
08182    AST_LIST_LOCK(varlist);
08183    AST_LIST_TRAVERSE(varlist, var, entries) {
08184       if (strcmp(var->name, data) == 0) {
08185          ast_copy_string(buf, var->value, len);
08186          break;
08187       }
08188    }
08189    AST_LIST_UNLOCK(varlist);
08190    return 0;
08191 }
08192 
08193 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
08194 {
08195    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08196    AST_LIST_HEAD(, ast_var_t) *varlist;
08197    struct ast_var_t *var;
08198 
08199    if (!variablestore) {
08200       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08201       if (!variablestore) {
08202          ast_log(LOG_ERROR, "Memory allocation error\n");
08203          return -1;
08204       }
08205       varlist = ast_calloc(1, sizeof(*varlist));
08206       if (!varlist) {
08207          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08208          return -1;
08209       }
08210 
08211       AST_LIST_HEAD_INIT(varlist);
08212       variablestore->data = varlist;
08213       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08214       ast_channel_datastore_add(chan, variablestore);
08215    } else
08216       varlist = variablestore->data;
08217 
08218    AST_LIST_LOCK(varlist);
08219    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
08220       if (strcmp(var->name, data) == 0) {
08221          AST_LIST_REMOVE_CURRENT(entries);
08222          ast_var_delete(var);
08223          break;
08224       }
08225    }
08226    AST_LIST_TRAVERSE_SAFE_END;
08227    var = ast_var_assign(data, value);
08228    if (var)
08229       AST_LIST_INSERT_TAIL(varlist, var, entries);
08230    else
08231       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08232    AST_LIST_UNLOCK(varlist);
08233    return 0;
08234 }
08235 
08236 static struct ast_custom_function iaxvar_function = {
08237    .name = "IAXVAR",
08238    .synopsis = "Sets or retrieves a remote variable",
08239    .syntax = "IAXVAR(<varname>)",
08240    .read = acf_iaxvar_read,
08241    .write = acf_iaxvar_write,
08242 };
08243 
08244 static int socket_process(struct iax2_thread *thread)
08245 {
08246    struct sockaddr_in sin;
08247    int res;
08248    int updatehistory=1;
08249    int new = NEW_PREVENT;
08250    int dcallno = 0;
08251    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08252    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08253    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08254    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08255    struct iax_frame *fr;
08256    struct iax_frame *cur;
08257    struct ast_frame f = { 0, };
08258    struct ast_channel *c = NULL;
08259    struct iax2_dpcache *dp;
08260    struct iax2_peer *peer;
08261    struct iax_ies ies;
08262    struct iax_ie_data ied0, ied1;
08263    int format;
08264    int fd;
08265    int exists;
08266    int minivid = 0;
08267    char empty[32]="";      /* Safety measure */
08268    struct iax_frame *duped_fr;
08269    char host_pref_buf[128];
08270    char caller_pref_buf[128];
08271    struct ast_codec_pref pref;
08272    char *using_prefs = "mine";
08273 
08274    /* allocate an iax_frame with 4096 bytes of data buffer */
08275    fr = alloca(sizeof(*fr) + 4096);
08276    memset(fr, 0, sizeof(*fr));
08277    fr->afdatalen = 4096; /* From alloca() above */
08278 
08279    /* Copy frequently used parameters to the stack */
08280    res = thread->buf_len;
08281    fd = thread->iofd;
08282    memcpy(&sin, &thread->iosin, sizeof(sin));
08283 
08284    if (res < sizeof(*mh)) {
08285       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
08286       return 1;
08287    }
08288    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08289       if (res < sizeof(*vh)) {
08290          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));
08291          return 1;
08292       }
08293 
08294       /* This is a video frame, get call number */
08295       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08296       minivid = 1;
08297    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
08298       return socket_process_meta(res, meta, &sin, fd, fr);
08299 
08300 #ifdef DEBUG_SUPPORT
08301    if (res >= sizeof(*fh))
08302       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08303 #endif
08304    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08305       if (res < sizeof(*fh)) {
08306          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));
08307          return 1;
08308       }
08309 
08310       /* Get the destination call number */
08311       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08312       /* Retrieve the type and subclass */
08313       f.frametype = fh->type;
08314       if (f.frametype == AST_FRAME_VIDEO) {
08315          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08316       } else {
08317          f.subclass = uncompress_subclass(fh->csub);
08318       }
08319 
08320       /* Deal with POKE/PONG without allocating a callno */
08321       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08322          /* Reply back with a PONG, but don't care about the result. */
08323          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1);
08324          return 1;
08325       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08326          /* Ignore */
08327          return 1;
08328       }
08329 
08330       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
08331                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
08332                          (f.subclass == IAX_COMMAND_REGREL)))
08333          new = NEW_ALLOW;
08334    } else {
08335       /* Don't know anything about it yet */
08336       f.frametype = AST_FRAME_NULL;
08337       f.subclass = 0;
08338    }
08339 
08340    if (!fr->callno) {
08341       int check_dcallno = 0;
08342 
08343       /*
08344        * We enforce accurate destination call numbers for all full frames except
08345        * LAGRQ and PING commands.  This is because older versions of Asterisk
08346        * schedule these commands to get sent very quickly, and they will sometimes
08347        * be sent before they receive the first frame from the other side.  When
08348        * that happens, it doesn't contain the destination call number.  However,
08349        * not checking it for these frames is safe.
08350        * 
08351        * Discussed in the following thread:
08352        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
08353        */
08354 
08355       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08356          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08357       }
08358 
08359       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
08360    }
08361 
08362    if (fr->callno > 0)
08363       ast_mutex_lock(&iaxsl[fr->callno]);
08364 
08365    if (!fr->callno || !iaxs[fr->callno]) {
08366       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
08367          frame, reply with an inval */
08368       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08369          /* We can only raw hangup control frames */
08370          if (((f.subclass != IAX_COMMAND_INVAL) &&
08371              (f.subclass != IAX_COMMAND_TXCNT) &&
08372              (f.subclass != IAX_COMMAND_TXACC) &&
08373              (f.subclass != IAX_COMMAND_FWDOWNL))||
08374              (f.frametype != AST_FRAME_IAX))
08375             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08376             fd);
08377       }
08378       if (fr->callno > 0) 
08379          ast_mutex_unlock(&iaxsl[fr->callno]);
08380       return 1;
08381    }
08382    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08383       if (decrypt_frame(fr->callno, fh, &f, &res)) {
08384          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08385          ast_mutex_unlock(&iaxsl[fr->callno]);
08386          return 1;
08387       }
08388 #ifdef DEBUG_SUPPORT
08389       else
08390          iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08391 #endif
08392    }
08393 
08394    /* count this frame */
08395    iaxs[fr->callno]->frames_received++;
08396 
08397    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08398       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
08399       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
08400       unsigned short new_peercallno;
08401       
08402       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08403       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08404          if (iaxs[fr->callno]->peercallno) {
08405             remove_by_peercallno(iaxs[fr->callno]);
08406          }
08407          iaxs[fr->callno]->peercallno = new_peercallno;
08408          store_by_peercallno(iaxs[fr->callno]);
08409       }
08410    }
08411    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08412       if (iaxdebug)
08413          ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08414       /* Check if it's out of order (and not an ACK or INVAL) */
08415       fr->oseqno = fh->oseqno;
08416       fr->iseqno = fh->iseqno;
08417       fr->ts = ntohl(fh->ts);
08418 #ifdef IAXTESTS
08419       if (test_resync) {
08420          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08421          fr->ts += test_resync;
08422       }
08423 #endif /* IAXTESTS */
08424 #if 0
08425       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08426            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08427                         (f.subclass == IAX_COMMAND_NEW ||
08428                          f.subclass == IAX_COMMAND_AUTHREQ ||
08429                          f.subclass == IAX_COMMAND_ACCEPT ||
08430                          f.subclass == IAX_COMMAND_REJECT))      ) )
08431 #endif
08432       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08433          updatehistory = 0;
08434       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08435          (iaxs[fr->callno]->iseqno ||
08436             ((f.subclass != IAX_COMMAND_TXCNT) &&
08437             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
08438             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
08439             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
08440             (f.subclass != IAX_COMMAND_TXACC)) ||
08441             (f.frametype != AST_FRAME_IAX))) {
08442          if (
08443           ((f.subclass != IAX_COMMAND_ACK) &&
08444            (f.subclass != IAX_COMMAND_INVAL) &&
08445            (f.subclass != IAX_COMMAND_TXCNT) &&
08446            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
08447            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
08448            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
08449            (f.subclass != IAX_COMMAND_TXACC) &&
08450            (f.subclass != IAX_COMMAND_VNAK)) ||
08451            (f.frametype != AST_FRAME_IAX)) {
08452             /* If it's not an ACK packet, it's out of order. */
08453             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
08454                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08455             /* Check to see if we need to request retransmission,
08456              * and take sequence number wraparound into account */
08457             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08458                /* If we've already seen it, ack it XXX There's a border condition here XXX */
08459                if ((f.frametype != AST_FRAME_IAX) || 
08460                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08461                   ast_debug(1, "Acking anyway\n");
08462                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
08463                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
08464                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08465                }
08466             } else {
08467                /* Send a VNAK requesting retransmission */
08468                iax2_vnak(fr->callno);
08469             }
08470             ast_mutex_unlock(&iaxsl[fr->callno]);
08471             return 1;
08472          }
08473       } else {
08474          /* Increment unless it's an ACK or VNAK */
08475          if (((f.subclass != IAX_COMMAND_ACK) &&
08476              (f.subclass != IAX_COMMAND_INVAL) &&
08477              (f.subclass != IAX_COMMAND_TXCNT) &&
08478              (f.subclass != IAX_COMMAND_TXACC) &&
08479             (f.subclass != IAX_COMMAND_VNAK)) ||
08480              (f.frametype != AST_FRAME_IAX))
08481             iaxs[fr->callno]->iseqno++;
08482       }
08483       /* A full frame */
08484       if (res < sizeof(*fh)) {
08485          ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*fh));
08486          ast_mutex_unlock(&iaxsl[fr->callno]);
08487          return 1;
08488       }
08489       /* Ensure text frames are NULL-terminated */
08490       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08491          if (res < thread->buf_size)
08492             thread->buf[res++] = '\0';
08493          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
08494             thread->buf[res - 1] = '\0';
08495       }
08496       f.datalen = res - sizeof(*fh);
08497 
08498       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
08499          from the real peer, not the transfer peer */
08500       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08501           ((f.subclass != IAX_COMMAND_INVAL) ||
08502            (f.frametype != AST_FRAME_IAX))) {
08503          unsigned char x;
08504          int call_to_destroy;
08505          /* First we have to qualify that the ACKed value is within our window */
08506          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
08507             x = fr->iseqno;
08508          else 
08509             x = iaxs[fr->callno]->oseqno;
08510          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08511             /* The acknowledgement is within our window.  Time to acknowledge everything
08512                that it says to */
08513             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08514                /* Ack the packet with the given timestamp */
08515                if (iaxdebug)
08516                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
08517                call_to_destroy = 0;
08518                AST_LIST_LOCK(&frame_queue);
08519                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08520                   /* If it's our call, and our timestamp, mark -1 retries */
08521                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08522                      cur->retries = -1;
08523                      /* Destroy call if this is the end */
08524                      if (cur->final)
08525                         call_to_destroy = fr->callno;
08526                   }
08527                }
08528                AST_LIST_UNLOCK(&frame_queue);
08529                if (call_to_destroy) {
08530                   if (iaxdebug)
08531                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08532                   ast_mutex_lock(&iaxsl[call_to_destroy]);
08533                   iax2_destroy(call_to_destroy);
08534                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
08535                }
08536             }
08537             /* Note how much we've received acknowledgement for */
08538             if (iaxs[fr->callno])
08539                iaxs[fr->callno]->rseqno = fr->iseqno;
08540             else {
08541                /* Stop processing now */
08542                ast_mutex_unlock(&iaxsl[fr->callno]);
08543                return 1;
08544             }
08545          } else {
08546             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08547          }
08548       }
08549       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08550          ((f.frametype != AST_FRAME_IAX) || 
08551           ((f.subclass != IAX_COMMAND_TXACC) &&
08552            (f.subclass != IAX_COMMAND_TXCNT)))) {
08553          /* Only messages we accept from a transfer host are TXACC and TXCNT */
08554          ast_mutex_unlock(&iaxsl[fr->callno]);
08555          return 1;
08556       }
08557 
08558       if (f.datalen) {
08559          if (f.frametype == AST_FRAME_IAX) {
08560             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08561                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08562                ast_mutex_unlock(&iaxsl[fr->callno]);
08563                return 1;
08564             }
08565             f.data.ptr = NULL;
08566             f.datalen = 0;
08567          } else {
08568             f.data.ptr = thread->buf + sizeof(*fh);
08569             memset(&ies, 0, sizeof(ies));
08570          }
08571       } else {
08572          if (f.frametype == AST_FRAME_IAX)
08573             f.data.ptr = NULL;
08574          else
08575             f.data.ptr = empty;
08576          memset(&ies, 0, sizeof(ies));
08577       }
08578 
08579       /* when we receive the first full frame for a new incoming channel,
08580          it is safe to start the PBX on the channel because we have now
08581          completed a 3-way handshake with the peer */
08582       if ((f.frametype == AST_FRAME_VOICE) ||
08583           (f.frametype == AST_FRAME_VIDEO) ||
08584           (f.frametype == AST_FRAME_IAX)) {
08585          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08586             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08587             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08588                ast_mutex_unlock(&iaxsl[fr->callno]);
08589                return 1;
08590             }
08591          }
08592 
08593          if (ies.vars) {
08594             struct ast_datastore *variablestore = NULL;
08595             struct ast_variable *var, *prev = NULL;
08596             AST_LIST_HEAD(, ast_var_t) *varlist;
08597             if ((c = iaxs[fr->callno]->owner)) {
08598                varlist = ast_calloc(1, sizeof(*varlist));
08599                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08600 
08601                if (variablestore && varlist) {
08602                   variablestore->data = varlist;
08603                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08604                   AST_LIST_HEAD_INIT(varlist);
08605                   ast_debug(1, "I can haz IAX vars?\n");
08606                   for (var = ies.vars; var; var = var->next) {
08607                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08608                      if (prev) {
08609                         ast_free(prev);
08610                      }
08611                      prev = var;
08612                      if (!newvar) {
08613                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
08614                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08615                      } else {
08616                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08617                      }
08618                   }
08619                   if (prev) {
08620                      ast_free(prev);
08621                   }
08622                   ies.vars = NULL;
08623                   ast_channel_datastore_add(c, variablestore);
08624                } else {
08625                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08626                   if (variablestore) {
08627                      ast_datastore_free(variablestore);
08628                   }
08629                   if (varlist) {
08630                      ast_free(varlist);
08631                   }
08632                }
08633             } else {
08634                /* No channel yet, so transfer the variables directly over to the pvt,
08635                 * for later inheritance. */
08636                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
08637                for (var = ies.vars; var && var->next; var = var->next);
08638                if (var) {
08639                   var->next = iaxs[fr->callno]->iaxvars;
08640                   iaxs[fr->callno]->iaxvars = ies.vars;
08641                   ies.vars = NULL;
08642                }
08643             }
08644          }
08645 
08646          if (ies.vars) {
08647             ast_debug(1, "I have IAX variables, but they were not processed\n");
08648          }
08649       }
08650 
08651       if (f.frametype == AST_FRAME_VOICE) {
08652          if (f.subclass != iaxs[fr->callno]->voiceformat) {
08653                iaxs[fr->callno]->voiceformat = f.subclass;
08654                ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
08655                if (iaxs[fr->callno]->owner) {
08656                   int orignative;
08657 retryowner:
08658                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
08659                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08660                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08661                   }
08662                   if (iaxs[fr->callno]) {
08663                      if (iaxs[fr->callno]->owner) {
08664                         orignative = iaxs[fr->callno]->owner->nativeformats;
08665                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
08666                         if (iaxs[fr->callno]->owner->readformat)
08667                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08668                         iaxs[fr->callno]->owner->nativeformats = orignative;
08669                         ast_channel_unlock(iaxs[fr->callno]->owner);
08670                      }
08671                   } else {
08672                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
08673                      /* Free remote variables (if any) */
08674                      if (ies.vars) {
08675                         ast_variables_destroy(ies.vars);
08676                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
08677                         ies.vars = NULL;
08678                      }
08679                      ast_mutex_unlock(&iaxsl[fr->callno]);
08680                      return 1;
08681                   }
08682                }
08683          }
08684       }
08685       if (f.frametype == AST_FRAME_VIDEO) {
08686          if (f.subclass != iaxs[fr->callno]->videoformat) {
08687             ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08688             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08689          }
08690       }
08691       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08692          if (f.subclass == AST_CONTROL_BUSY) {
08693             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08694          } else if (f.subclass == AST_CONTROL_CONGESTION) {
08695             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08696          }
08697       }
08698       if (f.frametype == AST_FRAME_IAX) {
08699          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08700          /* Handle the IAX pseudo frame itself */
08701          if (iaxdebug)
08702             ast_debug(1, "IAX subclass %d received\n", f.subclass);
08703 
08704                         /* Update last ts unless the frame's timestamp originated with us. */
08705          if (iaxs[fr->callno]->last < fr->ts &&
08706                             f.subclass != IAX_COMMAND_ACK &&
08707                             f.subclass != IAX_COMMAND_PONG &&
08708                             f.subclass != IAX_COMMAND_LAGRP) {
08709             iaxs[fr->callno]->last = fr->ts;
08710             if (iaxdebug)
08711                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08712          }
08713 
08714          switch(f.subclass) {
08715          case IAX_COMMAND_ACK:
08716             /* Do nothing */
08717             break;
08718          case IAX_COMMAND_QUELCH:
08719             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08720                     /* Generate Manager Hold event, if necessary*/
08721                if (iaxs[fr->callno]->owner) {
08722                   manager_event(EVENT_FLAG_CALL, "Hold",
08723                      "Status: On\r\n"
08724                      "Channel: %s\r\n"
08725                      "Uniqueid: %s\r\n",
08726                      iaxs[fr->callno]->owner->name, 
08727                      iaxs[fr->callno]->owner->uniqueid);
08728                }
08729 
08730                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08731                if (ies.musiconhold) {
08732                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08733                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
08734                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
08735                         S_OR(moh_suggest, NULL),
08736                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
08737                      if (!iaxs[fr->callno]) {
08738                         ast_mutex_unlock(&iaxsl[fr->callno]);
08739                         return 1;
08740                      }
08741                   }
08742                }
08743             }
08744             break;
08745          case IAX_COMMAND_UNQUELCH:
08746             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08747                     /* Generate Manager Unhold event, if necessary*/
08748                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08749                   manager_event(EVENT_FLAG_CALL, "Hold",
08750                      "Status: Off\r\n"
08751                      "Channel: %s\r\n"
08752                      "Uniqueid: %s\r\n",
08753                      iaxs[fr->callno]->owner->name, 
08754                      iaxs[fr->callno]->owner->uniqueid);
08755                }
08756 
08757                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08758                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08759                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08760                   if (!iaxs[fr->callno]) {
08761                      ast_mutex_unlock(&iaxsl[fr->callno]);
08762                      return 1;
08763                   }
08764                }
08765             }
08766             break;
08767          case IAX_COMMAND_TXACC:
08768             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08769                /* Ack the packet with the given timestamp */
08770                AST_LIST_LOCK(&frame_queue);
08771                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08772                   /* Cancel any outstanding txcnt's */
08773                   if ((fr->callno == cur->callno) && (cur->transfer))
08774                      cur->retries = -1;
08775                }
08776                AST_LIST_UNLOCK(&frame_queue);
08777                memset(&ied1, 0, sizeof(ied1));
08778                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08779                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08780                iaxs[fr->callno]->transferring = TRANSFER_READY;
08781             }
08782             break;
08783          case IAX_COMMAND_NEW:
08784             /* Ignore if it's already up */
08785             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08786                break;
08787             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08788                ast_mutex_unlock(&iaxsl[fr->callno]);
08789                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08790                ast_mutex_lock(&iaxsl[fr->callno]);
08791                if (!iaxs[fr->callno]) {
08792                   ast_mutex_unlock(&iaxsl[fr->callno]);
08793                   return 1;
08794                }
08795             }
08796             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
08797             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08798                int new_callno;
08799                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08800                   fr->callno = new_callno;
08801             }
08802             /* For security, always ack immediately */
08803             if (delayreject)
08804                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08805             if (check_access(fr->callno, &sin, &ies)) {
08806                /* They're not allowed on */
08807                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08808                if (authdebug)
08809                   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);
08810                break;
08811             }
08812             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08813                const char *context, *exten, *cid_num;
08814 
08815                context = ast_strdupa(iaxs[fr->callno]->context);
08816                exten = ast_strdupa(iaxs[fr->callno]->exten);
08817                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08818 
08819                /* This might re-enter the IAX code and need the lock */
08820                ast_mutex_unlock(&iaxsl[fr->callno]);
08821                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08822                ast_mutex_lock(&iaxsl[fr->callno]);
08823 
08824                if (!iaxs[fr->callno]) {
08825                   ast_mutex_unlock(&iaxsl[fr->callno]);
08826                   return 1;
08827                }
08828             } else
08829                exists = 0;
08830             /* Get OSP token if it does exist */
08831             save_osptoken(fr, &ies);
08832             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08833                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08834                   memset(&ied0, 0, sizeof(ied0));
08835                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08836                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08837                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08838                   if (!iaxs[fr->callno]) {
08839                      ast_mutex_unlock(&iaxsl[fr->callno]);
08840                      return 1;
08841                   }
08842                   if (authdebug)
08843                      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);
08844                } else {
08845                   /* Select an appropriate format */
08846 
08847                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08848                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08849                         using_prefs = "reqonly";
08850                      } else {
08851                         using_prefs = "disabled";
08852                      }
08853                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08854                      memset(&pref, 0, sizeof(pref));
08855                      strcpy(caller_pref_buf, "disabled");
08856                      strcpy(host_pref_buf, "disabled");
08857                   } else {
08858                      using_prefs = "mine";
08859                      /* If the information elements are in here... use them */
08860                      if (ies.codec_prefs)
08861                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08862                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08863                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
08864                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08865                            pref = iaxs[fr->callno]->rprefs;
08866                            using_prefs = "caller";
08867                         } else {
08868                            pref = iaxs[fr->callno]->prefs;
08869                         }
08870                      } else
08871                         pref = iaxs[fr->callno]->prefs;
08872                      
08873                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08874                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08875                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08876                   }
08877                   if (!format) {
08878                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08879                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08880                      if (!format) {
08881                         memset(&ied0, 0, sizeof(ied0));
08882                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08883                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08884                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08885                         if (!iaxs[fr->callno]) {
08886                            ast_mutex_unlock(&iaxsl[fr->callno]);
08887                            return 1;
08888                         }
08889                         if (authdebug) {
08890                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08891                               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);
08892                            else 
08893                               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);
08894                         }
08895                      } else {
08896                         /* Pick one... */
08897                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08898                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08899                               format = 0;
08900                         } else {
08901                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08902                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08903                               memset(&pref, 0, sizeof(pref));
08904                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08905                               strcpy(caller_pref_buf,"disabled");
08906                               strcpy(host_pref_buf,"disabled");
08907                            } else {
08908                               using_prefs = "mine";
08909                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08910                                  /* Do the opposite of what we tried above. */
08911                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08912                                     pref = iaxs[fr->callno]->prefs;                       
08913                                  } else {
08914                                     pref = iaxs[fr->callno]->rprefs;
08915                                     using_prefs = "caller";
08916                                  }
08917                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08918                            
08919                               } else /* if no codec_prefs IE do it the old way */
08920                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08921                            }
08922                         }
08923 
08924                         if (!format) {
08925                            memset(&ied0, 0, sizeof(ied0));
08926                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08927                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08928                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08929                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08930                            if (!iaxs[fr->callno]) {
08931                               ast_mutex_unlock(&iaxsl[fr->callno]);
08932                               return 1;
08933                            }
08934                            if (authdebug)
08935                               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);
08936                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
08937                            break;
08938                         }
08939                      }
08940                   }
08941                   if (format) {
08942                      /* No authentication required, let them in */
08943                      memset(&ied1, 0, sizeof(ied1));
08944                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08945                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08946                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08947                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08948                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
08949                                     "%srequested format = %s,\n"
08950                                     "%srequested prefs = %s,\n"
08951                                     "%sactual format = %s,\n"
08952                                     "%shost prefs = %s,\n"
08953                                     "%spriority = %s\n",
08954                                     ast_inet_ntoa(sin.sin_addr), 
08955                                     VERBOSE_PREFIX_4,
08956                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
08957                                     VERBOSE_PREFIX_4,
08958                                     caller_pref_buf,
08959                                     VERBOSE_PREFIX_4,
08960                                     ast_getformatname(format), 
08961                                     VERBOSE_PREFIX_4,
08962                                     host_pref_buf, 
08963                                     VERBOSE_PREFIX_4,
08964                                     using_prefs);
08965                         
08966                         iaxs[fr->callno]->chosenformat = format;
08967                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08968                      } else {
08969                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08970                         /* If this is a TBD call, we're ready but now what...  */
08971                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08972                      }
08973                   }
08974                }
08975                break;
08976             }
08977             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
08978                merge_encryption(iaxs[fr->callno],ies.encmethods);
08979             else
08980                iaxs[fr->callno]->encmethods = 0;
08981             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
08982                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
08983             if (!iaxs[fr->callno]) {
08984                ast_mutex_unlock(&iaxsl[fr->callno]);
08985                return 1;
08986             }
08987             break;
08988          case IAX_COMMAND_DPREQ:
08989             /* Request status in the dialplan */
08990             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
08991                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
08992                if (iaxcompat) {
08993                   /* Spawn a thread for the lookup */
08994                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
08995                } else {
08996                   /* Just look it up */
08997                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
08998                }
08999             }
09000             break;
09001          case IAX_COMMAND_HANGUP:
09002             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09003             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
09004             /* Set hangup cause according to remote */
09005             if (ies.causecode && iaxs[fr->callno]->owner)
09006                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09007             /* Send ack immediately, before we destroy */
09008             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09009             iax2_destroy(fr->callno);
09010             break;
09011          case IAX_COMMAND_REJECT:
09012             /* Set hangup cause according to remote */
09013             if (ies.causecode && iaxs[fr->callno]->owner)
09014                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09015 
09016             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09017                if (iaxs[fr->callno]->owner && authdebug)
09018                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09019                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09020                      ies.cause ? ies.cause : "<Unknown>");
09021                ast_debug(1, "Immediately destroying %d, having received reject\n",
09022                   fr->callno);
09023             }
09024             /* Send ack immediately, before we destroy */
09025             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09026                          fr->ts, NULL, 0, fr->iseqno);
09027             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09028                iaxs[fr->callno]->error = EPERM;
09029             iax2_destroy(fr->callno);
09030             break;
09031          case IAX_COMMAND_TRANSFER:
09032          {
09033             struct ast_channel *bridged_chan;
09034 
09035             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09036                /* Set BLINDTRANSFER channel variables */
09037 
09038                ast_mutex_unlock(&iaxsl[fr->callno]);
09039                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09040                ast_mutex_lock(&iaxsl[fr->callno]);
09041                if (!iaxs[fr->callno]) {
09042                   ast_mutex_unlock(&iaxsl[fr->callno]);
09043                   return 1;
09044                }
09045 
09046                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09047                if (!strcmp(ies.called_number, ast_parking_ext())) {
09048                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09049                   ast_mutex_unlock(&iaxsl[fr->callno]);
09050                   if (iax_park(bridged_chan, saved_channel)) {
09051                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09052                   } else {
09053                      ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
09054                   }
09055                   ast_mutex_lock(&iaxsl[fr->callno]);
09056                } else {
09057                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09058                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
09059                         ies.called_number, iaxs[fr->callno]->context);
09060                   else {
09061                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
09062                         ies.called_number, iaxs[fr->callno]->context);
09063                   }
09064                }
09065             } else {
09066                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
09067             }
09068 
09069             break;
09070          }
09071          case IAX_COMMAND_ACCEPT:
09072             /* Ignore if call is already up or needs authentication or is a TBD */
09073             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09074                break;
09075             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09076                /* Send ack immediately, before we destroy */
09077                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09078                iax2_destroy(fr->callno);
09079                break;
09080             }
09081             if (ies.format) {
09082                iaxs[fr->callno]->peerformat = ies.format;
09083             } else {
09084                if (iaxs[fr->callno]->owner)
09085                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09086                else
09087                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09088             }
09089             ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
09090             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09091                memset(&ied0, 0, sizeof(ied0));
09092                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09093                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09094                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09095                if (!iaxs[fr->callno]) {
09096                   ast_mutex_unlock(&iaxsl[fr->callno]);
09097                   return 1;
09098                }
09099                if (authdebug)
09100                   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);
09101             } else {
09102                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09103                if (iaxs[fr->callno]->owner) {
09104                   /* Switch us to use a compatible format */
09105                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09106                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09107 retryowner2:
09108                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09109                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09110                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09111                   }
09112                   
09113                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09114                      /* Setup read/write formats properly. */
09115                      if (iaxs[fr->callno]->owner->writeformat)
09116                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
09117                      if (iaxs[fr->callno]->owner->readformat)
09118                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
09119                      ast_channel_unlock(iaxs[fr->callno]->owner);
09120                   }
09121                }
09122             }
09123             if (iaxs[fr->callno]) {
09124                AST_LIST_LOCK(&dpcache);
09125                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
09126                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
09127                      iax2_dprequest(dp, fr->callno);
09128                AST_LIST_UNLOCK(&dpcache);
09129             }
09130             break;
09131          case IAX_COMMAND_POKE:
09132             /* Send back a pong packet with the original timestamp */
09133             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09134             if (!iaxs[fr->callno]) {
09135                ast_mutex_unlock(&iaxsl[fr->callno]);
09136                return 1;
09137             }
09138             break;
09139          case IAX_COMMAND_PING:
09140          {
09141             struct iax_ie_data pingied;
09142             construct_rr(iaxs[fr->callno], &pingied);
09143             /* Send back a pong packet with the original timestamp */
09144             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09145          }
09146             break;
09147          case IAX_COMMAND_PONG:
09148             /* Calculate ping time */
09149             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09150             /* save RR info */
09151             save_rr(fr, &ies);
09152 
09153             /* Good time to write jb stats for this call */
09154             log_jitterstats(fr->callno);
09155 
09156             if (iaxs[fr->callno]->peerpoke) {
09157                peer = iaxs[fr->callno]->peerpoke;
09158                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
09159                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09160                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09161                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
09162                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
09163                   }
09164                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09165                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
09166                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09167                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
09168                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
09169                   }
09170                }
09171                peer->lastms = iaxs[fr->callno]->pingtime;
09172                if (peer->smoothing && (peer->lastms > -1))
09173                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09174                else if (peer->smoothing && peer->lastms < 0)
09175                   peer->historicms = (0 + peer->historicms) / 2;
09176                else              
09177                   peer->historicms = iaxs[fr->callno]->pingtime;
09178 
09179                /* Remove scheduled iax2_poke_noanswer */
09180                if (peer->pokeexpire > -1) {
09181                   if (!ast_sched_del(sched, peer->pokeexpire)) {
09182                      peer_unref(peer);
09183                      peer->pokeexpire = -1;
09184                   }
09185                }
09186                /* Schedule the next cycle */
09187                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
09188                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09189                else
09190                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09191                if (peer->pokeexpire == -1)
09192                   peer_unref(peer);
09193                /* and finally send the ack */
09194                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09195                /* And wrap up the qualify call */
09196                iax2_destroy(fr->callno);
09197                peer->callno = 0;
09198                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09199             }
09200             break;
09201          case IAX_COMMAND_LAGRQ:
09202          case IAX_COMMAND_LAGRP:
09203             f.src = "LAGRQ";
09204             f.mallocd = 0;
09205             f.offset = 0;
09206             f.samples = 0;
09207             iax_frame_wrap(fr, &f);
09208             if(f.subclass == IAX_COMMAND_LAGRQ) {
09209                /* Received a LAGRQ - echo back a LAGRP */
09210                fr->af.subclass = IAX_COMMAND_LAGRP;
09211                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09212             } else {
09213                /* Received LAGRP in response to our LAGRQ */
09214                unsigned int ts;
09215                /* This is a reply we've been given, actually measure the difference */
09216                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09217                iaxs[fr->callno]->lag = ts - fr->ts;
09218                if (iaxdebug)
09219                   ast_debug(1, "Peer %s lag measured as %dms\n",
09220                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09221             }
09222             break;
09223          case IAX_COMMAND_AUTHREQ:
09224             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09225                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>");
09226                break;
09227             }
09228             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09229                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09230                         .subclass = AST_CONTROL_HANGUP,
09231                };
09232                ast_log(LOG_WARNING, 
09233                   "I don't know how to authenticate %s to %s\n", 
09234                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09235                iax2_queue_frame(fr->callno, &hangup_fr);
09236             }
09237             if (!iaxs[fr->callno]) {
09238                ast_mutex_unlock(&iaxsl[fr->callno]);
09239                return 1;
09240             }
09241             break;
09242          case IAX_COMMAND_AUTHREP:
09243             /* For security, always ack immediately */
09244             if (delayreject)
09245                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09246             /* Ignore once we've started */
09247             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09248                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>");
09249                break;
09250             }
09251             if (authenticate_verify(iaxs[fr->callno], &ies)) {
09252                if (authdebug)
09253                   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);
09254                memset(&ied0, 0, sizeof(ied0));
09255                auth_fail(fr->callno, IAX_COMMAND_REJECT);
09256                break;
09257             }
09258             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09259                /* This might re-enter the IAX code and need the lock */
09260                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09261             } else
09262                exists = 0;
09263             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09264                if (authdebug)
09265                   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);
09266                memset(&ied0, 0, sizeof(ied0));
09267                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09268                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09269                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09270                if (!iaxs[fr->callno]) {
09271                   ast_mutex_unlock(&iaxsl[fr->callno]);
09272                   return 1;
09273                }
09274             } else {
09275                /* Select an appropriate format */
09276                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09277                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09278                      using_prefs = "reqonly";
09279                   } else {
09280                      using_prefs = "disabled";
09281                   }
09282                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09283                   memset(&pref, 0, sizeof(pref));
09284                   strcpy(caller_pref_buf, "disabled");
09285                   strcpy(host_pref_buf, "disabled");
09286                } else {
09287                   using_prefs = "mine";
09288                   if (ies.codec_prefs)
09289                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09290                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09291                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09292                         pref = iaxs[fr->callno]->rprefs;
09293                         using_prefs = "caller";
09294                      } else {
09295                         pref = iaxs[fr->callno]->prefs;
09296                      }
09297                   } else /* if no codec_prefs IE do it the old way */
09298                      pref = iaxs[fr->callno]->prefs;
09299                
09300                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09301                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09302                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09303                }
09304                if (!format) {
09305                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09306                      ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
09307                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09308                   }
09309                   if (!format) {
09310                      if (authdebug) {
09311                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
09312                            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);
09313                         else
09314                            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);
09315                      }
09316                      memset(&ied0, 0, sizeof(ied0));
09317                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09318                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09319                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09320                      if (!iaxs[fr->callno]) {
09321                         ast_mutex_unlock(&iaxsl[fr->callno]);
09322                         return 1;
09323                      }
09324                   } else {
09325                      /* Pick one... */
09326                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09327                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09328                            format = 0;
09329                      } else {
09330                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09331                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09332                            memset(&pref, 0, sizeof(pref));
09333                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09334                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09335                            strcpy(caller_pref_buf,"disabled");
09336                            strcpy(host_pref_buf,"disabled");
09337                         } else {
09338                            using_prefs = "mine";
09339                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09340                               /* Do the opposite of what we tried above. */
09341                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09342                                  pref = iaxs[fr->callno]->prefs;                 
09343                               } else {
09344                                  pref = iaxs[fr->callno]->rprefs;
09345                                  using_prefs = "caller";
09346                               }
09347                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09348                            } else /* if no codec_prefs IE do it the old way */
09349                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
09350                         }
09351                      }
09352                      if (!format) {
09353                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09354                         if (authdebug) {
09355                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09356                               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);
09357                            else
09358                               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);
09359                         }
09360                         memset(&ied0, 0, sizeof(ied0));
09361                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09362                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09363                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09364                         if (!iaxs[fr->callno]) {
09365                            ast_mutex_unlock(&iaxsl[fr->callno]);
09366                            return 1;
09367                         }
09368                      }
09369                   }
09370                }
09371                if (format) {
09372                   /* Authentication received */
09373                   memset(&ied1, 0, sizeof(ied1));
09374                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09375                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09376                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09377                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09378                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
09379                                  "%srequested format = %s,\n"
09380                                  "%srequested prefs = %s,\n"
09381                                  "%sactual format = %s,\n"
09382                                  "%shost prefs = %s,\n"
09383                                  "%spriority = %s\n", 
09384                                  ast_inet_ntoa(sin.sin_addr), 
09385                                  VERBOSE_PREFIX_4,
09386                                  ast_getformatname(iaxs[fr->callno]->peerformat),
09387                                  VERBOSE_PREFIX_4,
09388                                  caller_pref_buf,
09389                                  VERBOSE_PREFIX_4,
09390                                  ast_getformatname(format),
09391                                  VERBOSE_PREFIX_4,
09392                                  host_pref_buf,
09393                                  VERBOSE_PREFIX_4,
09394                                  using_prefs);
09395 
09396                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09397                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09398                         iax2_destroy(fr->callno);
09399                      else if (ies.vars) {
09400                         struct ast_datastore *variablestore;
09401                         struct ast_variable *var, *prev = NULL;
09402                         AST_LIST_HEAD(, ast_var_t) *varlist;
09403                         varlist = ast_calloc(1, sizeof(*varlist));
09404                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09405                         if (variablestore && varlist) {
09406                            variablestore->data = varlist;
09407                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09408                            AST_LIST_HEAD_INIT(varlist);
09409                            ast_debug(1, "I can haz IAX vars? w00t\n");
09410                            for (var = ies.vars; var; var = var->next) {
09411                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09412                               if (prev)
09413                                  ast_free(prev);
09414                               prev = var;
09415                               if (!newvar) {
09416                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
09417                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09418                               } else {
09419                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09420                               }
09421                            }
09422                            if (prev)
09423                               ast_free(prev);
09424                            ies.vars = NULL;
09425                            ast_channel_datastore_add(c, variablestore);
09426                         } else {
09427                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09428                            if (variablestore)
09429                               ast_datastore_free(variablestore);
09430                            if (varlist)
09431                               ast_free(varlist);
09432                         }
09433                      }
09434                   } else {
09435                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09436                      /* If this is a TBD call, we're ready but now what...  */
09437                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09438                   }
09439                }
09440             }
09441             break;
09442          case IAX_COMMAND_DIAL:
09443             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09444                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09445                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09446                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09447                   if (authdebug)
09448                      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);
09449                   memset(&ied0, 0, sizeof(ied0));
09450                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09451                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09452                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09453                   if (!iaxs[fr->callno]) {
09454                      ast_mutex_unlock(&iaxsl[fr->callno]);
09455                      return 1;
09456                   }
09457                } else {
09458                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09459                   ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09460                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09461                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09462                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09463                      iax2_destroy(fr->callno);
09464                   else if (ies.vars) {
09465                      struct ast_datastore *variablestore;
09466                      struct ast_variable *var, *prev = NULL;
09467                      AST_LIST_HEAD(, ast_var_t) *varlist;
09468                      varlist = ast_calloc(1, sizeof(*varlist));
09469                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09470                      ast_debug(1, "I can haz IAX vars? w00t\n");
09471                      if (variablestore && varlist) {
09472                         variablestore->data = varlist;
09473                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09474                         AST_LIST_HEAD_INIT(varlist);
09475                         for (var = ies.vars; var; var = var->next) {
09476                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09477                            if (prev)
09478                               ast_free(prev);
09479                            prev = var;
09480                            if (!newvar) {
09481                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
09482                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09483                            } else {
09484                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09485                            }
09486                         }
09487                         if (prev)
09488                            ast_free(prev);
09489                         ies.vars = NULL;
09490                         ast_channel_datastore_add(c, variablestore);
09491                      } else {
09492                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09493                         if (variablestore)
09494                            ast_datastore_free(variablestore);
09495                         if (varlist)
09496                            ast_free(varlist);
09497                      }
09498                   }
09499                }
09500             }
09501             break;
09502          case IAX_COMMAND_INVAL:
09503             iaxs[fr->callno]->error = ENOTCONN;
09504             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
09505             iax2_destroy(fr->callno);
09506             ast_debug(1, "Destroying call %d\n", fr->callno);
09507             break;
09508          case IAX_COMMAND_VNAK:
09509             ast_debug(1, "Received VNAK: resending outstanding frames\n");
09510             /* Force retransmission */
09511             vnak_retransmit(fr->callno, fr->iseqno);
09512             break;
09513          case IAX_COMMAND_REGREQ:
09514          case IAX_COMMAND_REGREL:
09515             /* For security, always ack immediately */
09516             if (delayreject)
09517                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09518             if (register_verify(fr->callno, &sin, &ies)) {
09519                if (!iaxs[fr->callno]) {
09520                   ast_mutex_unlock(&iaxsl[fr->callno]);
09521                   return 1;
09522                }
09523                /* Send delayed failure */
09524                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09525                break;
09526             }
09527             if (!iaxs[fr->callno]) {
09528                ast_mutex_unlock(&iaxsl[fr->callno]);
09529                return 1;
09530             }
09531             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09532                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09533 
09534                if (f.subclass == IAX_COMMAND_REGREL)
09535                   memset(&sin, 0, sizeof(sin));
09536                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09537                   ast_log(LOG_WARNING, "Registry error\n");
09538                if (!iaxs[fr->callno]) {
09539                   ast_mutex_unlock(&iaxsl[fr->callno]);
09540                   return 1;
09541                }
09542                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09543                   ast_mutex_unlock(&iaxsl[fr->callno]);
09544                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09545                   ast_mutex_lock(&iaxsl[fr->callno]);
09546                   if (!iaxs[fr->callno]) {
09547                      ast_mutex_unlock(&iaxsl[fr->callno]);
09548                      return 1;
09549                   }
09550                }
09551                break;
09552             }
09553             registry_authrequest(fr->callno);
09554             if (!iaxs[fr->callno]) {
09555                ast_mutex_unlock(&iaxsl[fr->callno]);
09556                return 1;
09557             }
09558             break;
09559          case IAX_COMMAND_REGACK:
09560             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
09561                ast_log(LOG_WARNING, "Registration failure\n");
09562             /* Send ack immediately, before we destroy */
09563             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09564             iax2_destroy(fr->callno);
09565             break;
09566          case IAX_COMMAND_REGREJ:
09567             if (iaxs[fr->callno]->reg) {
09568                if (authdebug) {
09569                   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));
09570                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
09571                }
09572                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09573             }
09574             /* Send ack immediately, before we destroy */
09575             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09576             iax2_destroy(fr->callno);
09577             break;
09578          case IAX_COMMAND_REGAUTH:
09579             /* Authentication request */
09580             if (registry_rerequest(&ies, fr->callno, &sin)) {
09581                memset(&ied0, 0, sizeof(ied0));
09582                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09583                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09584                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09585                if (!iaxs[fr->callno]) {
09586                   ast_mutex_unlock(&iaxsl[fr->callno]);
09587                   return 1;
09588                }
09589             }
09590             break;
09591          case IAX_COMMAND_TXREJ:
09592             iaxs[fr->callno]->transferring = 0;
09593             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09594             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09595             if (iaxs[fr->callno]->bridgecallno) {
09596                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09597                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09598                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09599                }
09600             }
09601             break;
09602          case IAX_COMMAND_TXREADY:
09603             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09604                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09605                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09606                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09607                else
09608                   iaxs[fr->callno]->transferring = TRANSFER_READY;
09609                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09610                if (iaxs[fr->callno]->bridgecallno) {
09611                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09612                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09613                      /* They're both ready, now release them. */
09614                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09615                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09616                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09617 
09618                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09619                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09620 
09621                         memset(&ied0, 0, sizeof(ied0));
09622                         memset(&ied1, 0, sizeof(ied1));
09623                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09624                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09625                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09626                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09627                      } else {
09628                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09629                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09630 
09631                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09632                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09633                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09634                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09635 
09636                         /* Stop doing lag & ping requests */
09637                         stop_stuff(fr->callno);
09638                         stop_stuff(iaxs[fr->callno]->bridgecallno);
09639 
09640                         memset(&ied0, 0, sizeof(ied0));
09641                         memset(&ied1, 0, sizeof(ied1));
09642                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09643                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09644                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09645                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09646                      }
09647 
09648                   }
09649                }
09650             }
09651             break;
09652          case IAX_COMMAND_TXREQ:
09653             try_transfer(iaxs[fr->callno], &ies);
09654             break;
09655          case IAX_COMMAND_TXCNT:
09656             if (iaxs[fr->callno]->transferring)
09657                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09658             break;
09659          case IAX_COMMAND_TXREL:
09660             /* Send ack immediately, rather than waiting until we've changed addresses */
09661             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09662             complete_transfer(fr->callno, &ies);
09663             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
09664             break;   
09665          case IAX_COMMAND_TXMEDIA:
09666             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09667                AST_LIST_LOCK(&frame_queue);
09668                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09669                   /* Cancel any outstanding frames and start anew */
09670                   if ((fr->callno == cur->callno) && (cur->transfer))
09671                      cur->retries = -1;
09672                }
09673                AST_LIST_UNLOCK(&frame_queue);
09674                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
09675                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09676             }
09677             break;
09678          case IAX_COMMAND_RTKEY:
09679             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
09680                ast_log(LOG_WARNING, 
09681                   "we've been told to rotate our encryption key, "
09682                   "but this isn't an encrypted call. bad things will happen.\n"
09683                );
09684                break;
09685             }
09686 
09687             IAX_DEBUGDIGEST("Receiving", ies.challenge);
09688 
09689             ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
09690             break;
09691          case IAX_COMMAND_DPREP:
09692             complete_dpreply(iaxs[fr->callno], &ies);
09693             break;
09694          case IAX_COMMAND_UNSUPPORT:
09695             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09696             break;
09697          case IAX_COMMAND_FWDOWNL:
09698             /* Firmware download */
09699             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09700                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09701                break;
09702             }
09703             memset(&ied0, 0, sizeof(ied0));
09704             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09705             if (res < 0)
09706                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09707             else if (res > 0)
09708                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09709             else
09710                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09711             if (!iaxs[fr->callno]) {
09712                ast_mutex_unlock(&iaxsl[fr->callno]);
09713                return 1;
09714             }
09715             break;
09716          default:
09717             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09718             memset(&ied0, 0, sizeof(ied0));
09719             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09720             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09721          }
09722          /* Free remote variables (if any) */
09723          if (ies.vars) {
09724             ast_variables_destroy(ies.vars);
09725             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
09726             ies.vars = NULL;
09727          }
09728 
09729          /* Don't actually pass these frames along */
09730          if ((f.subclass != IAX_COMMAND_ACK) && 
09731            (f.subclass != IAX_COMMAND_TXCNT) && 
09732            (f.subclass != IAX_COMMAND_TXACC) && 
09733            (f.subclass != IAX_COMMAND_INVAL) &&
09734            (f.subclass != IAX_COMMAND_VNAK)) { 
09735             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09736                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09737          }
09738          ast_mutex_unlock(&iaxsl[fr->callno]);
09739          return 1;
09740       }
09741       /* Unless this is an ACK or INVAL frame, ack it */
09742       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09743          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09744    } else if (minivid) {
09745       f.frametype = AST_FRAME_VIDEO;
09746       if (iaxs[fr->callno]->videoformat > 0) 
09747          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09748       else {
09749          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09750          iax2_vnak(fr->callno);
09751          ast_mutex_unlock(&iaxsl[fr->callno]);
09752          return 1;
09753       }
09754       f.datalen = res - sizeof(*vh);
09755       if (f.datalen)
09756          f.data.ptr = thread->buf + sizeof(*vh);
09757       else
09758          f.data.ptr = NULL;
09759 #ifdef IAXTESTS
09760       if (test_resync) {
09761          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09762       } else
09763 #endif /* IAXTESTS */
09764          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09765    } else {
09766       /* A mini frame */
09767       f.frametype = AST_FRAME_VOICE;
09768       if (iaxs[fr->callno]->voiceformat > 0)
09769          f.subclass = iaxs[fr->callno]->voiceformat;
09770       else {
09771          ast_debug(1, "Received mini frame before first full voice frame\n");
09772          iax2_vnak(fr->callno);
09773          ast_mutex_unlock(&iaxsl[fr->callno]);
09774          return 1;
09775       }
09776       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09777       if (f.datalen < 0) {
09778          ast_log(LOG_WARNING, "Datalen < 0?\n");
09779          ast_mutex_unlock(&iaxsl[fr->callno]);
09780          return 1;
09781       }
09782       if (f.datalen)
09783          f.data.ptr = thread->buf + sizeof(*mh);
09784       else
09785          f.data.ptr = NULL;
09786 #ifdef IAXTESTS
09787       if (test_resync) {
09788          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09789       } else
09790 #endif /* IAXTESTS */
09791       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09792       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
09793    }
09794    /* Don't pass any packets until we're started */
09795    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09796       ast_mutex_unlock(&iaxsl[fr->callno]);
09797       return 1;
09798    }
09799    /* Common things */
09800    f.src = "IAX2";
09801    f.mallocd = 0;
09802    f.offset = 0;
09803    f.len = 0;
09804    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09805       f.samples = ast_codec_get_samples(&f);
09806       /* We need to byteswap incoming slinear samples from network byte order */
09807       if (f.subclass == AST_FORMAT_SLINEAR)
09808          ast_frame_byteswap_be(&f);
09809    } else
09810       f.samples = 0;
09811    iax_frame_wrap(fr, &f);
09812 
09813    /* If this is our most recent packet, use it as our basis for timestamping */
09814    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09815       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
09816       fr->outoforder = 0;
09817    } else {
09818       if (iaxdebug && iaxs[fr->callno])
09819          ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
09820       fr->outoforder = -1;
09821    }
09822    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09823    duped_fr = iaxfrdup2(fr);
09824    if (duped_fr) {
09825       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09826    }
09827    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09828       iaxs[fr->callno]->last = fr->ts;
09829 #if 1
09830       if (iaxdebug)
09831          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09832 #endif
09833    }
09834 
09835    /* Always run again */
09836    ast_mutex_unlock(&iaxsl[fr->callno]);
09837    return 1;
09838 }
09839 
09840 /* Function to clean up process thread if it is cancelled */
09841 static void iax2_process_thread_cleanup(void *data)
09842 {
09843    struct iax2_thread *thread = data;
09844    ast_mutex_destroy(&thread->lock);
09845    ast_cond_destroy(&thread->cond);
09846    ast_mutex_destroy(&thread->init_lock);
09847    ast_cond_destroy(&thread->init_cond);
09848    ast_free(thread);
09849    ast_atomic_dec_and_test(&iaxactivethreadcount);
09850 }
09851 
09852 static void *iax2_process_thread(void *data)
09853 {
09854    struct iax2_thread *thread = data;
09855    struct timeval wait;
09856    struct timespec ts;
09857    int put_into_idle = 0;
09858    int first_time = 1;
09859 
09860    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09861    pthread_cleanup_push(iax2_process_thread_cleanup, data);
09862    for(;;) {
09863       /* Wait for something to signal us to be awake */
09864       ast_mutex_lock(&thread->lock);
09865 
09866       /* Flag that we're ready to accept signals */
09867       if (first_time) {
09868          signal_condition(&thread->init_lock, &thread->init_cond);
09869          first_time = 0;
09870       }
09871 
09872       /* Put into idle list if applicable */
09873       if (put_into_idle)
09874          insert_idle_thread(thread);
09875 
09876       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
09877          struct iax2_thread *t = NULL;
09878          /* Wait to be signalled or time out */
09879          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09880          ts.tv_sec = wait.tv_sec;
09881          ts.tv_nsec = wait.tv_usec * 1000;
09882          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09883             /* This thread was never put back into the available dynamic
09884              * thread list, so just go away. */
09885             if (!put_into_idle) {
09886                ast_mutex_unlock(&thread->lock);
09887                break;
09888             }
09889             AST_LIST_LOCK(&dynamic_list);
09890             /* Account for the case where this thread is acquired *right* after a timeout */
09891             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09892                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
09893             AST_LIST_UNLOCK(&dynamic_list);
09894             if (t) {
09895                /* This dynamic thread timed out waiting for a task and was
09896                 * not acquired immediately after the timeout, 
09897                 * so it's time to go away. */
09898                ast_mutex_unlock(&thread->lock);
09899                break;
09900             }
09901             /* Someone grabbed our thread *right* after we timed out.
09902              * Wait for them to set us up with something to do and signal
09903              * us to continue. */
09904             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09905             ts.tv_sec = wait.tv_sec;
09906             ts.tv_nsec = wait.tv_usec * 1000;
09907             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09908             {
09909                ast_mutex_unlock(&thread->lock);
09910                break;
09911             }
09912          }
09913       } else {
09914          ast_cond_wait(&thread->cond, &thread->lock);
09915       }
09916 
09917       /* Go back into our respective list */
09918       put_into_idle = 1;
09919 
09920       ast_mutex_unlock(&thread->lock);
09921 
09922       if (thread->iostate == IAX_IOSTATE_IDLE)
09923          continue;
09924 
09925       /* Add ourselves to the active list now */
09926       AST_LIST_LOCK(&active_list);
09927       AST_LIST_INSERT_HEAD(&active_list, thread, list);
09928       AST_LIST_UNLOCK(&active_list);
09929 
09930       /* See what we need to do */
09931       switch(thread->iostate) {
09932       case IAX_IOSTATE_READY:
09933          thread->actions++;
09934          thread->iostate = IAX_IOSTATE_PROCESSING;
09935          socket_process(thread);
09936          handle_deferred_full_frames(thread);
09937          break;
09938       case IAX_IOSTATE_SCHEDREADY:
09939          thread->actions++;
09940          thread->iostate = IAX_IOSTATE_PROCESSING;
09941 #ifdef SCHED_MULTITHREADED
09942          thread->schedfunc(thread->scheddata);
09943 #endif      
09944       default:
09945          break;
09946       }
09947       time(&thread->checktime);
09948       thread->iostate = IAX_IOSTATE_IDLE;
09949 #ifdef DEBUG_SCHED_MULTITHREAD
09950       thread->curfunc[0]='\0';
09951 #endif      
09952 
09953       /* Now... remove ourselves from the active list, and return to the idle list */
09954       AST_LIST_LOCK(&active_list);
09955       AST_LIST_REMOVE(&active_list, thread, list);
09956       AST_LIST_UNLOCK(&active_list);
09957 
09958       /* Make sure another frame didn't sneak in there after we thought we were done. */
09959       handle_deferred_full_frames(thread);
09960    }
09961 
09962    /*!\note For some reason, idle threads are exiting without being removed
09963     * from an idle list, which is causing memory corruption.  Forcibly remove
09964     * it from the list, if it's there.
09965     */
09966    AST_LIST_LOCK(&idle_list);
09967    AST_LIST_REMOVE(&idle_list, thread, list);
09968    AST_LIST_UNLOCK(&idle_list);
09969 
09970    AST_LIST_LOCK(&dynamic_list);
09971    AST_LIST_REMOVE(&dynamic_list, thread, list);
09972    AST_LIST_UNLOCK(&dynamic_list);
09973 
09974    /* I am exiting here on my own volition, I need to clean up my own data structures
09975    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
09976    */
09977    pthread_cleanup_pop(1);
09978    return NULL;
09979 }
09980 
09981 static int iax2_do_register(struct iax2_registry *reg)
09982 {
09983    struct iax_ie_data ied;
09984    if (iaxdebug)
09985       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
09986 
09987    if (reg->dnsmgr && 
09988        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09989       /* Maybe the IP has changed, force DNS refresh */
09990       ast_dnsmgr_refresh(reg->dnsmgr);
09991    }
09992    
09993    /*
09994     * if IP has Changed, free allocated call to create a new one with new IP
09995     * call has the pointer to IP and must be updated to the new one
09996     */
09997    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
09998       int callno = reg->callno;
09999       ast_mutex_lock(&iaxsl[callno]);
10000       iax2_destroy(callno);
10001       ast_mutex_unlock(&iaxsl[callno]);
10002       reg->callno = 0;
10003    }
10004    if (!reg->addr.sin_addr.s_addr) {
10005       if (iaxdebug)
10006          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
10007       /* Setup the next registration attempt */
10008       reg->expire = iax2_sched_replace(reg->expire, sched, 
10009          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10010       return -1;
10011    }
10012 
10013    if (!reg->callno) {
10014       ast_debug(3, "Allocate call number\n");
10015       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
10016       if (reg->callno < 1) {
10017          ast_log(LOG_WARNING, "Unable to create call for registration\n");
10018          return -1;
10019       } else
10020          ast_debug(3, "Registration created on call %d\n", reg->callno);
10021       iaxs[reg->callno]->reg = reg;
10022       ast_mutex_unlock(&iaxsl[reg->callno]);
10023    }
10024    /* Setup the next registration a little early */
10025    reg->expire = iax2_sched_replace(reg->expire, sched, 
10026       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10027    /* Send the request */
10028    memset(&ied, 0, sizeof(ied));
10029    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10030    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10031    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10032    reg->regstate = REG_STATE_REGSENT;
10033    return 0;
10034 }
10035 
10036 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
10037 {
10038    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
10039       is found for template */
10040    struct iax_ie_data provdata;
10041    struct iax_ie_data ied;
10042    unsigned int sig;
10043    struct sockaddr_in sin;
10044    int callno;
10045    struct create_addr_info cai;
10046 
10047    memset(&cai, 0, sizeof(cai));
10048 
10049    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
10050 
10051    if (iax_provision_build(&provdata, &sig, template, force)) {
10052       ast_debug(1, "No provisioning found for template '%s'\n", template);
10053       return 0;
10054    }
10055 
10056    if (end) {
10057       memcpy(&sin, end, sizeof(sin));
10058       cai.sockfd = sockfd;
10059    } else if (create_addr(dest, NULL, &sin, &cai))
10060       return -1;
10061 
10062    /* Build the rest of the message */
10063    memset(&ied, 0, sizeof(ied));
10064    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10065 
10066    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10067    if (!callno)
10068       return -1;
10069 
10070    if (iaxs[callno]) {
10071       /* Schedule autodestruct in case they don't ever give us anything back */
10072       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
10073          sched, 15000, auto_hangup, (void *)(long)callno);
10074       ast_set_flag(iaxs[callno], IAX_PROVISION);
10075       /* Got a call number now, so go ahead and send the provisioning information */
10076       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10077    }
10078    ast_mutex_unlock(&iaxsl[callno]);
10079 
10080    return 1;
10081 }
10082 
10083 static char *papp = "IAX2Provision";
10084 static char *psyn = "Provision a calling IAXy with a given template";
10085 static char *pdescrip = 
10086 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
10087 "the calling entity is in fact an IAXy) with the given template or\n"
10088 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
10089 
10090 /*! iax2provision
10091 \ingroup applications
10092 */
10093 static int iax2_prov_app(struct ast_channel *chan, void *data)
10094 {
10095    int res;
10096    char *sdata;
10097    char *opts;
10098    int force =0;
10099    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
10100    if (ast_strlen_zero(data))
10101       data = "default";
10102    sdata = ast_strdupa(data);
10103    opts = strchr(sdata, '|');
10104    if (opts)
10105       *opts='\0';
10106 
10107    if (chan->tech != &iax2_tech) {
10108       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
10109       return -1;
10110    } 
10111    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
10112       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
10113       return -1;
10114    }
10115    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
10116    ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
10117       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
10118       sdata, res);
10119    return res;
10120 }
10121 
10122 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
10123 {
10124    int force = 0;
10125    int res;
10126 
10127    switch (cmd) {
10128    case CLI_INIT:
10129       e->command = "iax2 provision";
10130       e->usage = 
10131          "Usage: iax2 provision <host> <template> [forced]\n"
10132          "       Provisions the given peer or IP address using a template\n"
10133          "       matching either 'template' or '*' if the template is not\n"
10134          "       found.  If 'forced' is specified, even empty provisioning\n"
10135          "       fields will be provisioned as empty fields.\n";
10136       return NULL;
10137    case CLI_GENERATE:
10138       if (a->pos == 3)
10139          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
10140       return NULL;
10141    }
10142 
10143    if (a->argc < 4)
10144       return CLI_SHOWUSAGE;
10145    if (a->argc > 4) {
10146       if (!strcasecmp(a->argv[4], "forced"))
10147          force = 1;
10148       else
10149          return CLI_SHOWUSAGE;
10150    }
10151    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
10152    if (res < 0)
10153       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
10154    else if (res < 1)
10155       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
10156    else
10157       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
10158    return CLI_SUCCESS;
10159 }
10160 
10161 static void __iax2_poke_noanswer(const void *data)
10162 {
10163    struct iax2_peer *peer = (struct iax2_peer *)data;
10164    int callno;
10165 
10166    if (peer->lastms > -1) {
10167       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10168       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10169       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
10170    }
10171    if ((callno = peer->callno) > 0) {
10172       ast_mutex_lock(&iaxsl[callno]);
10173       iax2_destroy(callno);
10174       ast_mutex_unlock(&iaxsl[callno]);
10175    }
10176    peer->callno = 0;
10177    peer->lastms = -1;
10178    /* Try again quickly */
10179    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10180    if (peer->pokeexpire == -1)
10181       peer_unref(peer);
10182 }
10183 
10184 static int iax2_poke_noanswer(const void *data)
10185 {
10186    struct iax2_peer *peer = (struct iax2_peer *)data;
10187    peer->pokeexpire = -1;
10188 #ifdef SCHED_MULTITHREADED
10189    if (schedule_action(__iax2_poke_noanswer, data))
10190 #endif      
10191       __iax2_poke_noanswer(data);
10192    peer_unref(peer);
10193    return 0;
10194 }
10195 
10196 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
10197 {
10198    struct iax2_peer *peer = obj;
10199 
10200    iax2_poke_peer(peer, 0);
10201 
10202    return 0;
10203 }
10204 
10205 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
10206 {
10207    int callno;
10208    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10209       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
10210         immediately after clearing things out */
10211       peer->lastms = 0;
10212       peer->historicms = 0;
10213       peer->pokeexpire = -1;
10214       peer->callno = 0;
10215       return 0;
10216    }
10217 
10218    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
10219    if ((callno = peer->callno) > 0) {
10220       ast_log(LOG_NOTICE, "Still have a callno...\n");
10221       ast_mutex_lock(&iaxsl[callno]);
10222       iax2_destroy(callno);
10223       ast_mutex_unlock(&iaxsl[callno]);
10224    }
10225    if (heldcall)
10226       ast_mutex_unlock(&iaxsl[heldcall]);
10227    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10228    if (heldcall)
10229       ast_mutex_lock(&iaxsl[heldcall]);
10230    if (peer->callno < 1) {
10231       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10232       return -1;
10233    }
10234 
10235    /* Speed up retransmission times for this qualify call */
10236    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10237    iaxs[peer->callno]->peerpoke = peer;
10238 
10239    if (peer->pokeexpire > -1) {
10240       if (!ast_sched_del(sched, peer->pokeexpire)) {
10241          peer->pokeexpire = -1;
10242          peer_unref(peer);
10243       }
10244    }
10245  
10246    /* Queue up a new task to handle no reply */
10247    /* If the host is already unreachable then use the unreachable interval instead */
10248    if (peer->lastms < 0)
10249       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10250    else
10251       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10252 
10253    if (peer->pokeexpire == -1)
10254       peer_unref(peer);
10255 
10256    /* And send the poke */
10257    ast_mutex_lock(&iaxsl[callno]);
10258    if (iaxs[callno]) {
10259       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
10260    }
10261    ast_mutex_unlock(&iaxsl[callno]);
10262 
10263    return 0;
10264 }
10265 
10266 static void free_context(struct iax2_context *con)
10267 {
10268    struct iax2_context *conl;
10269    while(con) {
10270       conl = con;
10271       con = con->next;
10272       ast_free(conl);
10273    }
10274 }
10275 
10276 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
10277 {
10278    int callno;
10279    int res;
10280    int fmt, native;
10281    struct sockaddr_in sin;
10282    struct ast_channel *c;
10283    struct parsed_dial_string pds;
10284    struct create_addr_info cai;
10285    char *tmpstr;
10286 
10287    memset(&pds, 0, sizeof(pds));
10288    tmpstr = ast_strdupa(data);
10289    parse_dial_string(tmpstr, &pds);
10290 
10291    if (ast_strlen_zero(pds.peer)) {
10292       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10293       return NULL;
10294    }
10295           
10296    memset(&cai, 0, sizeof(cai));
10297    cai.capability = iax2_capability;
10298 
10299    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10300    
10301    /* Populate our address from the given */
10302    if (create_addr(pds.peer, NULL, &sin, &cai)) {
10303       *cause = AST_CAUSE_UNREGISTERED;
10304       return NULL;
10305    }
10306 
10307    if (pds.port)
10308       sin.sin_port = htons(atoi(pds.port));
10309 
10310    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10311    if (callno < 1) {
10312       ast_log(LOG_WARNING, "Unable to create call\n");
10313       *cause = AST_CAUSE_CONGESTION;
10314       return NULL;
10315    }
10316 
10317    /* If this is a trunk, update it now */
10318    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10319    if (ast_test_flag(&cai, IAX_TRUNK)) {
10320       int new_callno;
10321       if ((new_callno = make_trunk(callno, 1)) != -1)
10322          callno = new_callno;
10323    }
10324    iaxs[callno]->maxtime = cai.maxtime;
10325    if (cai.found)
10326       ast_string_field_set(iaxs[callno], host, pds.peer);
10327 
10328    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10329 
10330    ast_mutex_unlock(&iaxsl[callno]);
10331 
10332    if (c) {
10333       /* Choose a format we can live with */
10334       if (c->nativeformats & format) 
10335          c->nativeformats &= format;
10336       else {
10337          native = c->nativeformats;
10338          fmt = format;
10339          res = ast_translator_best_choice(&fmt, &native);
10340          if (res < 0) {
10341             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10342                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10343             ast_hangup(c);
10344             return NULL;
10345          }
10346          c->nativeformats = native;
10347       }
10348       c->readformat = ast_best_codec(c->nativeformats);
10349       c->writeformat = c->readformat;
10350    }
10351 
10352    return c;
10353 }
10354 
10355 static void *sched_thread(void *ignore)
10356 {
10357    int count;
10358    int res;
10359    struct timeval wait;
10360    struct timespec ts;
10361 
10362    for (;;) {
10363       pthread_testcancel();
10364       ast_mutex_lock(&sched_lock);
10365       res = ast_sched_wait(sched);
10366       if ((res > 1000) || (res < 0))
10367          res = 1000;
10368       wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
10369       ts.tv_sec = wait.tv_sec;
10370       ts.tv_nsec = wait.tv_usec * 1000;
10371       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10372       ast_mutex_unlock(&sched_lock);
10373       pthread_testcancel();
10374 
10375       count = ast_sched_runq(sched);
10376       if (count >= 20)
10377          ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10378    }
10379 
10380    return NULL;
10381 }
10382 
10383 static void *network_thread(void *ignore)
10384 {
10385    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
10386       from the network, and queue them for delivery to the channels */
10387    int res, count, wakeup;
10388    struct iax_frame *f;
10389 
10390    if (timer)
10391       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10392    
10393    for(;;) {
10394       pthread_testcancel();
10395 
10396       /* Go through the queue, sending messages which have not yet been
10397          sent, and scheduling retransmissions if appropriate */
10398       AST_LIST_LOCK(&frame_queue);
10399       count = 0;
10400       wakeup = -1;
10401       AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
10402          if (f->sentyet)
10403             continue;
10404          
10405          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
10406          if (ast_mutex_trylock(&iaxsl[f->callno])) {
10407             wakeup = 1;
10408             continue;
10409          }
10410 
10411          f->sentyet = 1;
10412 
10413          if (iaxs[f->callno]) {
10414             send_packet(f);
10415             count++;
10416          } 
10417 
10418          ast_mutex_unlock(&iaxsl[f->callno]);
10419 
10420          if (f->retries < 0) {
10421             /* This is not supposed to be retransmitted */
10422             AST_LIST_REMOVE_CURRENT(list);
10423             /* Free the iax frame */
10424             iax_frame_free(f);
10425          } else {
10426             /* We need reliable delivery.  Schedule a retransmission */
10427             f->retries++;
10428             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10429          }
10430       }
10431       AST_LIST_TRAVERSE_SAFE_END;
10432       AST_LIST_UNLOCK(&frame_queue);
10433 
10434       pthread_testcancel();
10435       if (count >= 20)
10436          ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10437 
10438       /* Now do the IO, and run scheduled tasks */
10439       res = ast_io_wait(io, wakeup);
10440       if (res >= 0) {
10441          if (res >= 20)
10442             ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10443       }
10444    }
10445    return NULL;
10446 }
10447 
10448 static int start_network_thread(void)
10449 {
10450    struct iax2_thread *thread;
10451    int threadcount = 0;
10452    int x;
10453    for (x = 0; x < iaxthreadcount; x++) {
10454       thread = ast_calloc(1, sizeof(*thread));
10455       if (thread) {
10456          thread->type = IAX_THREAD_TYPE_POOL;
10457          thread->threadnum = ++threadcount;
10458          ast_mutex_init(&thread->lock);
10459          ast_cond_init(&thread->cond, NULL);
10460          if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
10461             ast_log(LOG_WARNING, "Failed to create new thread!\n");
10462             ast_free(thread);
10463             thread = NULL;
10464          }
10465          AST_LIST_LOCK(&idle_list);
10466          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10467          AST_LIST_UNLOCK(&idle_list);
10468       }
10469    }
10470    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10471    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10472    ast_verb(2, "%d helper threads started\n", threadcount);
10473    return 0;
10474 }
10475 
10476 static struct iax2_context *build_context(const char *context)
10477 {
10478    struct iax2_context *con;
10479 
10480    if ((con = ast_calloc(1, sizeof(*con))))
10481       ast_copy_string(con->context, context, sizeof(con->context));
10482    
10483    return con;
10484 }
10485 
10486 static int get_auth_methods(const char *value)
10487 {
10488    int methods = 0;
10489    if (strstr(value, "rsa"))
10490       methods |= IAX_AUTH_RSA;
10491    if (strstr(value, "md5"))
10492       methods |= IAX_AUTH_MD5;
10493    if (strstr(value, "plaintext"))
10494       methods |= IAX_AUTH_PLAINTEXT;
10495    return methods;
10496 }
10497 
10498 
10499 /*! \brief Check if address can be used as packet source.
10500  \return 0  address available, 1  address unavailable, -1  error
10501 */
10502 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
10503 {
10504    int sd;
10505    int res;
10506    
10507    sd = socket(AF_INET, SOCK_DGRAM, 0);
10508    if (sd < 0) {
10509       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10510       return -1;
10511    }
10512 
10513    res = bind(sd, sa, salen);
10514    if (res < 0) {
10515       ast_debug(1, "Can't bind: %s\n", strerror(errno));
10516       close(sd);
10517       return 1;
10518    }
10519 
10520    close(sd);
10521    return 0;
10522 }
10523 
10524 /*! \brief Parse the "sourceaddress" value,
10525   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
10526   not found. */
10527 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
10528 {
10529    struct sockaddr_in sin;
10530    int nonlocal = 1;
10531    int port = IAX_DEFAULT_PORTNO;
10532    int sockfd = defaultsockfd;
10533    char *tmp;
10534    char *addr;
10535    char *portstr;
10536 
10537    if (!(tmp = ast_strdupa(srcaddr)))
10538       return -1;
10539 
10540    addr = strsep(&tmp, ":");
10541    portstr = tmp;
10542 
10543    if (portstr) {
10544       port = atoi(portstr);
10545       if (port < 1)
10546          port = IAX_DEFAULT_PORTNO;
10547    }
10548    
10549    if (!ast_get_ip(&sin, addr)) {
10550       struct ast_netsock *sock;
10551       int res;
10552 
10553       sin.sin_port = 0;
10554       sin.sin_family = AF_INET;
10555       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10556       if (res == 0) {
10557          /* ip address valid. */
10558          sin.sin_port = htons(port);
10559          if (!(sock = ast_netsock_find(netsock, &sin)))
10560             sock = ast_netsock_find(outsock, &sin);
10561          if (sock) {
10562             sockfd = ast_netsock_sockfd(sock);
10563             nonlocal = 0;
10564          } else {
10565             unsigned int orig_saddr = sin.sin_addr.s_addr;
10566             /* INADDR_ANY matches anyway! */
10567             sin.sin_addr.s_addr = INADDR_ANY;
10568             if (ast_netsock_find(netsock, &sin)) {
10569                sin.sin_addr.s_addr = orig_saddr;
10570                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
10571                if (sock) {
10572                   sockfd = ast_netsock_sockfd(sock);
10573                   ast_netsock_unref(sock);
10574                   nonlocal = 0;
10575                } else {
10576                   nonlocal = 2;
10577                }
10578             }
10579          }
10580       }
10581    }
10582       
10583    peer->sockfd = sockfd;
10584 
10585    if (nonlocal == 1) {
10586       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10587          srcaddr, peer->name);
10588       return -1;
10589         } else if (nonlocal == 2) {
10590       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10591          srcaddr, peer->name);
10592          return -1;
10593    } else {
10594       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10595       return 0;
10596    }
10597 }
10598 
10599 static void peer_destructor(void *obj)
10600 {
10601    struct iax2_peer *peer = obj;
10602    int callno = peer->callno;
10603 
10604    ast_free_ha(peer->ha);
10605 
10606    if (callno > 0) {
10607       ast_mutex_lock(&iaxsl[callno]);
10608       iax2_destroy(callno);
10609       ast_mutex_unlock(&iaxsl[callno]);
10610    }
10611 
10612    register_peer_exten(peer, 0);
10613 
10614    if (peer->dnsmgr)
10615       ast_dnsmgr_release(peer->dnsmgr);
10616 
10617    if (peer->mwi_event_sub)
10618       ast_event_unsubscribe(peer->mwi_event_sub);
10619 
10620    ast_string_field_free_memory(peer);
10621 }
10622 
10623 /*! \brief Create peer structure based on configuration */
10624 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10625 {
10626    struct iax2_peer *peer = NULL;
10627    struct ast_ha *oldha = NULL;
10628    int maskfound = 0;
10629    int found = 0;
10630    int firstpass = 1;
10631    struct iax2_peer tmp_peer = {
10632       .name = name,
10633    };
10634 
10635    if (!temponly) {
10636       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10637       if (peer && !ast_test_flag(peer, IAX_DELME))
10638          firstpass = 0;
10639    }
10640 
10641    if (peer) {
10642       found++;
10643       if (firstpass) {
10644          oldha = peer->ha;
10645          peer->ha = NULL;
10646       }
10647       unlink_peer(peer);
10648    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10649       peer->expire = -1;
10650       peer->pokeexpire = -1;
10651       peer->sockfd = defaultsockfd;
10652       if (ast_string_field_init(peer, 32))
10653          peer = peer_unref(peer);
10654    }
10655 
10656    if (peer) {
10657       if (firstpass) {
10658          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10659          peer->encmethods = iax2_encryption;
10660          peer->adsi = adsi;
10661          ast_string_field_set(peer,secret,"");
10662          if (!found) {
10663             ast_string_field_set(peer, name, name);
10664             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10665             peer->expiry = min_reg_expire;
10666          }
10667          peer->prefs = prefs;
10668          peer->capability = iax2_capability;
10669          peer->smoothing = 0;
10670          peer->pokefreqok = DEFAULT_FREQ_OK;
10671          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10672          ast_string_field_set(peer,context,"");
10673          ast_string_field_set(peer,peercontext,"");
10674          ast_clear_flag(peer, IAX_HASCALLERID);
10675          ast_string_field_set(peer, cid_name, "");
10676          ast_string_field_set(peer, cid_num, "");
10677       }
10678 
10679       if (!v) {
10680          v = alt;
10681          alt = NULL;
10682       }
10683       while(v) {
10684          if (!strcasecmp(v->name, "secret")) {
10685             ast_string_field_set(peer, secret, v->value);
10686          } else if (!strcasecmp(v->name, "mailbox")) {
10687             ast_string_field_set(peer, mailbox, v->value);
10688          } else if (!strcasecmp(v->name, "hasvoicemail")) {
10689             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10690                ast_string_field_set(peer, mailbox, name);
10691             }
10692          } else if (!strcasecmp(v->name, "mohinterpret")) {
10693             ast_string_field_set(peer, mohinterpret, v->value);
10694          } else if (!strcasecmp(v->name, "mohsuggest")) {
10695             ast_string_field_set(peer, mohsuggest, v->value);
10696          } else if (!strcasecmp(v->name, "dbsecret")) {
10697             ast_string_field_set(peer, dbsecret, v->value);
10698          } else if (!strcasecmp(v->name, "trunk")) {
10699             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
10700             if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
10701                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
10702                ast_clear_flag(peer, IAX_TRUNK);
10703             }
10704          } else if (!strcasecmp(v->name, "auth")) {
10705             peer->authmethods = get_auth_methods(v->value);
10706          } else if (!strcasecmp(v->name, "encryption")) {
10707             peer->encmethods |= get_encrypt_methods(v->value);
10708          } else if (!strcasecmp(v->name, "transfer")) {
10709             if (!strcasecmp(v->value, "mediaonly")) {
10710                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10711             } else if (ast_true(v->value)) {
10712                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10713             } else 
10714                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10715          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10716             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
10717          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10718             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
10719          } else if (!strcasecmp(v->name, "host")) {
10720             if (!strcasecmp(v->value, "dynamic")) {
10721                /* They'll register with us */
10722                ast_set_flag(peer, IAX_DYNAMIC); 
10723                if (!found) {
10724                   /* Initialize stuff iff we're not found, otherwise
10725                      we keep going with what we had */
10726                   memset(&peer->addr.sin_addr, 0, 4);
10727                   if (peer->addr.sin_port) {
10728                      /* If we've already got a port, make it the default rather than absolute */
10729                      peer->defaddr.sin_port = peer->addr.sin_port;
10730                      peer->addr.sin_port = 0;
10731                   }
10732                }
10733             } else {
10734                /* Non-dynamic.  Make sure we become that way if we're not */
10735                AST_SCHED_DEL(sched, peer->expire);
10736                ast_clear_flag(peer, IAX_DYNAMIC);
10737                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
10738                   return peer_unref(peer);
10739                if (!peer->addr.sin_port)
10740                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10741             }
10742             if (!maskfound)
10743                inet_aton("255.255.255.255", &peer->mask);
10744          } else if (!strcasecmp(v->name, "defaultip")) {
10745             if (ast_get_ip(&peer->defaddr, v->value))
10746                return peer_unref(peer);
10747          } else if (!strcasecmp(v->name, "sourceaddress")) {
10748             peer_set_srcaddr(peer, v->value);
10749          } else if (!strcasecmp(v->name, "permit") ||
10750                   !strcasecmp(v->name, "deny")) {
10751             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
10752          } else if (!strcasecmp(v->name, "mask")) {
10753             maskfound++;
10754             inet_aton(v->value, &peer->mask);
10755          } else if (!strcasecmp(v->name, "context")) {
10756             ast_string_field_set(peer, context, v->value);
10757          } else if (!strcasecmp(v->name, "regexten")) {
10758             ast_string_field_set(peer, regexten, v->value);
10759          } else if (!strcasecmp(v->name, "peercontext")) {
10760             ast_string_field_set(peer, peercontext, v->value);
10761          } else if (!strcasecmp(v->name, "port")) {
10762             if (ast_test_flag(peer, IAX_DYNAMIC))
10763                peer->defaddr.sin_port = htons(atoi(v->value));
10764             else
10765                peer->addr.sin_port = htons(atoi(v->value));
10766          } else if (!strcasecmp(v->name, "username")) {
10767             ast_string_field_set(peer, username, v->value);
10768          } else if (!strcasecmp(v->name, "allow")) {
10769             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10770          } else if (!strcasecmp(v->name, "disallow")) {
10771             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10772          } else if (!strcasecmp(v->name, "callerid")) {
10773             if (!ast_strlen_zero(v->value)) {
10774                char name2[80];
10775                char num2[80];
10776                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10777                ast_string_field_set(peer, cid_name, name2);
10778                ast_string_field_set(peer, cid_num, num2);
10779             } else {
10780                ast_string_field_set(peer, cid_name, "");
10781                ast_string_field_set(peer, cid_num, "");
10782             }
10783             ast_set_flag(peer, IAX_HASCALLERID);
10784          } else if (!strcasecmp(v->name, "fullname")) {
10785             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10786             ast_set_flag(peer, IAX_HASCALLERID);
10787          } else if (!strcasecmp(v->name, "cid_number")) {
10788             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10789             ast_set_flag(peer, IAX_HASCALLERID);
10790          } else if (!strcasecmp(v->name, "sendani")) {
10791             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
10792          } else if (!strcasecmp(v->name, "inkeys")) {
10793             ast_string_field_set(peer, inkeys, v->value);
10794          } else if (!strcasecmp(v->name, "outkey")) {
10795             ast_string_field_set(peer, outkey, v->value);
10796          } else if (!strcasecmp(v->name, "qualify")) {
10797             if (!strcasecmp(v->value, "no")) {
10798                peer->maxms = 0;
10799             } else if (!strcasecmp(v->value, "yes")) {
10800                peer->maxms = DEFAULT_MAXMS;
10801             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
10802                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);
10803                peer->maxms = 0;
10804             }
10805          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10806             peer->smoothing = ast_true(v->value);
10807          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10808             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
10809                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);
10810             }
10811          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10812             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
10813                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);
10814             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10815          } else if (!strcasecmp(v->name, "timezone")) {
10816             ast_string_field_set(peer, zonetag, v->value);
10817          } else if (!strcasecmp(v->name, "adsi")) {
10818             peer->adsi = ast_true(v->value);
10819          }/* else if (strcasecmp(v->name,"type")) */
10820          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10821          v = v->next;
10822          if (!v) {
10823             v = alt;
10824             alt = NULL;
10825          }
10826       }
10827       if (!peer->authmethods)
10828          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10829       ast_clear_flag(peer, IAX_DELME); 
10830       /* Make sure these are IPv4 addresses */
10831       peer->addr.sin_family = AF_INET;
10832    }
10833 
10834    if (oldha)
10835       ast_free_ha(oldha);
10836 
10837    if (!ast_strlen_zero(peer->mailbox)) {
10838       char *mailbox, *context;
10839       context = mailbox = ast_strdupa(peer->mailbox);
10840       strsep(&context, "@");
10841       if (ast_strlen_zero(context))
10842          context = "default";
10843       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
10844          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
10845          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
10846          AST_EVENT_IE_END);
10847    }
10848 
10849    return peer;
10850 }
10851 
10852 static void user_destructor(void *obj)
10853 {
10854    struct iax2_user *user = obj;
10855 
10856    ast_free_ha(user->ha);
10857    free_context(user->contexts);
10858    if(user->vars) {
10859       ast_variables_destroy(user->vars);
10860       user->vars = NULL;
10861    }
10862    ast_string_field_free_memory(user);
10863 }
10864 
10865 /*! \brief Create in-memory user structure from configuration */
10866 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10867 {
10868    struct iax2_user *user = NULL;
10869    struct iax2_context *con, *conl = NULL;
10870    struct ast_ha *oldha = NULL;
10871    struct iax2_context *oldcon = NULL;
10872    int format;
10873    int firstpass=1;
10874    int oldcurauthreq = 0;
10875    char *varname = NULL, *varval = NULL;
10876    struct ast_variable *tmpvar = NULL;
10877    struct iax2_user tmp_user = {
10878       .name = name,
10879    };
10880 
10881    if (!temponly) {
10882       user = ao2_find(users, &tmp_user, OBJ_POINTER);
10883       if (user && !ast_test_flag(user, IAX_DELME))
10884          firstpass = 0;
10885    }
10886 
10887    if (user) {
10888       if (firstpass) {
10889          oldcurauthreq = user->curauthreq;
10890          oldha = user->ha;
10891          oldcon = user->contexts;
10892          user->ha = NULL;
10893          user->contexts = NULL;
10894       }
10895       /* Already in the list, remove it and it will be added back (or FREE'd) */
10896       ao2_unlink(users, user);
10897    } else {
10898       user = ao2_alloc(sizeof(*user), user_destructor);
10899    }
10900    
10901    if (user) {
10902       if (firstpass) {
10903          ast_string_field_free_memory(user);
10904          memset(user, 0, sizeof(struct iax2_user));
10905          if (ast_string_field_init(user, 32)) {
10906             user = user_unref(user);
10907             goto cleanup;
10908          }
10909          user->maxauthreq = maxauthreq;
10910          user->curauthreq = oldcurauthreq;
10911          user->prefs = prefs;
10912          user->capability = iax2_capability;
10913          user->encmethods = iax2_encryption;
10914          user->adsi = adsi;
10915          ast_string_field_set(user, name, name);
10916          ast_string_field_set(user, language, language);
10917          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
10918          ast_clear_flag(user, IAX_HASCALLERID);
10919          ast_string_field_set(user, cid_name, "");
10920          ast_string_field_set(user, cid_num, "");
10921       }
10922       if (!v) {
10923          v = alt;
10924          alt = NULL;
10925       }
10926       while(v) {
10927          if (!strcasecmp(v->name, "context")) {
10928             con = build_context(v->value);
10929             if (con) {
10930                if (conl)
10931                   conl->next = con;
10932                else
10933                   user->contexts = con;
10934                conl = con;
10935             }
10936          } else if (!strcasecmp(v->name, "permit") ||
10937                   !strcasecmp(v->name, "deny")) {
10938             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
10939          } else if (!strcasecmp(v->name, "setvar")) {
10940             varname = ast_strdupa(v->value);
10941             if (varname && (varval = strchr(varname,'='))) {
10942                *varval = '\0';
10943                varval++;
10944                if((tmpvar = ast_variable_new(varname, varval, ""))) {
10945                   tmpvar->next = user->vars; 
10946                   user->vars = tmpvar;
10947                }
10948             }
10949          } else if (!strcasecmp(v->name, "allow")) {
10950             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10951          } else if (!strcasecmp(v->name, "disallow")) {
10952             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10953          } else if (!strcasecmp(v->name, "trunk")) {
10954             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
10955             if (ast_test_flag(user, IAX_TRUNK) && !timer) {
10956                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
10957                ast_clear_flag(user, IAX_TRUNK);
10958             }
10959          } else if (!strcasecmp(v->name, "auth")) {
10960             user->authmethods = get_auth_methods(v->value);
10961          } else if (!strcasecmp(v->name, "encryption")) {
10962             user->encmethods |= get_encrypt_methods(v->value);
10963          } else if (!strcasecmp(v->name, "transfer")) {
10964             if (!strcasecmp(v->value, "mediaonly")) {
10965                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10966             } else if (ast_true(v->value)) {
10967                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10968             } else 
10969                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10970          } else if (!strcasecmp(v->name, "codecpriority")) {
10971             if(!strcasecmp(v->value, "caller"))
10972                ast_set_flag(user, IAX_CODEC_USER_FIRST);
10973             else if(!strcasecmp(v->value, "disabled"))
10974                ast_set_flag(user, IAX_CODEC_NOPREFS);
10975             else if(!strcasecmp(v->value, "reqonly")) {
10976                ast_set_flag(user, IAX_CODEC_NOCAP);
10977                ast_set_flag(user, IAX_CODEC_NOPREFS);
10978             }
10979          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10980             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
10981          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10982             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
10983          } else if (!strcasecmp(v->name, "dbsecret")) {
10984             ast_string_field_set(user, dbsecret, v->value);
10985          } else if (!strcasecmp(v->name, "secret")) {
10986             if (!ast_strlen_zero(user->secret)) {
10987                char *old = ast_strdupa(user->secret);
10988 
10989                ast_string_field_build(user, secret, "%s;%s", old, v->value);
10990             } else
10991                ast_string_field_set(user, secret, v->value);
10992          } else if (!strcasecmp(v->name, "callerid")) {
10993             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
10994                char name2[80];
10995                char num2[80];
10996                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10997                ast_string_field_set(user, cid_name, name2);
10998                ast_string_field_set(user, cid_num, num2);
10999                ast_set_flag(user, IAX_HASCALLERID);
11000             } else {
11001                ast_clear_flag(user, IAX_HASCALLERID);
11002                ast_string_field_set(user, cid_name, "");
11003                ast_string_field_set(user, cid_num, "");
11004             }
11005          } else if (!strcasecmp(v->name, "fullname")) {
11006             if (!ast_strlen_zero(v->value)) {
11007                ast_string_field_set(user, cid_name, v->value);
11008                ast_set_flag(user, IAX_HASCALLERID);
11009             } else {
11010                ast_string_field_set(user, cid_name, "");
11011                if (ast_strlen_zero(user->cid_num))
11012                   ast_clear_flag(user, IAX_HASCALLERID);
11013             }
11014          } else if (!strcasecmp(v->name, "cid_number")) {
11015             if (!ast_strlen_zero(v->value)) {
11016                ast_string_field_set(user, cid_num, v->value);
11017                ast_set_flag(user, IAX_HASCALLERID);
11018             } else {
11019                ast_string_field_set(user, cid_num, "");
11020                if (ast_strlen_zero(user->cid_name))
11021                   ast_clear_flag(user, IAX_HASCALLERID);
11022             }
11023          } else if (!strcasecmp(v->name, "accountcode")) {
11024             ast_string_field_set(user, accountcode, v->value);
11025          } else if (!strcasecmp(v->name, "mohinterpret")) {
11026             ast_string_field_set(user, mohinterpret, v->value);
11027          } else if (!strcasecmp(v->name, "mohsuggest")) {
11028             ast_string_field_set(user, mohsuggest, v->value);
11029          } else if (!strcasecmp(v->name, "parkinglot")) {
11030             ast_string_field_set(user, parkinglot, v->value);
11031          } else if (!strcasecmp(v->name, "language")) {
11032             ast_string_field_set(user, language, v->value);
11033          } else if (!strcasecmp(v->name, "amaflags")) {
11034             format = ast_cdr_amaflags2int(v->value);
11035             if (format < 0) {
11036                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11037             } else {
11038                user->amaflags = format;
11039             }
11040          } else if (!strcasecmp(v->name, "inkeys")) {
11041             ast_string_field_set(user, inkeys, v->value);
11042          } else if (!strcasecmp(v->name, "maxauthreq")) {
11043             user->maxauthreq = atoi(v->value);
11044             if (user->maxauthreq < 0)
11045                user->maxauthreq = 0;
11046          } else if (!strcasecmp(v->name, "adsi")) {
11047             user->adsi = ast_true(v->value);
11048          }/* else if (strcasecmp(v->name,"type")) */
11049          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11050          v = v->next;
11051          if (!v) {
11052             v = alt;
11053             alt = NULL;
11054          }
11055       }
11056       if (!user->authmethods) {
11057          if (!ast_strlen_zero(user->secret)) {
11058             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11059             if (!ast_strlen_zero(user->inkeys))
11060                user->authmethods |= IAX_AUTH_RSA;
11061          } else if (!ast_strlen_zero(user->inkeys)) {
11062             user->authmethods = IAX_AUTH_RSA;
11063          } else {
11064             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11065          }
11066       }
11067       ast_clear_flag(user, IAX_DELME);
11068    }
11069 cleanup:
11070    if (oldha)
11071       ast_free_ha(oldha);
11072    if (oldcon)
11073       free_context(oldcon);
11074    return user;
11075 }
11076 
11077 static int peer_delme_cb(void *obj, void *arg, int flags)
11078 {
11079    struct iax2_peer *peer = obj;
11080 
11081    ast_set_flag(peer, IAX_DELME);
11082 
11083    return 0;
11084 }
11085 
11086 static int user_delme_cb(void *obj, void *arg, int flags)
11087 {
11088    struct iax2_user *user = obj;
11089 
11090    ast_set_flag(user, IAX_DELME);
11091 
11092    return 0;
11093 }
11094 
11095 static void delete_users(void)
11096 {
11097    struct iax2_registry *reg;
11098 
11099    ao2_callback(users, 0, user_delme_cb, NULL);
11100 
11101    AST_LIST_LOCK(&registrations);
11102    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
11103       AST_SCHED_DEL(sched, reg->expire);
11104       if (reg->callno) {
11105          int callno = reg->callno;
11106          ast_mutex_lock(&iaxsl[callno]);
11107          if (iaxs[callno]) {
11108             iaxs[callno]->reg = NULL;
11109             iax2_destroy(callno);
11110          }
11111          ast_mutex_unlock(&iaxsl[callno]);
11112       }
11113       if (reg->dnsmgr)
11114          ast_dnsmgr_release(reg->dnsmgr);
11115       ast_free(reg);
11116    }
11117    AST_LIST_UNLOCK(&registrations);
11118 
11119    ao2_callback(peers, 0, peer_delme_cb, NULL);
11120 }
11121 
11122 static void prune_users(void)
11123 {
11124    struct iax2_user *user;
11125    struct ao2_iterator i;
11126 
11127    i = ao2_iterator_init(users, 0);
11128    while ((user = ao2_iterator_next(&i))) {
11129       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11130          ao2_unlink(users, user);
11131       }
11132       user_unref(user);
11133    }
11134 }
11135 
11136 /* Prune peers who still are supposed to be deleted */
11137 static void prune_peers(void)
11138 {
11139    struct iax2_peer *peer;
11140    struct ao2_iterator i;
11141 
11142    i = ao2_iterator_init(peers, 0);
11143    while ((peer = ao2_iterator_next(&i))) {
11144       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11145          unlink_peer(peer);
11146       }
11147       peer_unref(peer);
11148    }
11149 }
11150 
11151 static void set_config_destroy(void)
11152 {
11153    strcpy(accountcode, "");
11154    strcpy(language, "");
11155    strcpy(mohinterpret, "default");
11156    strcpy(mohsuggest, "");
11157    global_max_trunk_mtu = MAX_TRUNK_MTU;
11158    trunkmaxsize = MAX_TRUNKDATA;
11159    amaflags = 0;
11160    delayreject = 0;
11161    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
11162    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11163    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
11164    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
11165    delete_users();
11166 }
11167 
11168 /*! \brief Load configuration */
11169 static int set_config(char *config_file, int reload)
11170 {
11171    struct ast_config *cfg, *ucfg;
11172    int capability=iax2_capability;
11173    struct ast_variable *v;
11174    char *cat;
11175    const char *utype;
11176    const char *tosval;
11177    int format;
11178    int portno = IAX_DEFAULT_PORTNO;
11179    int  x;
11180    int mtuv; 
11181    struct iax2_user *user;
11182    struct iax2_peer *peer;
11183    struct ast_netsock *ns;
11184    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11185 #if 0
11186    static unsigned short int last_port=0;
11187 #endif
11188 
11189    cfg = ast_config_load(config_file, config_flags);
11190 
11191    if (!cfg) {
11192       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11193       return -1;
11194    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
11195       ucfg = ast_config_load("users.conf", config_flags);
11196       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
11197          return 0;
11198       /* Otherwise we need to reread both files */
11199       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11200       cfg = ast_config_load(config_file, config_flags);
11201    } else { /* iax.conf changed, gotta reread users.conf, too */
11202       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11203       ucfg = ast_config_load("users.conf", config_flags);
11204    }
11205 
11206    if (reload) {
11207       set_config_destroy();
11208    }
11209 
11210    /* Reset global codec prefs */   
11211    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11212    
11213    /* Reset Global Flags */
11214    memset(&globalflags, 0, sizeof(globalflags));
11215    ast_set_flag(&globalflags, IAX_RTUPDATE);
11216    
11217    /* Turns on support for key rotation during encryption. */
11218    iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
11219 #ifdef SO_NO_CHECK
11220    nochecksums = 0;
11221 #endif
11222    /* Reset default parking lot */
11223    default_parkinglot[0] = '\0';
11224 
11225    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11226    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11227 
11228    maxauthreq = 3;
11229 
11230    srvlookup = 0;
11231 
11232    v = ast_variable_browse(cfg, "general");
11233 
11234    /* Seed initial tos value */
11235    tosval = ast_variable_retrieve(cfg, "general", "tos");
11236    if (tosval) {
11237       if (ast_str2tos(tosval, &qos.tos))
11238          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
11239    }
11240    /* Seed initial cos value */
11241    tosval = ast_variable_retrieve(cfg, "general", "cos");
11242    if (tosval) {
11243       if (ast_str2cos(tosval, &qos.cos))
11244          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
11245    }
11246    while(v) {
11247       if (!strcasecmp(v->name, "bindport")){ 
11248          if (reload)
11249             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11250          else
11251             portno = atoi(v->value);
11252       } else if (!strcasecmp(v->name, "pingtime")) 
11253          ping_time = atoi(v->value);
11254       else if (!strcasecmp(v->name, "iaxthreadcount")) {
11255          if (reload) {
11256             if (atoi(v->value) != iaxthreadcount)
11257                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11258          } else {
11259             iaxthreadcount = atoi(v->value);
11260             if (iaxthreadcount < 1) {
11261                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11262                iaxthreadcount = 1;
11263             } else if (iaxthreadcount > 256) {
11264                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11265                iaxthreadcount = 256;
11266             }
11267          }
11268       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11269          if (reload) {
11270             AST_LIST_LOCK(&dynamic_list);
11271             iaxmaxthreadcount = atoi(v->value);
11272             AST_LIST_UNLOCK(&dynamic_list);
11273          } else {
11274             iaxmaxthreadcount = atoi(v->value);
11275             if (iaxmaxthreadcount < 0) {
11276                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11277                iaxmaxthreadcount = 0;
11278             } else if (iaxmaxthreadcount > 256) {
11279                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11280                iaxmaxthreadcount = 256;
11281             }
11282          }
11283       } else if (!strcasecmp(v->name, "nochecksums")) {
11284 #ifdef SO_NO_CHECK
11285          if (ast_true(v->value))
11286             nochecksums = 1;
11287          else
11288             nochecksums = 0;
11289 #else
11290          if (ast_true(v->value))
11291             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11292 #endif
11293       }
11294       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
11295          maxjitterbuffer = atoi(v->value);
11296       else if (!strcasecmp(v->name, "resyncthreshold")) 
11297          resyncthreshold = atoi(v->value);
11298       else if (!strcasecmp(v->name, "maxjitterinterps")) 
11299          maxjitterinterps = atoi(v->value);
11300       else if (!strcasecmp(v->name, "jittertargetextra"))
11301          jittertargetextra = atoi(v->value);
11302       else if (!strcasecmp(v->name, "lagrqtime")) 
11303          lagrq_time = atoi(v->value);
11304       else if (!strcasecmp(v->name, "maxregexpire")) 
11305          max_reg_expire = atoi(v->value);
11306       else if (!strcasecmp(v->name, "minregexpire")) 
11307          min_reg_expire = atoi(v->value);
11308       else if (!strcasecmp(v->name, "bindaddr")) {
11309          if (reload) {
11310             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11311          } else {
11312             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
11313                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11314             } else {
11315                   if (strchr(v->value, ':'))
11316                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
11317                   else
11318                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
11319                if (defaultsockfd < 0) 
11320                   defaultsockfd = ast_netsock_sockfd(ns);
11321                ast_netsock_unref(ns);
11322             }
11323          }
11324       } else if (!strcasecmp(v->name, "authdebug"))
11325          authdebug = ast_true(v->value);
11326       else if (!strcasecmp(v->name, "encryption"))
11327          iax2_encryption |= get_encrypt_methods(v->value);
11328       else if (!strcasecmp(v->name, "transfer")) {
11329          if (!strcasecmp(v->value, "mediaonly")) {
11330             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
11331          } else if (ast_true(v->value)) {
11332             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11333          } else 
11334             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11335       } else if (!strcasecmp(v->name, "codecpriority")) {
11336          if(!strcasecmp(v->value, "caller"))
11337             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11338          else if(!strcasecmp(v->value, "disabled"))
11339             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11340          else if(!strcasecmp(v->value, "reqonly")) {
11341             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11342             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11343          }
11344       } else if (!strcasecmp(v->name, "jitterbuffer"))
11345          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
11346       else if (!strcasecmp(v->name, "forcejitterbuffer"))
11347          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
11348       else if (!strcasecmp(v->name, "delayreject"))
11349          delayreject = ast_true(v->value);
11350       else if (!strcasecmp(v->name, "allowfwdownload"))
11351          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11352       else if (!strcasecmp(v->name, "rtcachefriends"))
11353          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
11354       else if (!strcasecmp(v->name, "rtignoreregexpire"))
11355          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
11356       else if (!strcasecmp(v->name, "rtupdate"))
11357          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11358       else if (!strcasecmp(v->name, "trunktimestamps"))
11359          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11360       else if (!strcasecmp(v->name, "rtautoclear")) {
11361          int i = atoi(v->value);
11362          if(i > 0)
11363             global_rtautoclear = i;
11364          else
11365             i = 0;
11366          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
11367       } else if (!strcasecmp(v->name, "trunkfreq")) {
11368          trunkfreq = atoi(v->value);
11369          if (trunkfreq < 10)
11370             trunkfreq = 10;
11371       } else if (!strcasecmp(v->name, "trunkmtu")) {
11372          mtuv = atoi(v->value);
11373          if (mtuv  == 0 )  
11374             global_max_trunk_mtu = 0; 
11375          else if (mtuv >= 172 && mtuv < 4000) 
11376             global_max_trunk_mtu = mtuv; 
11377          else 
11378             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
11379                mtuv, v->lineno);
11380       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
11381          trunkmaxsize = atoi(v->value);
11382          if (trunkmaxsize == 0)
11383             trunkmaxsize = MAX_TRUNKDATA;
11384       } else if (!strcasecmp(v->name, "autokill")) {
11385          if (sscanf(v->value, "%d", &x) == 1) {
11386             if (x >= 0)
11387                autokill = x;
11388             else
11389                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11390          } else if (ast_true(v->value)) {
11391             autokill = DEFAULT_MAXMS;
11392          } else {
11393             autokill = 0;
11394          }
11395       } else if (!strcasecmp(v->name, "bandwidth")) {
11396          if (!strcasecmp(v->value, "low")) {
11397             capability = IAX_CAPABILITY_LOWBANDWIDTH;
11398          } else if (!strcasecmp(v->value, "medium")) {
11399             capability = IAX_CAPABILITY_MEDBANDWIDTH;
11400          } else if (!strcasecmp(v->value, "high")) {
11401             capability = IAX_CAPABILITY_FULLBANDWIDTH;
11402          } else
11403             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11404       } else if (!strcasecmp(v->name, "allow")) {
11405          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11406       } else if (!strcasecmp(v->name, "disallow")) {
11407          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11408       } else if (!strcasecmp(v->name, "register")) {
11409          iax2_register(v->value, v->lineno);
11410       } else if (!strcasecmp(v->name, "iaxcompat")) {
11411          iaxcompat = ast_true(v->value);
11412       } else if (!strcasecmp(v->name, "regcontext")) {
11413          ast_copy_string(regcontext, v->value, sizeof(regcontext));
11414          /* Create context if it doesn't exist already */
11415          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
11416       } else if (!strcasecmp(v->name, "tos")) {
11417          if (ast_str2tos(v->value, &qos.tos))
11418             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
11419       } else if (!strcasecmp(v->name, "cos")) {
11420          if (ast_str2cos(v->value, &qos.cos))
11421             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
11422       } else if (!strcasecmp(v->name, "parkinglot")) {
11423          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
11424       } else if (!strcasecmp(v->name, "accountcode")) {
11425          ast_copy_string(accountcode, v->value, sizeof(accountcode));
11426       } else if (!strcasecmp(v->name, "mohinterpret")) {
11427          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11428       } else if (!strcasecmp(v->name, "mohsuggest")) {
11429          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11430       } else if (!strcasecmp(v->name, "amaflags")) {
11431          format = ast_cdr_amaflags2int(v->value);
11432          if (format < 0) {
11433             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11434          } else {
11435             amaflags = format;
11436          }
11437       } else if (!strcasecmp(v->name, "language")) {
11438          ast_copy_string(language, v->value, sizeof(language));
11439       } else if (!strcasecmp(v->name, "maxauthreq")) {
11440          maxauthreq = atoi(v->value);
11441          if (maxauthreq < 0)
11442             maxauthreq = 0;
11443       } else if (!strcasecmp(v->name, "adsi")) {
11444          adsi = ast_true(v->value);
11445       } else if (!strcasecmp(v->name, "srvlookup")) {
11446          srvlookup = ast_true(v->value);
11447       } /*else if (strcasecmp(v->name,"type")) */
11448       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11449       v = v->next;
11450    }
11451    
11452    if (defaultsockfd < 0) {
11453       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
11454          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11455       } else {
11456          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11457          defaultsockfd = ast_netsock_sockfd(ns);
11458          ast_netsock_unref(ns);
11459       }
11460    }
11461    if (reload) {
11462       ast_netsock_release(outsock);
11463       outsock = ast_netsock_list_alloc();
11464       if (!outsock) {
11465          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11466          return -1;
11467       }
11468       ast_netsock_init(outsock);
11469    }
11470 
11471    if (min_reg_expire > max_reg_expire) {
11472       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11473          min_reg_expire, max_reg_expire, max_reg_expire);
11474       min_reg_expire = max_reg_expire;
11475    }
11476    iax2_capability = capability;
11477    
11478    if (ucfg) {
11479       struct ast_variable *gen;
11480       int genhasiax;
11481       int genregisteriax;
11482       const char *hasiax, *registeriax;
11483       
11484       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11485       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11486       gen = ast_variable_browse(ucfg, "general");
11487       cat = ast_category_browse(ucfg, NULL);
11488       while (cat) {
11489          if (strcasecmp(cat, "general")) {
11490             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11491             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11492             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11493                /* Start with general parameters, then specific parameters, user and peer */
11494                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11495                if (user) {
11496                   ao2_link(users, user);
11497                   user = user_unref(user);
11498                }
11499                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11500                if (peer) {
11501                   if (ast_test_flag(peer, IAX_DYNAMIC))
11502                      reg_source_db(peer);
11503                   ao2_link(peers, peer);
11504                   peer = peer_unref(peer);
11505                }
11506             }
11507             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11508                char tmp[256];
11509                const char *host = ast_variable_retrieve(ucfg, cat, "host");
11510                const char *username = ast_variable_retrieve(ucfg, cat, "username");
11511                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11512                if (!host)
11513                   host = ast_variable_retrieve(ucfg, "general", "host");
11514                if (!username)
11515                   username = ast_variable_retrieve(ucfg, "general", "username");
11516                if (!secret)
11517                   secret = ast_variable_retrieve(ucfg, "general", "secret");
11518                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11519                   if (!ast_strlen_zero(secret))
11520                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11521                   else
11522                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11523                   iax2_register(tmp, 0);
11524                }
11525             }
11526          }
11527          cat = ast_category_browse(ucfg, cat);
11528       }
11529       ast_config_destroy(ucfg);
11530    }
11531    
11532    cat = ast_category_browse(cfg, NULL);
11533    while(cat) {
11534       if (strcasecmp(cat, "general")) {
11535          utype = ast_variable_retrieve(cfg, cat, "type");
11536          if (utype) {
11537             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11538                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11539                if (user) {
11540                   ao2_link(users, user);
11541                   user = user_unref(user);
11542                }
11543             }
11544             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11545                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11546                if (peer) {
11547                   if (ast_test_flag(peer, IAX_DYNAMIC))
11548                      reg_source_db(peer);
11549                   ao2_link(peers, peer);
11550                   peer = peer_unref(peer);
11551                }
11552             } else if (strcasecmp(utype, "user")) {
11553                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11554             }
11555          } else
11556             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11557       }
11558       cat = ast_category_browse(cfg, cat);
11559    }
11560    ast_config_destroy(cfg);
11561    return 1;
11562 }
11563 
11564 static void poke_all_peers(void)
11565 {
11566    struct ao2_iterator i;
11567    struct iax2_peer *peer;
11568 
11569    i = ao2_iterator_init(peers, 0);
11570    while ((peer = ao2_iterator_next(&i))) {
11571       iax2_poke_peer(peer, 0);
11572       peer_unref(peer);
11573    }
11574 }
11575 static int reload_config(void)
11576 {
11577    char *config = "iax.conf";
11578    struct iax2_registry *reg;
11579 
11580    if (set_config(config, 1) > 0) {
11581       prune_peers();
11582       prune_users();
11583       trunk_timed = trunk_untimed = 0; 
11584       trunk_nmaxmtu = trunk_maxmtu = 0;
11585       memset(&debugaddr, '\0', sizeof(debugaddr));
11586 
11587       AST_LIST_LOCK(&registrations);
11588       AST_LIST_TRAVERSE(&registrations, reg, entry)
11589          iax2_do_register(reg);
11590       AST_LIST_UNLOCK(&registrations);
11591 
11592       /* Qualify hosts, too */
11593       poke_all_peers();
11594    }
11595    
11596    reload_firmware(0);
11597    iax_provision_reload(1);
11598    ast_unload_realtime("iaxpeers");
11599 
11600    return 0;
11601 }
11602 
11603 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11604 {
11605    switch (cmd) {
11606    case CLI_INIT:
11607       e->command = "iax2 reload";
11608       e->usage =
11609          "Usage: iax2 reload\n"
11610          "       Reloads IAX configuration from iax.conf\n";
11611       return NULL;
11612    case CLI_GENERATE:
11613       return NULL;
11614    }
11615 
11616    reload_config();
11617 
11618    return CLI_SUCCESS;
11619 }
11620 
11621 static int reload(void)
11622 {
11623    return reload_config();
11624 }
11625 
11626 static int cache_get_callno_locked(const char *data)
11627 {
11628    struct sockaddr_in sin;
11629    int x;
11630    int callno;
11631    struct iax_ie_data ied;
11632    struct create_addr_info cai;
11633    struct parsed_dial_string pds;
11634    char *tmpstr;
11635 
11636    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11637       /* Look for an *exact match* call.  Once a call is negotiated, it can only
11638          look up entries for a single context */
11639       if (!ast_mutex_trylock(&iaxsl[x])) {
11640          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11641             return x;
11642          ast_mutex_unlock(&iaxsl[x]);
11643       }
11644    }
11645 
11646    /* No match found, we need to create a new one */
11647 
11648    memset(&cai, 0, sizeof(cai));
11649    memset(&ied, 0, sizeof(ied));
11650    memset(&pds, 0, sizeof(pds));
11651 
11652    tmpstr = ast_strdupa(data);
11653    parse_dial_string(tmpstr, &pds);
11654 
11655    if (ast_strlen_zero(pds.peer)) {
11656       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11657       return -1;
11658    }
11659 
11660    /* Populate our address from the given */
11661    if (create_addr(pds.peer, NULL, &sin, &cai))
11662       return -1;
11663 
11664    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
11665       pds.peer, pds.username, pds.password, pds.context);
11666 
11667    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11668    if (callno < 1) {
11669       ast_log(LOG_WARNING, "Unable to create call\n");
11670       return -1;
11671    }
11672 
11673    ast_string_field_set(iaxs[callno], dproot, data);
11674    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11675 
11676    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11677    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11678    /* the string format is slightly different from a standard dial string,
11679       because the context appears in the 'exten' position
11680    */
11681    if (pds.exten)
11682       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11683    if (pds.username)
11684       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11685    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11686    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11687    /* Keep password handy */
11688    if (pds.password)
11689       ast_string_field_set(iaxs[callno], secret, pds.password);
11690    if (pds.key)
11691       ast_string_field_set(iaxs[callno], outkey, pds.key);
11692    /* Start the call going */
11693    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11694 
11695    return callno;
11696 }
11697 
11698 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
11699 {
11700    struct iax2_dpcache *dp = NULL;
11701    struct timeval now = ast_tvnow();
11702    int x, com[2], timeout, old = 0, outfd, doabort, callno;
11703    struct ast_channel *c = NULL;
11704    struct ast_frame *f = NULL;
11705 
11706    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
11707       if (ast_tvcmp(now, dp->expiry) > 0) {
11708          AST_LIST_REMOVE_CURRENT(cache_list);
11709          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
11710             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
11711          else
11712             ast_free(dp);
11713          continue;
11714       }
11715       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
11716          break;
11717    }
11718    AST_LIST_TRAVERSE_SAFE_END;
11719 
11720    if (!dp) {
11721       /* No matching entry.  Create a new one. */
11722       /* First, can we make a callno? */
11723       if ((callno = cache_get_callno_locked(data)) < 0) {
11724          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11725          return NULL;
11726       }
11727       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11728          ast_mutex_unlock(&iaxsl[callno]);
11729          return NULL;
11730       }
11731       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11732       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11733       dp->expiry = ast_tvnow();
11734       dp->orig = dp->expiry;
11735       /* Expires in 30 mins by default */
11736       dp->expiry.tv_sec += iaxdefaultdpcache;
11737       dp->flags = CACHE_FLAG_PENDING;
11738       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
11739          dp->waiters[x] = -1;
11740       /* Insert into the lists */
11741       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
11742       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
11743       /* Send the request if we're already up */
11744       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11745          iax2_dprequest(dp, callno);
11746       ast_mutex_unlock(&iaxsl[callno]);
11747    }
11748 
11749    /* By here we must have a dp */
11750    if (dp->flags & CACHE_FLAG_PENDING) {
11751       /* Okay, here it starts to get nasty.  We need a pipe now to wait
11752          for a reply to come back so long as it's pending */
11753       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11754          /* Find an empty slot */
11755          if (dp->waiters[x] < 0)
11756             break;
11757       }
11758       if (x >= ARRAY_LEN(dp->waiters)) {
11759          ast_log(LOG_WARNING, "No more waiter positions available\n");
11760          return NULL;
11761       }
11762       if (pipe(com)) {
11763          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11764          return NULL;
11765       }
11766       dp->waiters[x] = com[1];
11767       /* Okay, now we wait */
11768       timeout = iaxdefaulttimeout * 1000;
11769       /* Temporarily unlock */
11770       AST_LIST_UNLOCK(&dpcache);
11771       /* Defer any dtmf */
11772       if (chan)
11773          old = ast_channel_defer_dtmf(chan);
11774       doabort = 0;
11775       while(timeout) {
11776          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11777          if (outfd > -1)
11778             break;
11779          if (!c)
11780             continue;
11781          if (!(f = ast_read(c))) {
11782             doabort = 1;
11783             break;
11784          }
11785          ast_frfree(f);
11786       }
11787       if (!timeout) {
11788          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11789       }
11790       AST_LIST_LOCK(&dpcache);
11791       dp->waiters[x] = -1;
11792       close(com[1]);
11793       close(com[0]);
11794       if (doabort) {
11795          /* Don't interpret anything, just abort.  Not sure what th epoint
11796            of undeferring dtmf on a hung up channel is but hey whatever */
11797          if (!old && chan)
11798             ast_channel_undefer_dtmf(chan);
11799          return NULL;
11800       }
11801       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11802          /* Now to do non-independent analysis the results of our wait */
11803          if (dp->flags & CACHE_FLAG_PENDING) {
11804             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
11805                pending.  Don't let it take as long to timeout. */
11806             dp->flags &= ~CACHE_FLAG_PENDING;
11807             dp->flags |= CACHE_FLAG_TIMEOUT;
11808             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
11809                systems without leaving it unavailable once the server comes back online */
11810             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11811             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11812                if (dp->waiters[x] > -1) {
11813                   if (write(dp->waiters[x], "asdf", 4) < 0) {
11814                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11815                   }
11816                }
11817             }
11818          }
11819       }
11820       /* Our caller will obtain the rest */
11821       if (!old && chan)
11822          ast_channel_undefer_dtmf(chan);
11823    }
11824    return dp;  
11825 }
11826 
11827 /*! \brief Part of the IAX2 switch interface */
11828 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11829 {
11830    int res = 0;
11831    struct iax2_dpcache *dp = NULL;
11832 #if 0
11833    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11834 #endif
11835    if ((priority != 1) && (priority != 2))
11836       return 0;
11837 
11838    AST_LIST_LOCK(&dpcache);
11839    if ((dp = find_cache(chan, data, context, exten, priority))) {
11840       if (dp->flags & CACHE_FLAG_EXISTS)
11841          res = 1;
11842    } else {
11843       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11844    }
11845    AST_LIST_UNLOCK(&dpcache);
11846 
11847    return res;
11848 }
11849 
11850 /*! \brief part of the IAX2 dial plan switch interface */
11851 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11852 {
11853    int res = 0;
11854    struct iax2_dpcache *dp = NULL;
11855 #if 0
11856    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11857 #endif
11858    if ((priority != 1) && (priority != 2))
11859       return 0;
11860 
11861    AST_LIST_LOCK(&dpcache);
11862    if ((dp = find_cache(chan, data, context, exten, priority))) {
11863       if (dp->flags & CACHE_FLAG_CANEXIST)
11864          res = 1;
11865    } else {
11866       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11867    }
11868    AST_LIST_UNLOCK(&dpcache);
11869 
11870    return res;
11871 }
11872 
11873 /*! \brief Part of the IAX2 Switch interface */
11874 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11875 {
11876    int res = 0;
11877    struct iax2_dpcache *dp = NULL;
11878 #if 0
11879    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11880 #endif
11881    if ((priority != 1) && (priority != 2))
11882       return 0;
11883 
11884    AST_LIST_LOCK(&dpcache);
11885    if ((dp = find_cache(chan, data, context, exten, priority))) {
11886       if (dp->flags & CACHE_FLAG_MATCHMORE)
11887          res = 1;
11888    } else {
11889       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11890    }
11891    AST_LIST_UNLOCK(&dpcache);
11892 
11893    return res;
11894 }
11895 
11896 /*! \brief Execute IAX2 dialplan switch */
11897 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11898 {
11899    char odata[256];
11900    char req[256];
11901    char *ncontext;
11902    struct iax2_dpcache *dp = NULL;
11903    struct ast_app *dial = NULL;
11904 #if 0
11905    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);
11906 #endif
11907    if (priority == 2) {
11908       /* Indicate status, can be overridden in dialplan */
11909       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11910       if (dialstatus) {
11911          dial = pbx_findapp(dialstatus);
11912          if (dial) 
11913             pbx_exec(chan, dial, "");
11914       }
11915       return -1;
11916    } else if (priority != 1)
11917       return -1;
11918 
11919    AST_LIST_LOCK(&dpcache);
11920    if ((dp = find_cache(chan, data, context, exten, priority))) {
11921       if (dp->flags & CACHE_FLAG_EXISTS) {
11922          ast_copy_string(odata, data, sizeof(odata));
11923          ncontext = strchr(odata, '/');
11924          if (ncontext) {
11925             *ncontext = '\0';
11926             ncontext++;
11927             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11928          } else {
11929             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11930          }
11931          ast_verb(3, "Executing Dial('%s')\n", req);
11932       } else {
11933          AST_LIST_UNLOCK(&dpcache);
11934          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11935          return -1;
11936       }
11937    }
11938    AST_LIST_UNLOCK(&dpcache);
11939 
11940    if ((dial = pbx_findapp("Dial")))
11941       return pbx_exec(chan, dial, req);
11942    else
11943       ast_log(LOG_WARNING, "No dial application registered\n");
11944 
11945    return -1;
11946 }
11947 
11948 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
11949 {
11950    struct iax2_peer *peer;
11951    char *peername, *colname;
11952 
11953    peername = ast_strdupa(data);
11954 
11955    /* if our channel, return the IP address of the endpoint of current channel */
11956    if (!strcmp(peername,"CURRENTCHANNEL")) {
11957            unsigned short callno;
11958       if (chan->tech != &iax2_tech)
11959          return -1;
11960       callno = PTR_TO_CALLNO(chan->tech_pvt);   
11961       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
11962       return 0;
11963    }
11964 
11965    if ((colname = strchr(peername, ',')))
11966       *colname++ = '\0';
11967    else
11968       colname = "ip";
11969 
11970    if (!(peer = find_peer(peername, 1)))
11971       return -1;
11972 
11973    if (!strcasecmp(colname, "ip")) {
11974       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11975    } else  if (!strcasecmp(colname, "status")) {
11976       peer_status(peer, buf, len); 
11977    } else  if (!strcasecmp(colname, "mailbox")) {
11978       ast_copy_string(buf, peer->mailbox, len);
11979    } else  if (!strcasecmp(colname, "context")) {
11980       ast_copy_string(buf, peer->context, len);
11981    } else  if (!strcasecmp(colname, "expire")) {
11982       snprintf(buf, len, "%d", peer->expire);
11983    } else  if (!strcasecmp(colname, "dynamic")) {
11984       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
11985    } else  if (!strcasecmp(colname, "callerid_name")) {
11986       ast_copy_string(buf, peer->cid_name, len);
11987    } else  if (!strcasecmp(colname, "callerid_num")) {
11988       ast_copy_string(buf, peer->cid_num, len);
11989    } else  if (!strcasecmp(colname, "codecs")) {
11990       ast_getformatname_multiple(buf, len -1, peer->capability);
11991    } else  if (!strncasecmp(colname, "codec[", 6)) {
11992       char *codecnum, *ptr;
11993       int codec = 0;
11994       
11995       codecnum = strchr(colname, '[');
11996       *codecnum = '\0';
11997       codecnum++;
11998       if ((ptr = strchr(codecnum, ']'))) {
11999          *ptr = '\0';
12000       }
12001       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
12002          ast_copy_string(buf, ast_getformatname(codec), len);
12003       } else {
12004          buf[0] = '\0';
12005       }
12006    } else {
12007       buf[0] = '\0';
12008    }
12009 
12010    peer_unref(peer);
12011 
12012    return 0;
12013 }
12014 
12015 struct ast_custom_function iaxpeer_function = {
12016    .name = "IAXPEER",
12017    .synopsis = "Gets IAX peer information",
12018    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
12019    .read = function_iaxpeer,
12020    .desc = "If peername specified, valid items are:\n"
12021    "- ip (default)          The IP address.\n"
12022    "- status                The peer's status (if qualify=yes)\n"
12023    "- mailbox               The configured mailbox.\n"
12024    "- context               The configured context.\n"
12025    "- expire                The epoch time of the next expire.\n"
12026    "- dynamic               Is it dynamic? (yes/no).\n"
12027    "- callerid_name         The configured Caller ID name.\n"
12028    "- callerid_num          The configured Caller ID number.\n"
12029    "- codecs                The configured codecs.\n"
12030    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
12031    "\n"
12032    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
12033    "\n"
12034 };
12035 
12036 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
12037 {
12038    struct chan_iax2_pvt *pvt;
12039    unsigned int callno;
12040    int res = 0;
12041 
12042    if (!chan || chan->tech != &iax2_tech) {
12043       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12044       return -1;
12045    }
12046 
12047    callno = PTR_TO_CALLNO(chan->tech_pvt);
12048    ast_mutex_lock(&iaxsl[callno]);
12049    if (!(pvt = iaxs[callno])) {
12050       ast_mutex_unlock(&iaxsl[callno]);
12051       return -1;
12052    }
12053 
12054    if (!strcasecmp(args, "osptoken"))
12055       ast_string_field_set(pvt, osptoken, value);
12056    else
12057       res = -1;
12058 
12059    ast_mutex_unlock(&iaxsl[callno]);
12060 
12061    return res;
12062 }
12063 
12064 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
12065 {
12066    struct chan_iax2_pvt *pvt;
12067    unsigned int callno;
12068    int res = 0;
12069 
12070    if (!chan || chan->tech != &iax2_tech) {
12071       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12072       return -1;
12073    }
12074 
12075    callno = PTR_TO_CALLNO(chan->tech_pvt);
12076    ast_mutex_lock(&iaxsl[callno]);
12077    if (!(pvt = iaxs[callno])) {
12078       ast_mutex_unlock(&iaxsl[callno]);
12079       return -1;
12080    }
12081 
12082    if (!strcasecmp(args, "osptoken")) {
12083       ast_copy_string(buf, pvt->osptoken, buflen);
12084    } else if (!strcasecmp(args, "peerip")) {
12085       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
12086    } else if (!strcasecmp(args, "peername")) {
12087       ast_copy_string(buf, pvt->username, buflen);
12088    } else {
12089       res = -1;
12090    }
12091 
12092    ast_mutex_unlock(&iaxsl[callno]);
12093 
12094    return res;
12095 }
12096 
12097 /*! \brief Part of the device state notification system ---*/
12098 static int iax2_devicestate(void *data) 
12099 {
12100    struct parsed_dial_string pds;
12101    char *tmp = ast_strdupa(data);
12102    struct iax2_peer *p;
12103    int res = AST_DEVICE_INVALID;
12104 
12105    memset(&pds, 0, sizeof(pds));
12106    parse_dial_string(tmp, &pds);
12107 
12108    if (ast_strlen_zero(pds.peer)) {
12109       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12110       return res;
12111    }
12112    
12113    ast_debug(3, "Checking device state for device %s\n", pds.peer);
12114 
12115    /* SLD: FIXME: second call to find_peer during registration */
12116    if (!(p = find_peer(pds.peer, 1)))
12117       return res;
12118 
12119    res = AST_DEVICE_UNAVAILABLE;
12120    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12121       pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12122    
12123    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12124        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12125       /* Peer is registered, or have default IP address
12126          and a valid registration */
12127       if (p->historicms == 0 || p->historicms <= p->maxms)
12128          /* let the core figure out whether it is in use or not */
12129          res = AST_DEVICE_UNKNOWN;  
12130    }
12131 
12132    peer_unref(p);
12133 
12134    return res;
12135 }
12136 
12137 static struct ast_switch iax2_switch = 
12138 {
12139    name:        "IAX2",
12140    description: "IAX Remote Dialplan Switch",
12141    exists:      iax2_exists,
12142    canmatch:    iax2_canmatch,
12143    exec:        iax2_exec,
12144    matchmore:   iax2_matchmore,
12145 };
12146 
12147 /*
12148    { { "iax2", "show", "cache", NULL },
12149    iax2_show_cache, "Display IAX cached dialplan",
12150    show_cache_usage },
12151 
12152    { { "iax2", "show", "channels", NULL },
12153    iax2_show_channels, "List active IAX channels",
12154    show_channels_usage },
12155 
12156    { { "iax2", "show", "firmware", NULL },
12157    iax2_show_firmware, "List available IAX firmwares",
12158    show_firmware_usage },
12159 
12160    { { "iax2", "show", "netstats", NULL },
12161    iax2_show_netstats, "List active IAX channel netstats",
12162    show_netstats_usage },
12163 
12164    { { "iax2", "show", "peers", NULL },
12165    iax2_show_peers, "List defined IAX peers",
12166    show_peers_usage },
12167 
12168    { { "iax2", "show", "registry", NULL },
12169    iax2_show_registry, "Display IAX registration status",
12170    show_reg_usage },
12171 
12172    { { "iax2", "show", "stats", NULL },
12173    iax2_show_stats, "Display IAX statistics",
12174    show_stats_usage },
12175 
12176    { { "iax2", "show", "threads", NULL },
12177    iax2_show_threads, "Display IAX helper thread info",
12178    show_threads_usage },
12179 
12180    { { "iax2", "unregister", NULL },
12181    iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry",
12182    unregister_usage, complete_iax2_unregister },
12183 
12184    { { "iax2", "set", "mtu", NULL },
12185    iax2_set_mtu, "Set the IAX systemwide trunking MTU",
12186    set_mtu_usage, NULL, NULL },
12187 
12188    { { "iax2", "show", "users", NULL },
12189    iax2_show_users, "List defined IAX users",
12190    show_users_usage },
12191 
12192    { { "iax2", "prune", "realtime", NULL },
12193    iax2_prune_realtime, "Prune a cached realtime lookup",
12194    prune_realtime_usage, complete_iax2_show_peer },
12195 
12196    { { "iax2", "reload", NULL },
12197    iax2_reload, "Reload IAX configuration",
12198    iax2_reload_usage },
12199 
12200    { { "iax2", "show", "peer", NULL },
12201    iax2_show_peer, "Show details on specific IAX peer",
12202    show_peer_usage, complete_iax2_show_peer },
12203 
12204    { { "iax2", "set", "debug", NULL },
12205    iax2_do_debug, "Enable IAX debugging",
12206    debug_usage },
12207 
12208    { { "iax2", "set", "debug", "trunk", NULL },
12209    iax2_do_trunk_debug, "Enable IAX trunk debugging",
12210    debug_trunk_usage },
12211 
12212    { { "iax2", "set", "debug", "jb", NULL },
12213    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
12214    debug_jb_usage },
12215 
12216    { { "iax2", "set", "debug", "off", NULL },
12217    iax2_no_debug, "Disable IAX debugging",
12218    no_debug_usage },
12219 
12220    { { "iax2", "set", "debug", "trunk", "off", NULL },
12221    iax2_no_trunk_debug, "Disable IAX trunk debugging",
12222    no_debug_trunk_usage },
12223 
12224    { { "iax2", "set", "debug", "jb", "off", NULL },
12225    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
12226    no_debug_jb_usage },
12227 
12228    { { "iax2", "test", "losspct", NULL },
12229    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
12230    iax2_test_losspct_usage },
12231 
12232    { { "iax2", "provision", NULL },
12233    iax2_prov_cmd, "Provision an IAX device",
12234    show_prov_usage, iax2_prov_complete_template_3rd },
12235 
12236 #ifdef IAXTESTS
12237    { { "iax2", "test", "late", NULL },
12238    iax2_test_late, "Test the receipt of a late frame",
12239    iax2_test_late_usage },
12240 
12241    { { "iax2", "test", "resync", NULL },
12242    iax2_test_resync, "Test a resync in received timestamps",
12243    iax2_test_resync_usage },
12244 
12245    { { "iax2", "test", "jitter", NULL },
12246    iax2_test_jitter, "Simulates jitter for testing",
12247    iax2_test_jitter_usage },
12248 #endif
12249 */
12250 
12251 static struct ast_cli_entry cli_iax2[] = {
12252    AST_CLI_DEFINE(handle_cli_iax2_provision,           "Provision an IAX device"),
12253    AST_CLI_DEFINE(handle_cli_iax2_prune_realtime,      "Prune a cached realtime lookup"),
12254    AST_CLI_DEFINE(handle_cli_iax2_reload,              "Reload IAX configuration"),
12255    AST_CLI_DEFINE(handle_cli_iax2_set_mtu,             "Set the IAX systemwide trunking MTU"),
12256    AST_CLI_DEFINE(handle_cli_iax2_set_debug,           "Enable/Disable IAX debugging"),
12257    AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk,     "Enable/Disable IAX trunk debugging"),
12258    AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb,        "Enable/Disable IAX jitterbuffer debugging"),
12259    AST_CLI_DEFINE(handle_cli_iax2_show_cache,          "Display IAX cached dialplan"),
12260    AST_CLI_DEFINE(handle_cli_iax2_show_channels,       "List active IAX channels"),
12261    AST_CLI_DEFINE(handle_cli_iax2_show_firmware,       "List available IAX firmware"),
12262    AST_CLI_DEFINE(handle_cli_iax2_show_netstats,       "List active IAX channel netstats"),
12263    AST_CLI_DEFINE(handle_cli_iax2_show_peer,           "Show details on specific IAX peer"),
12264    AST_CLI_DEFINE(handle_cli_iax2_show_peers,          "List defined IAX peers"),
12265    AST_CLI_DEFINE(handle_cli_iax2_show_registry,       "Display IAX registration status"),
12266    AST_CLI_DEFINE(handle_cli_iax2_show_stats,          "Display IAX statistics"),
12267    AST_CLI_DEFINE(handle_cli_iax2_show_threads,        "Display IAX helper thread info"),
12268    AST_CLI_DEFINE(handle_cli_iax2_show_users,          "List defined IAX users"),
12269    AST_CLI_DEFINE(handle_cli_iax2_test_losspct,        "Set IAX2 incoming frame loss percentage"),
12270    AST_CLI_DEFINE(handle_cli_iax2_unregister,          "Unregister (force expiration) an IAX2 peer from the registry"),
12271 #ifdef IAXTESTS
12272    AST_CLI_DEFINE(handle_cli_iax2_test_jitter,         "Simulates jitter for testing"),
12273    AST_CLI_DEFINE(handle_cli_iax2_test_late,           "Test the receipt of a late frame"),
12274    AST_CLI_DEFINE(handle_cli_iax2_test_resync,         "Test a resync in received timestamps"),
12275 #endif /* IAXTESTS */
12276 };
12277 
12278 static int __unload_module(void)
12279 {
12280    struct iax2_thread *thread = NULL;
12281    struct ast_context *con;
12282    int x;
12283 
12284    /* Make sure threads do not hold shared resources when they are canceled */
12285    
12286    /* Grab the sched lock resource to keep it away from threads about to die */
12287    /* Cancel the network thread, close the net socket */
12288    if (netthreadid != AST_PTHREADT_NULL) {
12289       AST_LIST_LOCK(&frame_queue);
12290       ast_mutex_lock(&sched_lock);
12291       pthread_cancel(netthreadid);
12292       ast_cond_signal(&sched_cond);
12293       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
12294       AST_LIST_UNLOCK(&frame_queue);
12295       pthread_join(netthreadid, NULL);
12296    }
12297    if (schedthreadid != AST_PTHREADT_NULL) {
12298       ast_mutex_lock(&sched_lock);
12299       pthread_cancel(schedthreadid);
12300       ast_cond_signal(&sched_cond);
12301       ast_mutex_unlock(&sched_lock);
12302       pthread_join(schedthreadid, NULL);
12303    }
12304 
12305    /* Call for all threads to halt */
12306    AST_LIST_LOCK(&idle_list);
12307    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
12308       pthread_cancel(thread->threadid);
12309    AST_LIST_UNLOCK(&idle_list);
12310 
12311    AST_LIST_LOCK(&active_list);
12312    while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
12313       pthread_cancel(thread->threadid);
12314    AST_LIST_UNLOCK(&active_list);
12315 
12316    AST_LIST_LOCK(&dynamic_list);
12317    while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
12318       pthread_cancel(thread->threadid);
12319    AST_LIST_UNLOCK(&dynamic_list);
12320    
12321    /* Wait for threads to exit */
12322    while(0 < iaxactivethreadcount)
12323       usleep(10000);
12324    
12325    ast_netsock_release(netsock);
12326    ast_netsock_release(outsock);
12327    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12328       if (iaxs[x]) {
12329          iax2_destroy(x);
12330       }
12331    }
12332    ast_manager_unregister( "IAXpeers" );
12333    ast_manager_unregister( "IAXpeerlist" );
12334    ast_manager_unregister( "IAXnetstats" );
12335    ast_unregister_application(papp);
12336    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12337    ast_unregister_switch(&iax2_switch);
12338    ast_channel_unregister(&iax2_tech);
12339    delete_users();
12340    iax_provision_unload();
12341    sched_context_destroy(sched);
12342    reload_firmware(1);
12343 
12344    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12345       ast_mutex_destroy(&iaxsl[x]);
12346    }
12347 
12348    ao2_ref(peers, -1);
12349    ao2_ref(users, -1);
12350    ao2_ref(iax_peercallno_pvts, -1);
12351    ao2_ref(iax_transfercallno_pvts, -1);
12352    if (timer) {
12353       ast_timer_close(timer);
12354    }
12355 
12356    con = ast_context_find(regcontext);
12357    if (con)
12358       ast_context_destroy(con, "IAX2");
12359    ast_unload_realtime("iaxpeers");
12360    return 0;
12361 }
12362 
12363 static int unload_module(void)
12364 {
12365    ast_custom_function_unregister(&iaxpeer_function);
12366    ast_custom_function_unregister(&iaxvar_function);
12367    return __unload_module();
12368 }
12369 
12370 static int peer_set_sock_cb(void *obj, void *arg, int flags)
12371 {
12372    struct iax2_peer *peer = obj;
12373 
12374    if (peer->sockfd < 0)
12375       peer->sockfd = defaultsockfd;
12376 
12377    return 0;
12378 }
12379 
12380 static int pvt_hash_cb(const void *obj, const int flags)
12381 {
12382    const struct chan_iax2_pvt *pvt = obj;
12383 
12384    return pvt->peercallno;
12385 }
12386 
12387 static int pvt_cmp_cb(void *obj, void *arg, int flags)
12388 {
12389    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12390 
12391    /* The frames_received field is used to hold whether we're matching
12392     * against a full frame or not ... */
12393 
12394    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
12395       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12396 }
12397 
12398 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
12399 {
12400    const struct chan_iax2_pvt *pvt = obj;
12401 
12402    return pvt->transfercallno;
12403 }
12404 
12405 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
12406 {
12407    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12408 
12409    /* The frames_received field is used to hold whether we're matching
12410     * against a full frame or not ... */
12411 
12412    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12413       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12414 }
12415 /*! \brief Load IAX2 module, load configuraiton ---*/
12416 static int load_module(void)
12417 {
12418    char *config = "iax.conf";
12419    int x = 0;
12420    struct iax2_registry *reg = NULL;
12421 
12422    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
12423    if (!peers)
12424       return AST_MODULE_LOAD_FAILURE;
12425    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
12426    if (!users) {
12427       ao2_ref(peers, -1);
12428       return AST_MODULE_LOAD_FAILURE;
12429    }
12430    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
12431    if (!iax_peercallno_pvts) {
12432       ao2_ref(peers, -1);
12433       ao2_ref(users, -1);
12434       return AST_MODULE_LOAD_FAILURE;
12435    }
12436    iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
12437    if (!iax_transfercallno_pvts) {
12438       ao2_ref(peers, -1);
12439       ao2_ref(users, -1);
12440       ao2_ref(iax_peercallno_pvts, -1);
12441       return AST_MODULE_LOAD_FAILURE;
12442    }
12443    ast_custom_function_register(&iaxpeer_function);
12444    ast_custom_function_register(&iaxvar_function);
12445 
12446    iax_set_output(iax_debug_output);
12447    iax_set_error(iax_error_output);
12448    jb_setoutput(jb_error_output, jb_warning_output, NULL);
12449 
12450    memset(iaxs, 0, sizeof(iaxs));
12451 
12452    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12453       ast_mutex_init(&iaxsl[x]);
12454    }
12455 
12456    ast_cond_init(&sched_cond, NULL);
12457 
12458    if (!(sched = sched_context_create())) {
12459       ast_log(LOG_ERROR, "Failed to create scheduler context\n");
12460       return AST_MODULE_LOAD_FAILURE;
12461    }
12462 
12463    if (!(io = io_context_create())) {
12464       ast_log(LOG_ERROR, "Failed to create I/O context\n");
12465       sched_context_destroy(sched);
12466       return AST_MODULE_LOAD_FAILURE;
12467    }
12468 
12469    if (!(netsock = ast_netsock_list_alloc())) {
12470       ast_log(LOG_ERROR, "Failed to create netsock list\n");
12471       io_context_destroy(io);
12472       sched_context_destroy(sched);
12473       return AST_MODULE_LOAD_FAILURE;
12474    }
12475    ast_netsock_init(netsock);
12476    
12477    outsock = ast_netsock_list_alloc();
12478    if (!outsock) {
12479       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12480       io_context_destroy(io);
12481       sched_context_destroy(sched);
12482       return AST_MODULE_LOAD_FAILURE;
12483    }
12484    ast_netsock_init(outsock);
12485 
12486    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12487 
12488    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12489    
12490    ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
12491    ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
12492    ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
12493 
12494    if ((timer = ast_timer_open())) {
12495       ast_timer_set_rate(timer, trunkfreq);
12496    }
12497 
12498    if (set_config(config, 0) == -1) {
12499       return AST_MODULE_LOAD_DECLINE;
12500    }
12501 
12502    if (ast_channel_register(&iax2_tech)) {
12503       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12504       __unload_module();
12505       return AST_MODULE_LOAD_FAILURE;
12506    }
12507 
12508    if (ast_register_switch(&iax2_switch)) 
12509       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12510 
12511    if (start_network_thread()) {
12512       ast_log(LOG_ERROR, "Unable to start network thread\n");
12513       __unload_module();
12514       return AST_MODULE_LOAD_FAILURE;
12515    } else
12516       ast_verb(2, "IAX Ready and Listening\n");
12517 
12518    AST_LIST_LOCK(&registrations);
12519    AST_LIST_TRAVERSE(&registrations, reg, entry)
12520       iax2_do_register(reg);
12521    AST_LIST_UNLOCK(&registrations); 
12522    
12523    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12524    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12525 
12526 
12527    reload_firmware(0);
12528    iax_provision_reload(0);
12529 
12530    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
12531 
12532    return AST_MODULE_LOAD_SUCCESS;
12533 }
12534 
12535 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
12536       .load = load_module,
12537       .unload = unload_module,
12538       .reload = reload,
12539       );

Generated on Fri Jul 24 00:40:48 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7