Thu Jul 9 13:40:26 2009

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>dahdi</use>
00033    <use>crypto</use>
00034  ***/
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 201997 $")
00039 
00040 #include <sys/mman.h>
00041 #include <dirent.h>
00042 #include <sys/socket.h>
00043 #include <netinet/in.h>
00044 #include <arpa/inet.h>
00045 #include <netinet/in_systm.h>
00046 #include <netinet/ip.h>
00047 #include <sys/time.h>
00048 #include <sys/signal.h>
00049 #include <signal.h>
00050 #include <strings.h>
00051 #include <netdb.h>
00052 #include <fcntl.h>
00053 #include <sys/stat.h>
00054 #include <regex.h>
00055 #include <sys/ioctl.h>
00056 #if defined(HAVE_DAHDI)
00057 #include <dahdi/user.h>
00058 #endif
00059 
00060 #include "asterisk/paths.h"   /* need ast_config_AST_DATA_DIR for firmware */
00061 
00062 #include "asterisk/lock.h"
00063 #include "asterisk/frame.h" 
00064 #include "asterisk/channel.h"
00065 #include "asterisk/module.h"
00066 #include "asterisk/pbx.h"
00067 #include "asterisk/sched.h"
00068 #include "asterisk/io.h"
00069 #include "asterisk/config.h"
00070 #include "asterisk/cli.h"
00071 #include "asterisk/translate.h"
00072 #include "asterisk/md5.h"
00073 #include "asterisk/cdr.h"
00074 #include "asterisk/crypto.h"
00075 #include "asterisk/acl.h"
00076 #include "asterisk/manager.h"
00077 #include "asterisk/callerid.h"
00078 #include "asterisk/app.h"
00079 #include "asterisk/astdb.h"
00080 #include "asterisk/musiconhold.h"
00081 #include "asterisk/features.h"
00082 #include "asterisk/utils.h"
00083 #include "asterisk/causes.h"
00084 #include "asterisk/localtime.h"
00085 #include "asterisk/aes.h"
00086 #include "asterisk/dnsmgr.h"
00087 #include "asterisk/devicestate.h"
00088 #include "asterisk/netsock.h"
00089 #include "asterisk/stringfields.h"
00090 #include "asterisk/linkedlists.h"
00091 #include "asterisk/event.h"
00092 #include "asterisk/astobj2.h"
00093 
00094 #include "iax2.h"
00095 #include "iax2-parser.h"
00096 #include "iax2-provision.h"
00097 #include "jitterbuf.h"
00098 
00099 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00100    multithreaded mode. */
00101 #define SCHED_MULTITHREADED
00102 
00103 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00104    thread is actually doing. */
00105 #define DEBUG_SCHED_MULTITHREAD
00106 
00107 
00108 #ifdef SO_NO_CHECK
00109 static int nochecksums = 0;
00110 #endif
00111 
00112 
00113 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00114 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00115 
00116 #define DEFAULT_THREAD_COUNT 10
00117 #define DEFAULT_MAX_THREAD_COUNT 100
00118 #define DEFAULT_RETRY_TIME 1000
00119 #define MEMORY_SIZE 100
00120 #define DEFAULT_DROP 3
00121 
00122 #define DEBUG_SUPPORT
00123 
00124 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00125 
00126 /* Sample over last 100 units to determine historic jitter */
00127 #define GAMMA (0.01)
00128 
00129 static struct ast_codec_pref prefs;
00130 
00131 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00132 
00133 
00134 /*! \brief Maximum transmission unit for the UDP packet in the trunk not to be
00135     fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240 */
00136 #define MAX_TRUNK_MTU 1240 
00137 
00138 static int global_max_trunk_mtu;    /*!< Maximum MTU, 0 if not used */
00139 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;    /*!< Trunk MTU statistics */
00140 
00141 
00142 static char context[80] = "default";
00143 
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146 
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int jittertargetextra = 40; /* number of milliseconds the new jitter buffer adds on to its size */
00155 
00156 #define MAX_TRUNKDATA           640 * 200       /*!< 40ms, uncompressed linear * 200 channels */
00157 
00158 static int trunkfreq = 20;
00159 static int trunkmaxsize = MAX_TRUNKDATA;
00160 
00161 static int authdebug = 1;
00162 static int autokill = 0;
00163 static int iaxcompat = 0;
00164 static int last_authmethod = 0;
00165 
00166 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00167 
00168 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00169 
00170 static unsigned int tos = 0;
00171 
00172 static unsigned int cos = 0;
00173 
00174 static int min_reg_expire;
00175 static int max_reg_expire;
00176 
00177 static int srvlookup = 0;
00178 
00179 static int timingfd = -1;           /* Timing file descriptor */
00180 
00181 static struct ast_netsock_list *netsock;
00182 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00183 static int defaultsockfd = -1;
00184 
00185 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00186 
00187 /* Ethernet, etc */
00188 #define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00189 /* T1, maybe ISDN */
00190 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00191                 ~AST_FORMAT_SLINEAR &        \
00192                 ~AST_FORMAT_SLINEAR16 &         \
00193                 ~AST_FORMAT_ULAW &        \
00194                 ~AST_FORMAT_ALAW &        \
00195                 ~AST_FORMAT_G722) 
00196 /* A modem */
00197 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00198                 ~AST_FORMAT_G726 &        \
00199                 ~AST_FORMAT_G726_AAL2 &      \
00200                 ~AST_FORMAT_ADPCM)
00201 
00202 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00203                 ~AST_FORMAT_G723_1)
00204 
00205 
00206 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00207 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00208 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00209 
00210 static   struct io_context *io;
00211 static   struct sched_context *sched;
00212 
00213 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00214 
00215 static int iaxdebug = 0;
00216 
00217 static int iaxtrunkdebug = 0;
00218 
00219 static int test_losspct = 0;
00220 #ifdef IAXTESTS
00221 static int test_late = 0;
00222 static int test_resync = 0;
00223 static int test_jit = 0;
00224 static int test_jitpct = 0;
00225 #endif /* IAXTESTS */
00226 
00227 static char accountcode[AST_MAX_ACCOUNT_CODE];
00228 static char mohinterpret[MAX_MUSICCLASS];
00229 static char mohsuggest[MAX_MUSICCLASS];
00230 static int amaflags = 0;
00231 static int adsi = 0;
00232 static int delayreject = 0;
00233 static int iax2_encryption = 0;
00234 
00235 static struct ast_flags globalflags = { 0 };
00236 
00237 static pthread_t netthreadid = AST_PTHREADT_NULL;
00238 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00239 AST_MUTEX_DEFINE_STATIC(sched_lock);
00240 static ast_cond_t sched_cond;
00241 
00242 enum iax2_state {
00243    IAX_STATE_STARTED =        (1 << 0),
00244    IAX_STATE_AUTHENTICATED =  (1 << 1),
00245    IAX_STATE_TBD =            (1 << 2),
00246 };
00247 
00248 struct iax2_context {
00249    char context[AST_MAX_CONTEXT];
00250    struct iax2_context *next;
00251 };
00252 
00253 enum iax2_flags {
00254    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00255    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00256    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00257    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00258    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00259    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00260    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00261    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00262         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00263    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00264    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00265    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00266    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00267    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00268    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00269    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00270    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00271    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00272    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00273    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00274    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00275    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00276    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00277    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00278    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00279    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00280                        response, so that we've achieved a three-way handshake with
00281                        them before sending voice or anything else*/
00282    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00283 };
00284 
00285 static int global_rtautoclear = 120;
00286 
00287 static int reload_config(void);
00288 
00289 struct iax2_user {
00290    AST_DECLARE_STRING_FIELDS(
00291       AST_STRING_FIELD(name);
00292       AST_STRING_FIELD(secret);
00293       AST_STRING_FIELD(dbsecret);
00294       AST_STRING_FIELD(accountcode);
00295       AST_STRING_FIELD(mohinterpret);
00296       AST_STRING_FIELD(mohsuggest);
00297       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00298       AST_STRING_FIELD(language);
00299       AST_STRING_FIELD(cid_num);
00300       AST_STRING_FIELD(cid_name);
00301    );
00302    
00303    int authmethods;
00304    int encmethods;
00305    int amaflags;
00306    int adsi;
00307    unsigned int flags;
00308    int capability;
00309    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00310    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00311    struct ast_codec_pref prefs;
00312    struct ast_ha *ha;
00313    struct iax2_context *contexts;
00314    struct ast_variable *vars;
00315 };
00316 
00317 struct iax2_peer {
00318    AST_DECLARE_STRING_FIELDS(
00319       AST_STRING_FIELD(name);
00320       AST_STRING_FIELD(username);
00321       AST_STRING_FIELD(secret);
00322       AST_STRING_FIELD(dbsecret);
00323       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00324 
00325       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00326       AST_STRING_FIELD(context);      /*!< For transfers only */
00327       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00328       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00329       AST_STRING_FIELD(mohinterpret);
00330       AST_STRING_FIELD(mohsuggest);
00331       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00332       /* Suggested caller id if registering */
00333       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00334       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00335       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00336    );
00337    struct ast_codec_pref prefs;
00338    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00339    struct sockaddr_in addr;
00340    int formats;
00341    int sockfd;             /*!< Socket to use for transmission */
00342    struct in_addr mask;
00343    int adsi;
00344    unsigned int flags;
00345 
00346    /* Dynamic Registration fields */
00347    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00348    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00349    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00350 
00351    int expire;             /*!< Schedule entry for expiry */
00352    int expiry;             /*!< How soon to expire */
00353    int capability;               /*!< Capability */
00354 
00355    /* Qualification */
00356    int callno;             /*!< Call number of POKE request */
00357    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00358    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00359    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00360 
00361    int pokefreqok;               /*!< How often to check if the host is up */
00362    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00363    int historicms;               /*!< How long recent average responses took */
00364    int smoothing;             /*!< Sample over how many units to determine historic ms */
00365 
00366    struct ast_event_sub *mwi_event_sub;
00367 
00368    struct ast_ha *ha;
00369 };
00370 
00371 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00372 
00373 struct iax2_trunk_peer {
00374    ast_mutex_t lock;
00375    int sockfd;
00376    struct sockaddr_in addr;
00377    struct timeval txtrunktime;      /*!< Transmit trunktime */
00378    struct timeval rxtrunktime;      /*!< Receive trunktime */
00379    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00380    struct timeval trunkact;      /*!< Last trunk activity */
00381    unsigned int lastsent;        /*!< Last sent time */
00382    /* Trunk data and length */
00383    unsigned char *trunkdata;
00384    unsigned int trunkdatalen;
00385    unsigned int trunkdataalloc;
00386    int trunkmaxmtu;
00387    int trunkerror;
00388    int calls;
00389    AST_LIST_ENTRY(iax2_trunk_peer) list;
00390 };
00391 
00392 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00393 
00394 struct iax_firmware {
00395    AST_LIST_ENTRY(iax_firmware) list;
00396    int fd;
00397    int mmaplen;
00398    int dead;
00399    struct ast_iax2_firmware_header *fwh;
00400    unsigned char *buf;
00401 };
00402 
00403 enum iax_reg_state {
00404    REG_STATE_UNREGISTERED = 0,
00405    REG_STATE_REGSENT,
00406    REG_STATE_AUTHSENT,
00407    REG_STATE_REGISTERED,
00408    REG_STATE_REJECTED,
00409    REG_STATE_TIMEOUT,
00410    REG_STATE_NOAUTH
00411 };
00412 
00413 enum iax_transfer_state {
00414    TRANSFER_NONE = 0,
00415    TRANSFER_BEGIN,
00416    TRANSFER_READY,
00417    TRANSFER_RELEASED,
00418    TRANSFER_PASSTHROUGH,
00419    TRANSFER_MBEGIN,
00420    TRANSFER_MREADY,
00421    TRANSFER_MRELEASED,
00422    TRANSFER_MPASSTHROUGH,
00423    TRANSFER_MEDIA,
00424    TRANSFER_MEDIAPASS
00425 };
00426 
00427 struct iax2_registry {
00428    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00429    char username[80];
00430    char secret[80];        /*!< Password or key name in []'s */
00431    int expire;          /*!< Sched ID of expiration */
00432    int refresh;            /*!< How often to refresh */
00433    enum iax_reg_state regstate;
00434    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00435    int callno;          /*!< Associated call number if applicable */
00436    struct sockaddr_in us;        /*!< Who the server thinks we are */
00437    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00438    AST_LIST_ENTRY(iax2_registry) entry;
00439 };
00440 
00441 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00442 
00443 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00444 #define MIN_RETRY_TIME     100
00445 #define MAX_RETRY_TIME     10000
00446 
00447 #define MAX_JITTER_BUFFER  50
00448 #define MIN_JITTER_BUFFER  10
00449 
00450 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00451 
00452 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00453 
00454 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00455 #define TS_GAP_FOR_JB_RESYNC  5000
00456 
00457 /* used for first_iax_message and last_iax_message.  If this bit is set it was TX, else RX */
00458 #define MARK_IAX_SUBCLASS_TX  0x8000
00459 
00460 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00461 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00462 static int iaxdynamicthreadcount = 0;
00463 static int iaxdynamicthreadnum = 0;
00464 static int iaxactivethreadcount = 0;
00465 
00466 struct iax_rr {
00467    int jitter;
00468    int losspct;
00469    int losscnt;
00470    int packets;
00471    int delay;
00472    int dropped;
00473    int ooo;
00474 };
00475 
00476 struct iax2_pvt_ref;
00477 
00478 struct chan_iax2_pvt {
00479    /*! Socket to send/receive on for this call */
00480    int sockfd;
00481    /*! Last received voice format */
00482    int voiceformat;
00483    /*! Last received video format */
00484    int videoformat;
00485    /*! Last sent voice format */
00486    int svoiceformat;
00487    /*! Last sent video format */
00488    int svideoformat;
00489    /*! What we are capable of sending */
00490    int capability;
00491    /*! Last received timestamp */
00492    unsigned int last;
00493    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00494    unsigned int lastsent;
00495    /*! Timestamp of the last video frame sent */
00496    unsigned int lastvsent;
00497    /*! Next outgoing timestamp if everything is good */
00498    unsigned int nextpred;
00499    /*! iax frame subclass that began iax2_pvt entry. 0x8000 bit is set on TX */
00500    int first_iax_message;
00501    /*! Last iax frame subclass sent or received for a iax2_pvt. 0x8000 bit is set on TX */
00502    int last_iax_message;
00503    /*! True if the last voice we transmitted was not silence/CNG */
00504    unsigned int notsilenttx:1;
00505    /*! Ping time */
00506    unsigned int pingtime;
00507    /*! Max time for initial response */
00508    int maxtime;
00509    /*! Peer Address */
00510    struct sockaddr_in addr;
00511    /*! Actual used codec preferences */
00512    struct ast_codec_pref prefs;
00513    /*! Requested codec preferences */
00514    struct ast_codec_pref rprefs;
00515    /*! Our call number */
00516    unsigned short callno;
00517    /*! Peer callno */
00518    unsigned short peercallno;
00519    /*! Negotiated format, this is only used to remember what format was
00520        chosen for an unauthenticated call so that the channel can get
00521        created later using the right format */
00522    int chosenformat;
00523    /*! Peer selected format */
00524    int peerformat;
00525    /*! Peer capability */
00526    int peercapability;
00527    /*! timeval that we base our transmission on */
00528    struct timeval offset;
00529    /*! timeval that we base our delivery on */
00530    struct timeval rxcore;
00531    /*! The jitterbuffer */
00532    jitterbuf *jb;
00533    /*! active jb read scheduler id */
00534    int jbid;                       
00535    /*! LAG */
00536    int lag;
00537    /*! Error, as discovered by the manager */
00538    int error;
00539    /*! Owner if we have one */
00540    struct ast_channel *owner;
00541    /*! What's our state? */
00542    struct ast_flags state;
00543    /*! Expiry (optional) */
00544    int expiry;
00545    /*! Next outgoing sequence number */
00546    unsigned char oseqno;
00547    /*! Next sequence number they have not yet acknowledged */
00548    unsigned char rseqno;
00549    /*! Next incoming sequence number */
00550    unsigned char iseqno;
00551    /*! Last incoming sequence number we have acknowledged */
00552    unsigned char aseqno;
00553 
00554    AST_DECLARE_STRING_FIELDS(
00555       /*! Peer name */
00556       AST_STRING_FIELD(peer);
00557       /*! Default Context */
00558       AST_STRING_FIELD(context);
00559       /*! Caller ID if available */
00560       AST_STRING_FIELD(cid_num);
00561       AST_STRING_FIELD(cid_name);
00562       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00563       AST_STRING_FIELD(ani);
00564       /*! DNID */
00565       AST_STRING_FIELD(dnid);
00566       /*! RDNIS */
00567       AST_STRING_FIELD(rdnis);
00568       /*! Requested Extension */
00569       AST_STRING_FIELD(exten);
00570       /*! Expected Username */
00571       AST_STRING_FIELD(username);
00572       /*! Expected Secret */
00573       AST_STRING_FIELD(secret);
00574       /*! MD5 challenge */
00575       AST_STRING_FIELD(challenge);
00576       /*! Public keys permitted keys for incoming authentication */
00577       AST_STRING_FIELD(inkeys);
00578       /*! Private key for outgoing authentication */
00579       AST_STRING_FIELD(outkey);
00580       /*! Preferred language */
00581       AST_STRING_FIELD(language);
00582       /*! Hostname/peername for naming purposes */
00583       AST_STRING_FIELD(host);
00584 
00585       AST_STRING_FIELD(dproot);
00586       AST_STRING_FIELD(accountcode);
00587       AST_STRING_FIELD(mohinterpret);
00588       AST_STRING_FIELD(mohsuggest);
00589       /*! received OSP token */
00590       AST_STRING_FIELD(osptoken);
00591    );
00592    /*! AUTHREJ all AUTHREP frames */
00593    int authrej;
00594    /*! permitted authentication methods */
00595    int authmethods;
00596    /*! permitted encryption methods */
00597    int encmethods;
00598    /*! Encryption AES-128 Key */
00599    ast_aes_encrypt_key ecx;
00600    /*! Decryption AES-128 Key corresponding to ecx */
00601    ast_aes_decrypt_key mydcx;
00602    /*! Decryption AES-128 Key used to decrypt peer frames */
00603    ast_aes_decrypt_key dcx;
00604    /*! 32 bytes of semi-random data */
00605    unsigned char semirand[32];
00606    /*! Associated registry */
00607    struct iax2_registry *reg;
00608    /*! Associated peer for poking */
00609    struct iax2_peer *peerpoke;
00610    /*! IAX_ flags */
00611    unsigned int flags;
00612    int adsi;
00613 
00614    /*! Transferring status */
00615    enum iax_transfer_state transferring;
00616    /*! Transfer identifier */
00617    int transferid;
00618    /*! Who we are IAX transferring to */
00619    struct sockaddr_in transfer;
00620    /*! What's the new call number for the transfer */
00621    unsigned short transfercallno;
00622    /*! Transfer encrypt AES-128 Key */
00623    ast_aes_encrypt_key tdcx;
00624 
00625    /*! Status of knowledge of peer ADSI capability */
00626    int peeradsicpe;
00627 
00628    /*! Who we are bridged to */
00629    unsigned short bridgecallno;
00630    
00631    int pingid;       /*!< Transmit PING request */
00632    int lagid;        /*!< Retransmit lag request */
00633    int autoid;       /*!< Auto hangup for Dialplan requestor */
00634    int authid;       /*!< Authentication rejection ID */
00635    int authfail;        /*!< Reason to report failure */
00636    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00637    int calling_ton;
00638    int calling_tns;
00639    int calling_pres;
00640    int amaflags;
00641    AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00642    /*! variables inherited from the user definition */
00643    struct ast_variable *vars;
00644    /*! variables transmitted in a NEW packet */
00645    struct ast_variable *iaxvars;
00646    /*! last received remote rr */
00647    struct iax_rr remote_rr;
00648    /*! Current base time: (just for stats) */
00649    int min;
00650    /*! Dropped frame count: (just for stats) */
00651    int frames_dropped;
00652    /*! received frame count: (just for stats) */
00653    int frames_received;
00654 };
00655 
00656 /*!
00657  * \brief a list of frames that may need to be retransmitted
00658  *
00659  * \note The contents of this list do not need to be explicitly destroyed
00660  * on module unload.  This is because all active calls are destroyed, and
00661  * all frames in this queue will get destroyed as a part of that process.
00662  */
00663 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00664 
00665 /*!
00666  * This module will get much higher performance when doing a lot of
00667  * user and peer lookups if the number of buckets is increased from 1.
00668  * However, to maintain old behavior for Asterisk 1.4, these are set to
00669  * 1 by default.  When using multiple buckets, search order through these
00670  * containers is considered random, so you will not be able to depend on
00671  * the order the entires are specified in iax.conf for matching order. */
00672 #ifdef LOW_MEMORY
00673 #define MAX_PEER_BUCKETS 17
00674 #else
00675 #define MAX_PEER_BUCKETS 563
00676 #endif
00677 static struct ao2_container *peers;
00678 
00679 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00680 static struct ao2_container *users;
00681 
00682 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00683 
00684 enum {
00685    /*! Extension exists */
00686    CACHE_FLAG_EXISTS      = (1 << 0),
00687    /*! Extension is nonexistent */
00688    CACHE_FLAG_NONEXISTENT = (1 << 1),
00689    /*! Extension can exist */
00690    CACHE_FLAG_CANEXIST    = (1 << 2),
00691    /*! Waiting to hear back response */
00692    CACHE_FLAG_PENDING     = (1 << 3),
00693    /*! Timed out */
00694    CACHE_FLAG_TIMEOUT     = (1 << 4),
00695    /*! Request transmitted */
00696    CACHE_FLAG_TRANSMITTED = (1 << 5),
00697    /*! Timeout */
00698    CACHE_FLAG_UNKNOWN     = (1 << 6),
00699    /*! Matchmore */
00700    CACHE_FLAG_MATCHMORE   = (1 << 7),
00701 };
00702 
00703 struct iax2_dpcache {
00704    char peercontext[AST_MAX_CONTEXT];
00705    char exten[AST_MAX_EXTENSION];
00706    struct timeval orig;
00707    struct timeval expiry;
00708    int flags;
00709    unsigned short callno;
00710    int waiters[256];
00711    AST_LIST_ENTRY(iax2_dpcache) cache_list;
00712    AST_LIST_ENTRY(iax2_dpcache) peer_list;
00713 };
00714 
00715 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00716 
00717 static void reg_source_db(struct iax2_peer *p);
00718 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00719 
00720 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00721 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state);
00722 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00723 
00724 enum iax2_thread_iostate {
00725    IAX_IOSTATE_IDLE,
00726    IAX_IOSTATE_READY,
00727    IAX_IOSTATE_PROCESSING,
00728    IAX_IOSTATE_SCHEDREADY,
00729 };
00730 
00731 enum iax2_thread_type {
00732    IAX_THREAD_TYPE_POOL,
00733    IAX_THREAD_TYPE_DYNAMIC,
00734 };
00735 
00736 struct iax2_pkt_buf {
00737    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00738    size_t len;
00739    unsigned char buf[1];
00740 };
00741 
00742 struct iax2_thread {
00743    AST_LIST_ENTRY(iax2_thread) list;
00744    enum iax2_thread_type type;
00745    enum iax2_thread_iostate iostate;
00746 #ifdef SCHED_MULTITHREADED
00747    void (*schedfunc)(const void *);
00748    const void *scheddata;
00749 #endif
00750 #ifdef DEBUG_SCHED_MULTITHREAD
00751    char curfunc[80];
00752 #endif   
00753    int actions;
00754    pthread_t threadid;
00755    int threadnum;
00756    struct sockaddr_in iosin;
00757    unsigned char readbuf[4096]; 
00758    unsigned char *buf;
00759    ssize_t buf_len;
00760    size_t buf_size;
00761    int iofd;
00762    time_t checktime;
00763    ast_mutex_t lock;
00764    ast_cond_t cond;
00765    unsigned int ready_for_signal:1;
00766    /*! if this thread is processing a full frame,
00767      some information about that frame will be stored
00768      here, so we can avoid dispatching any more full
00769      frames for that callno to other threads */
00770    struct {
00771       unsigned short callno;
00772       struct sockaddr_in sin;
00773       unsigned char type;
00774       unsigned char csub;
00775    } ffinfo;
00776    /*! Queued up full frames for processing.  If more full frames arrive for
00777     *  a call which this thread is already processing a full frame for, they
00778     *  are queued up here. */
00779    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00780 };
00781 
00782 /* Thread lists */
00783 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00784 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00785 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00786 
00787 static void *iax2_process_thread(void *data);
00788 static void iax2_destroy(int callno);
00789 
00790 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00791 {
00792    ast_mutex_lock(lock);
00793    ast_cond_signal(cond);
00794    ast_mutex_unlock(lock);
00795 }
00796 
00797 static void iax_debug_output(const char *data)
00798 {
00799    if (iaxdebug)
00800       ast_verbose("%s", data);
00801 }
00802 
00803 static void iax_error_output(const char *data)
00804 {
00805    ast_log(LOG_WARNING, "%s", data);
00806 }
00807 
00808 static void __attribute__((format (printf, 1, 2))) jb_error_output(const char *fmt, ...)
00809 {
00810    va_list args;
00811    char buf[1024];
00812 
00813    va_start(args, fmt);
00814    vsnprintf(buf, sizeof(buf), fmt, args);
00815    va_end(args);
00816 
00817    ast_log(LOG_ERROR, "%s", buf);
00818 }
00819 
00820 static void __attribute__((format (printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00821 {
00822    va_list args;
00823    char buf[1024];
00824 
00825    va_start(args, fmt);
00826    vsnprintf(buf, sizeof(buf), fmt, args);
00827    va_end(args);
00828 
00829    ast_log(LOG_WARNING, "%s", buf);
00830 }
00831 
00832 static void __attribute__((format (printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00833 {
00834    va_list args;
00835    char buf[1024];
00836 
00837    va_start(args, fmt);
00838    vsnprintf(buf, sizeof(buf), fmt, args);
00839    va_end(args);
00840 
00841    ast_verbose("%s", buf);
00842 }
00843 
00844 /*!
00845  * \brief an array of iax2 pvt structures
00846  *
00847  * The container for active chan_iax2_pvt structures is implemented as an
00848  * array for extremely quick direct access to the correct pvt structure
00849  * based on the local call number.  The local call number is used as the
00850  * index into the array where the associated pvt structure is stored.
00851  */
00852 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00853 
00854 /*!
00855  * \brief Another container of iax2_pvt structures
00856  *
00857  * Active IAX2 pvt structs are also stored in this container, if they are a part
00858  * of an active call where we know the remote side's call number.  The reason
00859  * for this is that incoming media frames do not contain our call number.  So,
00860  * instead of having to iterate the entire iaxs array, we use this container to
00861  * look up calls where the remote side is using a given call number.
00862  */
00863 static struct ao2_container *iax_peercallno_pvts;
00864 
00865 /*!
00866  * \brief chan_iax2_pvt structure locks
00867  *
00868  * These locks are used when accessing a pvt structure in the iaxs array.
00869  * The index used here is the same as used in the iaxs array.  It is the
00870  * local call number for the associated pvt struct.
00871  */
00872 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00873 
00874 /*!
00875  * \brief The last time a call number was used
00876  *
00877  * It is important to know the last time that a call number was used locally so
00878  * that it is not used again too soon.  The reason for this is the same as the
00879  * reason that the TCP protocol state machine requires a "TIME WAIT" state.
00880  *
00881  * For example, say that a call is up.  Then, the remote side sends a HANGUP,
00882  * which we respond to with an ACK.  However, there is no way to know whether
00883  * the ACK made it there successfully.  If it were to get lost, the remote
00884  * side may retransmit the HANGUP.  If in the meantime, this call number has
00885  * been reused locally, given the right set of circumstances, this retransmitted
00886  * HANGUP could potentially improperly hang up the new session.  So, to avoid
00887  * this potential issue, we must wait a specified timeout period before reusing
00888  * a local call number.
00889  *
00890  * The specified time that we must wait before reusing a local call number is
00891  * defined as MIN_REUSE_TIME, with a default of 60 seconds.
00892  */
00893 static struct timeval lastused[ARRAY_LEN(iaxs)];
00894 
00895 /*!
00896  *  * \brief Another container of iax2_pvt structures
00897  *  
00898  *  Active IAX2 pvt stucts used during transfering a call are stored here.  
00899  */
00900 static struct ao2_container *iax_transfercallno_pvts;
00901 
00902 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00903    but keeps the division between trunked and non-trunked better. */
00904 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00905 
00906 static int maxtrunkcall = TRUNK_CALL_START;
00907 static int maxnontrunkcall = 1;
00908 
00909 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);
00910 static int expire_registry(const void *data);
00911 static int iax2_answer(struct ast_channel *c);
00912 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00913 static int iax2_devicestate(void *data);
00914 static int iax2_digit_begin(struct ast_channel *c, char digit);
00915 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00916 static int iax2_do_register(struct iax2_registry *reg);
00917 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00918 static int iax2_hangup(struct ast_channel *c);
00919 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00920 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00921 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00922 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00923 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00924 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00925 static int iax2_sendtext(struct ast_channel *c, const char *text);
00926 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00927 static int iax2_transfer(struct ast_channel *c, const char *dest);
00928 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00929 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
00930 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00931 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00932 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00933 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00934 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00935 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00936 static struct ast_frame *iax2_read(struct ast_channel *c);
00937 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00938 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00939 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00940 static void *iax2_dup_variable_datastore(void *);
00941 static void prune_peers(void);
00942 static void prune_users(void);
00943 static void iax2_free_variable_datastore(void *);
00944 
00945 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
00946 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
00947 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00948 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00949 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00950 static void build_rand_pad(unsigned char *buf, ssize_t len);
00951 
00952 static const struct ast_channel_tech iax2_tech = {
00953    .type = "IAX2",
00954    .description = tdesc,
00955    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00956    .properties = AST_CHAN_TP_WANTSJITTER,
00957    .requester = iax2_request,
00958    .devicestate = iax2_devicestate,
00959    .send_digit_begin = iax2_digit_begin,
00960    .send_digit_end = iax2_digit_end,
00961    .send_text = iax2_sendtext,
00962    .send_image = iax2_sendimage,
00963    .send_html = iax2_sendhtml,
00964    .call = iax2_call,
00965    .hangup = iax2_hangup,
00966    .answer = iax2_answer,
00967    .read = iax2_read,
00968    .write = iax2_write,
00969    .write_video = iax2_write,
00970    .indicate = iax2_indicate,
00971    .setoption = iax2_setoption,
00972    .bridge = iax2_bridge,
00973    .transfer = iax2_transfer,
00974    .fixup = iax2_fixup,
00975    .func_channel_read = acf_channel_read,
00976    .func_channel_write = acf_channel_write,
00977 };
00978 
00979 static void mwi_event_cb(const struct ast_event *event, void *userdata)
00980 {
00981    /* The MWI subscriptions exist just so the core knows we care about those
00982     * mailboxes.  However, we just grab the events out of the cache when it
00983     * is time to send MWI, since it is only sent with a REGACK. */
00984 }
00985 
00986 /*! \brief Send manager event at call setup to link between Asterisk channel name
00987    and IAX2 call identifiers */
00988 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt) 
00989 {
00990    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
00991       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
00992       pvt->owner ? pvt->owner->name : "",
00993       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
00994 }
00995 
00996 
00997 static struct ast_datastore_info iax2_variable_datastore_info = {
00998    .type = "IAX2_VARIABLE",
00999    .duplicate = iax2_dup_variable_datastore,
01000    .destroy = iax2_free_variable_datastore,
01001 };
01002 
01003 static void *iax2_dup_variable_datastore(void *old)
01004 {
01005    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01006    struct ast_var_t *oldvar, *newvar;
01007 
01008    newlist = ast_calloc(sizeof(*newlist), 1);
01009    if (!newlist) {
01010       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01011       return NULL;
01012    }
01013 
01014    AST_LIST_HEAD_INIT(newlist);
01015    AST_LIST_LOCK(oldlist);
01016    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01017       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01018       if (newvar)
01019          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01020       else
01021          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01022    }
01023    AST_LIST_UNLOCK(oldlist);
01024    return newlist;
01025 }
01026 
01027 static void iax2_free_variable_datastore(void *old)
01028 {
01029    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01030    struct ast_var_t *oldvar;
01031 
01032    AST_LIST_LOCK(oldlist);
01033    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01034       ast_free(oldvar);
01035    }
01036    AST_LIST_UNLOCK(oldlist);
01037    AST_LIST_HEAD_DESTROY(oldlist);
01038    ast_free(oldlist);
01039 }
01040 
01041 
01042 /* WARNING: insert_idle_thread should only ever be called within the
01043  * context of an iax2_process_thread() thread.
01044  */
01045 static void insert_idle_thread(struct iax2_thread *thread)
01046 {
01047    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01048       AST_LIST_LOCK(&dynamic_list);
01049       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01050       AST_LIST_UNLOCK(&dynamic_list);
01051    } else {
01052       AST_LIST_LOCK(&idle_list);
01053       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01054       AST_LIST_UNLOCK(&idle_list);
01055    }
01056 
01057    return;
01058 }
01059 
01060 static struct iax2_thread *find_idle_thread(void)
01061 {
01062    struct iax2_thread *thread = NULL;
01063 
01064    /* Pop the head of the idle list off */
01065    AST_LIST_LOCK(&idle_list);
01066    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01067    AST_LIST_UNLOCK(&idle_list);
01068 
01069    /* If we popped a thread off the idle list, just return it */
01070    if (thread) {
01071       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01072       return thread;
01073    }
01074 
01075    /* Pop the head of the dynamic list off */
01076    AST_LIST_LOCK(&dynamic_list);
01077    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01078    AST_LIST_UNLOCK(&dynamic_list);
01079 
01080    /* If we popped a thread off the dynamic list, just return it */
01081    if (thread) {
01082       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01083       return thread;
01084    }
01085 
01086    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01087    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01088       return NULL;
01089 
01090    /* Set default values */
01091    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01092    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01093    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01094 
01095    /* Initialize lock and condition */
01096    ast_mutex_init(&thread->lock);
01097    ast_cond_init(&thread->cond, NULL);
01098 
01099    /* Create thread and send it on it's way */
01100    if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01101       ast_cond_destroy(&thread->cond);
01102       ast_mutex_destroy(&thread->lock);
01103       ast_free(thread);
01104       return NULL;
01105    }
01106 
01107    /* this thread is not processing a full frame (since it is idle),
01108       so ensure that the field for the full frame call number is empty */
01109    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01110 
01111    /* Wait for the thread to be ready before returning it to the caller */
01112    while (!thread->ready_for_signal)
01113       usleep(1);
01114 
01115    return thread;
01116 }
01117 
01118 #ifdef SCHED_MULTITHREADED
01119 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01120 {
01121    struct iax2_thread *thread = NULL;
01122    static time_t lasterror;
01123    static time_t t;
01124 
01125    thread = find_idle_thread();
01126 
01127    if (thread != NULL) {
01128       thread->schedfunc = func;
01129       thread->scheddata = data;
01130       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01131 #ifdef DEBUG_SCHED_MULTITHREAD
01132       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01133 #endif
01134       signal_condition(&thread->lock, &thread->cond);
01135       return 0;
01136    }
01137    time(&t);
01138    if (t != lasterror) 
01139       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01140    lasterror = t;
01141 
01142    return -1;
01143 }
01144 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01145 #endif
01146 
01147 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01148 {
01149    AST_SCHED_REPLACE(id, con, when, callback, data);
01150    signal_condition(&sched_lock, &sched_cond);
01151 
01152    return id;
01153 }
01154 
01155 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01156 {
01157    int res;
01158 
01159    res = ast_sched_add(con, when, callback, data);
01160    signal_condition(&sched_lock, &sched_cond);
01161 
01162    return res;
01163 }
01164 
01165 static int send_ping(const void *data);
01166 
01167 static void __send_ping(const void *data)
01168 {
01169    int callno = (long) data;
01170 
01171    ast_mutex_lock(&iaxsl[callno]);
01172 
01173    if (iaxs[callno]) {
01174       if (iaxs[callno]->peercallno) {
01175          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01176          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01177       } else {
01178          /* I am the schedule, so I'm allowed to do this */
01179          iaxs[callno]->pingid = -1;
01180       }
01181    } else {
01182       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01183    }
01184 
01185    ast_mutex_unlock(&iaxsl[callno]);
01186 }
01187 
01188 static int send_ping(const void *data)
01189 {
01190 #ifdef SCHED_MULTITHREADED
01191    if (schedule_action(__send_ping, data))
01192 #endif      
01193       __send_ping(data);
01194 
01195    return 0;
01196 }
01197 
01198 static int get_encrypt_methods(const char *s)
01199 {
01200    int e;
01201    if (!strcasecmp(s, "aes128"))
01202       e = IAX_ENCRYPT_AES128;
01203    else if (ast_true(s))
01204       e = IAX_ENCRYPT_AES128;
01205    else
01206       e = 0;
01207    return e;
01208 }
01209 
01210 static int send_lagrq(const void *data);
01211 
01212 static void __send_lagrq(const void *data)
01213 {
01214    int callno = (long) data;
01215 
01216    ast_mutex_lock(&iaxsl[callno]);
01217 
01218    if (iaxs[callno]) {
01219       if (iaxs[callno]->peercallno) {
01220          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01221          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01222       } else {
01223          /* I am the schedule, so I'm allowed to do this */
01224          iaxs[callno]->lagid = -1;
01225       }
01226    } else {
01227       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01228    }
01229 
01230    ast_mutex_unlock(&iaxsl[callno]);
01231 }
01232 
01233 static int send_lagrq(const void *data)
01234 {
01235 #ifdef SCHED_MULTITHREADED
01236    if (schedule_action(__send_lagrq, data))
01237 #endif      
01238       __send_lagrq(data);
01239    
01240    return 0;
01241 }
01242 
01243 static unsigned char compress_subclass(int subclass)
01244 {
01245    int x;
01246    int power=-1;
01247    /* If it's 128 or smaller, just return it */
01248    if (subclass < IAX_FLAG_SC_LOG)
01249       return subclass;
01250    /* Otherwise find its power */
01251    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01252       if (subclass & (1 << x)) {
01253          if (power > -1) {
01254             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01255             return 0;
01256          } else
01257             power = x;
01258       }
01259    }
01260    return power | IAX_FLAG_SC_LOG;
01261 }
01262 
01263 static int uncompress_subclass(unsigned char csub)
01264 {
01265    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01266    if (csub & IAX_FLAG_SC_LOG) {
01267       /* special case for 'compressed' -1 */
01268       if (csub == 0xff)
01269          return -1;
01270       else
01271          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01272    }
01273    else
01274       return csub;
01275 }
01276 
01277 /*!
01278  * \note The only member of the peer passed here guaranteed to be set is the name field
01279  */
01280 static int peer_hash_cb(const void *obj, const int flags)
01281 {
01282    const struct iax2_peer *peer = obj;
01283 
01284    return ast_str_hash(peer->name);
01285 }
01286 
01287 /*!
01288  * \note The only member of the peer passed here guaranteed to be set is the name field
01289  */
01290 static int peer_cmp_cb(void *obj, void *arg, int flags)
01291 {
01292    struct iax2_peer *peer = obj, *peer2 = arg;
01293 
01294    return !strcmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01295 }
01296 
01297 /*!
01298  * \note The only member of the user passed here guaranteed to be set is the name field
01299  */
01300 static int user_hash_cb(const void *obj, const int flags)
01301 {
01302    const struct iax2_user *user = obj;
01303 
01304    return ast_str_hash(user->name);
01305 }
01306 
01307 /*!
01308  * \note The only member of the user passed here guaranteed to be set is the name field
01309  */
01310 static int user_cmp_cb(void *obj, void *arg, int flags)
01311 {
01312    struct iax2_user *user = obj, *user2 = arg;
01313 
01314    return !strcmp(user->name, user2->name) ? CMP_MATCH : 0;
01315 }
01316 
01317 /*!
01318  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01319  *       so do not call it with a pvt lock held.
01320  */
01321 static struct iax2_peer *find_peer(const char *name, int realtime) 
01322 {
01323    struct iax2_peer *peer = NULL;
01324    struct iax2_peer tmp_peer = {
01325       .name = name,
01326    };
01327 
01328    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01329 
01330    /* Now go for realtime if applicable */
01331    if(!peer && realtime)
01332       peer = realtime_peer(name, NULL);
01333 
01334    return peer;
01335 }
01336 
01337 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01338 {
01339    ao2_ref(peer, +1);
01340    return peer;
01341 }
01342 
01343 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01344 {
01345    ao2_ref(peer, -1);
01346    return NULL;
01347 }
01348 
01349 static struct iax2_user *find_user(const char *name)
01350 {
01351    struct iax2_user tmp_user = {
01352       .name = name,
01353    };
01354 
01355    return ao2_find(users, &tmp_user, OBJ_POINTER);
01356 }
01357 static inline struct iax2_user *user_ref(struct iax2_user *user)
01358 {
01359    ao2_ref(user, +1);
01360    return user;
01361 }
01362 
01363 static inline struct iax2_user *user_unref(struct iax2_user *user)
01364 {
01365    ao2_ref(user, -1);
01366    return NULL;
01367 }
01368 
01369 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01370 {
01371    struct iax2_peer *peer = NULL;
01372    int res = 0;
01373    struct ao2_iterator i;
01374 
01375    i = ao2_iterator_init(peers, 0);
01376    while ((peer = ao2_iterator_next(&i))) {
01377       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01378           (peer->addr.sin_port == sin.sin_port)) {
01379          ast_copy_string(host, peer->name, len);
01380          peer_unref(peer);
01381          res = 1;
01382          break;
01383       }
01384       peer_unref(peer);
01385    }
01386 
01387    if (!peer) {
01388       peer = realtime_peer(NULL, &sin);
01389       if (peer) {
01390          ast_copy_string(host, peer->name, len);
01391          peer_unref(peer);
01392          res = 1;
01393       }
01394    }
01395 
01396    return res;
01397 }
01398 
01399 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01400 {
01401    /* Decrement AUTHREQ count if needed */
01402    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01403       struct iax2_user *user;
01404       struct iax2_user tmp_user = {
01405          .name = pvt->username,
01406       };
01407 
01408       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01409       if (user) {
01410          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01411          user_unref(user); 
01412       }
01413 
01414       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01415    }
01416    /* No more pings or lagrq's */
01417    AST_SCHED_DEL(sched, pvt->pingid);
01418    AST_SCHED_DEL(sched, pvt->lagid);
01419    AST_SCHED_DEL(sched, pvt->autoid);
01420    AST_SCHED_DEL(sched, pvt->authid);
01421    AST_SCHED_DEL(sched, pvt->initid);
01422    AST_SCHED_DEL(sched, pvt->jbid);
01423 }
01424 
01425 static void iax2_frame_free(struct iax_frame *fr)
01426 {
01427    AST_SCHED_DEL(sched, fr->retrans);
01428    iax_frame_free(fr);
01429 }
01430 
01431 static int scheduled_destroy(const void *vid)
01432 {
01433    short callno = PTR_TO_CALLNO(vid);
01434    ast_mutex_lock(&iaxsl[callno]);
01435    if (iaxs[callno]) {
01436       if (option_debug) {
01437          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01438       }
01439       iax2_destroy(callno);
01440    }
01441    ast_mutex_unlock(&iaxsl[callno]);
01442    return 0;
01443 }
01444 
01445 static void pvt_destructor(void *obj)
01446 {
01447    struct chan_iax2_pvt *pvt = obj;
01448    struct iax_frame *cur = NULL;
01449 
01450    iax2_destroy_helper(pvt);
01451 
01452    /* Already gone */
01453    ast_set_flag(pvt, IAX_ALREADYGONE); 
01454 
01455    AST_LIST_LOCK(&frame_queue);
01456    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01457       /* Cancel any pending transmissions */
01458       if (cur->callno == pvt->callno) { 
01459          cur->retries = -1;
01460       }
01461    }
01462    AST_LIST_UNLOCK(&frame_queue);
01463 
01464    if (pvt->reg) {
01465       pvt->reg->callno = 0;
01466    }
01467 
01468    if (!pvt->owner) {
01469       jb_frame frame;
01470       if (pvt->vars) {
01471           ast_variables_destroy(pvt->vars);
01472           pvt->vars = NULL;
01473       }
01474 
01475       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01476          iax2_frame_free(frame.data);
01477       }
01478 
01479       jb_destroy(pvt->jb);
01480       ast_string_field_free_memory(pvt);
01481    }
01482 }
01483 
01484 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01485 {
01486    struct chan_iax2_pvt *tmp;
01487    jb_conf jbconf;
01488 
01489    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01490       return NULL;
01491    }
01492 
01493    if (ast_string_field_init(tmp, 32)) {
01494       ao2_ref(tmp, -1);
01495       tmp = NULL;
01496       return NULL;
01497    }
01498       
01499    tmp->prefs = prefs;
01500    tmp->pingid = -1;
01501    tmp->lagid = -1;
01502    tmp->autoid = -1;
01503    tmp->authid = -1;
01504    tmp->initid = -1;
01505 
01506    ast_string_field_set(tmp,exten, "s");
01507    ast_string_field_set(tmp,host, host);
01508 
01509    tmp->jb = jb_new();
01510    tmp->jbid = -1;
01511    jbconf.max_jitterbuf = maxjitterbuffer;
01512    jbconf.resync_threshold = resyncthreshold;
01513    jbconf.max_contig_interp = maxjitterinterps;
01514    jbconf.target_extra = jittertargetextra;
01515    jb_setconf(tmp->jb,&jbconf);
01516 
01517    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01518 
01519    return tmp;
01520 }
01521 
01522 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01523 {
01524    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01525    if (new) {
01526       size_t afdatalen = new->afdatalen;
01527       memcpy(new, fr, sizeof(*new));
01528       iax_frame_wrap(new, &fr->af);
01529       new->afdatalen = afdatalen;
01530       new->data = NULL;
01531       new->datalen = 0;
01532       new->direction = DIRECTION_INGRESS;
01533       new->retrans = -1;
01534    }
01535    return new;
01536 }
01537 
01538 #define NEW_PREVENT  0
01539 #define NEW_ALLOW    1
01540 #define NEW_FORCE    2
01541 
01542 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01543 {
01544    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01545       (cur->addr.sin_port == sin->sin_port)) {
01546       /* This is the main host */
01547       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01548           (check_dcallno ? dcallno == cur->callno : 1) ) {
01549          /* That's us.  Be sure we keep track of the peer call number */
01550          return 1;
01551       }
01552    }
01553    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01554        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01555       /* We're transferring */
01556       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01557          return 1;
01558    }
01559    return 0;
01560 }
01561 
01562 static void update_max_trunk(void)
01563 {
01564    int max = TRUNK_CALL_START;
01565    int x;
01566 
01567    /* XXX Prolly don't need locks here XXX */
01568    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01569       if (iaxs[x]) {
01570          max = x + 1;
01571       }
01572    }
01573 
01574    maxtrunkcall = max;
01575    if (iaxdebug)
01576       ast_debug(1, "New max trunk callno is %d\n", max);
01577 }
01578 
01579 static void update_max_nontrunk(void)
01580 {
01581    int max = 1;
01582    int x;
01583    /* XXX Prolly don't need locks here XXX */
01584    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01585       if (iaxs[x])
01586          max = x + 1;
01587    }
01588    maxnontrunkcall = max;
01589    if (iaxdebug)
01590       ast_debug(1, "New max nontrunk callno is %d\n", max);
01591 }
01592 
01593 static int make_trunk(unsigned short callno, int locked)
01594 {
01595    int x;
01596    int res= 0;
01597    struct timeval now = ast_tvnow();
01598    if (iaxs[callno]->oseqno) {
01599       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01600       return -1;
01601    }
01602    if (callno & TRUNK_CALL_START) {
01603       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01604       return -1;
01605    }
01606    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01607       ast_mutex_lock(&iaxsl[x]);
01608       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01609          /*!
01610           * \note We delete these before switching the slot, because if
01611           * they fire in the meantime, they will generate a warning.
01612           */
01613          AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01614          AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01615          iaxs[x] = iaxs[callno];
01616          iaxs[x]->callno = x;
01617          iaxs[callno] = NULL;
01618          /* Update the two timers that should have been started */
01619          iaxs[x]->pingid = iax2_sched_add(sched, 
01620             ping_time * 1000, send_ping, (void *)(long)x);
01621          iaxs[x]->lagid = iax2_sched_add(sched, 
01622             lagrq_time * 1000, send_lagrq, (void *)(long)x);
01623          if (locked)
01624             ast_mutex_unlock(&iaxsl[callno]);
01625          res = x;
01626          if (!locked)
01627             ast_mutex_unlock(&iaxsl[x]);
01628          break;
01629       }
01630       ast_mutex_unlock(&iaxsl[x]);
01631    }
01632    if (x >= ARRAY_LEN(iaxs) - 1) {
01633       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01634       return -1;
01635    }
01636    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01637    /* We move this call from a non-trunked to a trunked call */
01638    update_max_trunk();
01639    update_max_nontrunk();
01640    return res;
01641 }
01642 
01643 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01644 {
01645    if (!pvt->transfercallno) {
01646       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01647       return;
01648    }
01649 
01650    ao2_link(iax_transfercallno_pvts, pvt);
01651 }
01652 
01653 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01654 {
01655    if (!pvt->transfercallno) {
01656       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01657       return;
01658    }
01659 
01660    ao2_unlink(iax_transfercallno_pvts, pvt);
01661 }
01662 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01663 {
01664    if (!pvt->peercallno) {
01665       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01666       return;
01667    }
01668 
01669    ao2_link(iax_peercallno_pvts, pvt);
01670 }
01671 
01672 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01673 {
01674    if (!pvt->peercallno) {
01675       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01676       return;
01677    }
01678 
01679    ao2_unlink(iax_peercallno_pvts, pvt);
01680 }
01681 
01682 /*
01683  * \note Calling this function while holding another pvt lock can cause a deadlock.
01684  */
01685 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01686 {
01687    int res = 0;
01688    int x;
01689    struct timeval now;
01690    char host[80];
01691 
01692    if (new <= NEW_ALLOW) {
01693       if (callno) {
01694          struct chan_iax2_pvt *pvt;
01695          struct chan_iax2_pvt tmp_pvt = {
01696             .callno = dcallno,
01697             .peercallno = callno,
01698             .transfercallno = callno,
01699             /* hack!! */
01700             .frames_received = check_dcallno,
01701          };
01702 
01703          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01704          /* this works for finding normal call numbers not involving transfering */ 
01705          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01706             if (return_locked) {
01707                ast_mutex_lock(&iaxsl[pvt->callno]);
01708             }
01709             res = pvt->callno;
01710             ao2_ref(pvt, -1);
01711             pvt = NULL;
01712             return res;
01713          }
01714          /* this searches for transfer call numbers that might not get caught otherwise */
01715          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01716          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01717          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01718             if (return_locked) {
01719                ast_mutex_lock(&iaxsl[pvt->callno]);
01720             }
01721             res = pvt->callno;
01722             ao2_ref(pvt, -1);
01723             pvt = NULL;
01724             return res;
01725          }
01726       }
01727          /* This will occur on the first response to a message that we initiated,
01728        * such as a PING. */
01729       if (dcallno) {
01730          ast_mutex_lock(&iaxsl[dcallno]);
01731       }
01732       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01733          iaxs[dcallno]->peercallno = callno;
01734          res = dcallno;
01735          store_by_peercallno(iaxs[dcallno]);
01736          if (!res || !return_locked) {
01737             ast_mutex_unlock(&iaxsl[dcallno]);
01738          }
01739          return res;
01740       }
01741       if (dcallno) {
01742          ast_mutex_unlock(&iaxsl[dcallno]);
01743       }
01744 #ifdef IAX_OLD_FIND
01745       /* If we get here, we SHOULD NOT find a call structure for this
01746          callno; if we do, it means that there is a call structure that
01747          has a peer callno but did NOT get entered into the hash table,
01748          which is bad.
01749 
01750          If we find a call structure using this old, slow method, output a log
01751          message so we'll know about it. After a few months of leaving this in
01752          place, if we don't hear about people seeing these messages, we can
01753          remove this code for good.
01754       */
01755 
01756       for (x = 1; !res && x < maxnontrunkcall; x++) {
01757          ast_mutex_lock(&iaxsl[x]);
01758          if (iaxs[x]) {
01759             /* Look for an exact match */
01760             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01761                res = x;
01762             }
01763          }
01764          if (!res || !return_locked)
01765             ast_mutex_unlock(&iaxsl[x]);
01766       }
01767       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01768          ast_mutex_lock(&iaxsl[x]);
01769          if (iaxs[x]) {
01770             /* Look for an exact match */
01771             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01772                res = x;
01773             }
01774          }
01775          if (!res || !return_locked)
01776             ast_mutex_unlock(&iaxsl[x]);
01777       }
01778 #endif
01779    }
01780    if (!res && (new >= NEW_ALLOW)) {
01781       int start, found = 0;
01782 
01783       /* It may seem odd that we look through the peer list for a name for
01784        * this *incoming* call.  Well, it is weird.  However, users don't
01785        * have an IP address/port number that we can match against.  So,
01786        * this is just checking for a peer that has that IP/port and
01787        * assuming that we have a user of the same name.  This isn't always
01788        * correct, but it will be changed if needed after authentication. */
01789       if (!iax2_getpeername(*sin, host, sizeof(host)))
01790          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01791 
01792       now = ast_tvnow();
01793       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01794       for (x = start; 1; x++) {
01795          if (x == TRUNK_CALL_START) {
01796             x = 1;
01797             continue;
01798          }
01799 
01800          /* Find first unused call number that hasn't been used in a while */
01801          ast_mutex_lock(&iaxsl[x]);
01802          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01803             found = 1;
01804             break;
01805          }
01806          ast_mutex_unlock(&iaxsl[x]);
01807          
01808          if (x == start - 1) {
01809             break;
01810          }
01811       }
01812       /* We've still got lock held if we found a spot */
01813       if (x == start - 1 && !found) {
01814          ast_log(LOG_WARNING, "No more space\n");
01815          return 0;
01816       }
01817       iaxs[x] = new_iax(sin, host);
01818       update_max_nontrunk();
01819       if (iaxs[x]) {
01820          if (iaxdebug)
01821             ast_debug(1, "Creating new call structure %d\n", x);
01822          iaxs[x]->sockfd = sockfd;
01823          iaxs[x]->addr.sin_port = sin->sin_port;
01824          iaxs[x]->addr.sin_family = sin->sin_family;
01825          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01826          iaxs[x]->peercallno = callno;
01827          iaxs[x]->callno = x;
01828          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01829          iaxs[x]->expiry = min_reg_expire;
01830          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01831          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01832          iaxs[x]->amaflags = amaflags;
01833          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01834          
01835          ast_string_field_set(iaxs[x], accountcode, accountcode);
01836          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01837          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01838 
01839          if (iaxs[x]->peercallno) {
01840             store_by_peercallno(iaxs[x]);
01841          }
01842       } else {
01843          ast_log(LOG_WARNING, "Out of resources\n");
01844          ast_mutex_unlock(&iaxsl[x]);
01845          return 0;
01846       }
01847       if (!return_locked)
01848          ast_mutex_unlock(&iaxsl[x]);
01849       res = x;
01850    }
01851    return res;
01852 }
01853 
01854 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01855 
01856    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01857 }
01858 
01859 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01860 
01861    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01862 }
01863 
01864 /*!
01865  * \brief Queue a frame to a call's owning asterisk channel
01866  *
01867  * \pre This function assumes that iaxsl[callno] is locked when called.
01868  *
01869  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01870  * was valid before calling it, it may no longer be valid after calling it.
01871  * This function may unlock and lock the mutex associated with this callno,
01872  * meaning that another thread may grab it and destroy the call.
01873  */
01874 static int iax2_queue_frame(int callno, struct ast_frame *f)
01875 {
01876    for (;;) {
01877       if (iaxs[callno] && iaxs[callno]->owner) {
01878          if (ast_channel_trylock(iaxs[callno]->owner)) {
01879             /* Avoid deadlock by pausing and trying again */
01880             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01881          } else {
01882             ast_queue_frame(iaxs[callno]->owner, f);
01883             ast_channel_unlock(iaxs[callno]->owner);
01884             break;
01885          }
01886       } else
01887          break;
01888    }
01889    return 0;
01890 }
01891 
01892 /*!
01893  * \brief Queue a hangup frame on the ast_channel owner
01894  *
01895  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01896  * is active for the given call number.
01897  *
01898  * \pre Assumes lock for callno is already held.
01899  *
01900  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01901  * was valid before calling it, it may no longer be valid after calling it.
01902  * This function may unlock and lock the mutex associated with this callno,
01903  * meaning that another thread may grab it and destroy the call.
01904  */
01905 static int iax2_queue_hangup(int callno)
01906 {
01907    for (;;) {
01908       if (iaxs[callno] && iaxs[callno]->owner) {
01909          if (ast_channel_trylock(iaxs[callno]->owner)) {
01910             /* Avoid deadlock by pausing and trying again */
01911             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01912          } else {
01913             ast_queue_hangup(iaxs[callno]->owner);
01914             ast_channel_unlock(iaxs[callno]->owner);
01915             break;
01916          }
01917       } else
01918          break;
01919    }
01920    return 0;
01921 }
01922 
01923 /*!
01924  * \brief Queue a control frame on the ast_channel owner
01925  *
01926  * This function queues a control frame on the owner of the IAX2 pvt struct that
01927  * is active for the given call number.
01928  *
01929  * \pre Assumes lock for callno is already held.
01930  *
01931  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01932  * was valid before calling it, it may no longer be valid after calling it.
01933  * This function may unlock and lock the mutex associated with this callno,
01934  * meaning that another thread may grab it and destroy the call.
01935  */
01936 static int iax2_queue_control_data(int callno, 
01937    enum ast_control_frame_type control, const void *data, size_t datalen)
01938 {
01939    for (;;) {
01940       if (iaxs[callno] && iaxs[callno]->owner) {
01941          if (ast_channel_trylock(iaxs[callno]->owner)) {
01942             /* Avoid deadlock by pausing and trying again */
01943             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01944          } else {
01945             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01946             ast_channel_unlock(iaxs[callno]->owner);
01947             break;
01948          }
01949       } else
01950          break;
01951    }
01952    return 0;
01953 }
01954 static void destroy_firmware(struct iax_firmware *cur)
01955 {
01956    /* Close firmware */
01957    if (cur->fwh) {
01958       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01959    }
01960    close(cur->fd);
01961    ast_free(cur);
01962 }
01963 
01964 static int try_firmware(char *s)
01965 {
01966    struct stat stbuf;
01967    struct iax_firmware *cur = NULL;
01968    int ifd, fd, res, len, chunk;
01969    struct ast_iax2_firmware_header *fwh, fwh2;
01970    struct MD5Context md5;
01971    unsigned char sum[16], buf[1024];
01972    char *s2, *last;
01973 
01974    if (!(s2 = alloca(strlen(s) + 100))) {
01975       ast_log(LOG_WARNING, "Alloca failed!\n");
01976       return -1;
01977    }
01978 
01979    last = strrchr(s, '/');
01980    if (last)
01981       last++;
01982    else
01983       last = s;
01984 
01985    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01986 
01987    if ((res = stat(s, &stbuf) < 0)) {
01988       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01989       return -1;
01990    }
01991 
01992    /* Make sure it's not a directory */
01993    if (S_ISDIR(stbuf.st_mode))
01994       return -1;
01995    ifd = open(s, O_RDONLY);
01996    if (ifd < 0) {
01997       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01998       return -1;
01999    }
02000    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02001    if (fd < 0) {
02002       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02003       close(ifd);
02004       return -1;
02005    }
02006    /* Unlink our newly created file */
02007    unlink(s2);
02008    
02009    /* Now copy the firmware into it */
02010    len = stbuf.st_size;
02011    while(len) {
02012       chunk = len;
02013       if (chunk > sizeof(buf))
02014          chunk = sizeof(buf);
02015       res = read(ifd, buf, chunk);
02016       if (res != chunk) {
02017          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02018          close(ifd);
02019          close(fd);
02020          return -1;
02021       }
02022       res = write(fd, buf, chunk);
02023       if (res != chunk) {
02024          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02025          close(ifd);
02026          close(fd);
02027          return -1;
02028       }
02029       len -= chunk;
02030    }
02031    close(ifd);
02032    /* Return to the beginning */
02033    lseek(fd, 0, SEEK_SET);
02034    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02035       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02036       close(fd);
02037       return -1;
02038    }
02039    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02040       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02041       close(fd);
02042       return -1;
02043    }
02044    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02045       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02046       close(fd);
02047       return -1;
02048    }
02049    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02050       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02051       close(fd);
02052       return -1;
02053    }
02054    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
02055    if (fwh == MAP_FAILED) {
02056       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02057       close(fd);
02058       return -1;
02059    }
02060    MD5Init(&md5);
02061    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02062    MD5Final(sum, &md5);
02063    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02064       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02065       munmap((void*)fwh, stbuf.st_size);
02066       close(fd);
02067       return -1;
02068    }
02069 
02070    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02071       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02072          /* Found a candidate */
02073          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02074             /* The version we have on loaded is older, load this one instead */
02075             break;
02076          /* This version is no newer than what we have.  Don't worry about it.
02077             We'll consider it a proper load anyhow though */
02078          munmap((void*)fwh, stbuf.st_size);
02079          close(fd);
02080          return 0;
02081       }
02082    }
02083    
02084    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02085       cur->fd = -1;
02086       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02087    }
02088    
02089    if (cur) {
02090       if (cur->fwh)
02091          munmap((void*)cur->fwh, cur->mmaplen);
02092       if (cur->fd > -1)
02093          close(cur->fd);
02094       cur->fwh = fwh;
02095       cur->fd = fd;
02096       cur->mmaplen = stbuf.st_size;
02097       cur->dead = 0;
02098    }
02099    
02100    return 0;
02101 }
02102 
02103 static int iax_check_version(char *dev)
02104 {
02105    int res = 0;
02106    struct iax_firmware *cur = NULL;
02107 
02108    if (ast_strlen_zero(dev))
02109       return 0;
02110 
02111    AST_LIST_LOCK(&firmwares);
02112    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02113       if (!strcmp(dev, (char *)cur->fwh->devname)) {
02114          res = ntohs(cur->fwh->version);
02115          break;
02116       }
02117    }
02118    AST_LIST_UNLOCK(&firmwares);
02119 
02120    return res;
02121 }
02122 
02123 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02124 {
02125    int res = -1;
02126    unsigned int bs = desc & 0xff;
02127    unsigned int start = (desc >> 8) & 0xffffff;
02128    unsigned int bytes;
02129    struct iax_firmware *cur;
02130 
02131    if (ast_strlen_zero((char *)dev) || !bs)
02132       return -1;
02133 
02134    start *= bs;
02135    
02136    AST_LIST_LOCK(&firmwares);
02137    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02138       if (strcmp((char *)dev, (char *)cur->fwh->devname))
02139          continue;
02140       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02141       if (start < ntohl(cur->fwh->datalen)) {
02142          bytes = ntohl(cur->fwh->datalen) - start;
02143          if (bytes > bs)
02144             bytes = bs;
02145          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02146       } else {
02147          bytes = 0;
02148          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02149       }
02150       if (bytes == bs)
02151          res = 0;
02152       else
02153          res = 1;
02154       break;
02155    }
02156    AST_LIST_UNLOCK(&firmwares);
02157 
02158    return res;
02159 }
02160 
02161 
02162 static void reload_firmware(int unload)
02163 {
02164    struct iax_firmware *cur = NULL;
02165    DIR *fwd;
02166    struct dirent *de;
02167    char dir[256], fn[256];
02168 
02169    AST_LIST_LOCK(&firmwares);
02170 
02171    /* Mark all as dead */
02172    AST_LIST_TRAVERSE(&firmwares, cur, list)
02173       cur->dead = 1;
02174 
02175    /* Now that we have marked them dead... load new ones */
02176    if (!unload) {
02177       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02178       fwd = opendir(dir);
02179       if (fwd) {
02180          while((de = readdir(fwd))) {
02181             if (de->d_name[0] != '.') {
02182                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02183                if (!try_firmware(fn)) {
02184                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02185                }
02186             }
02187          }
02188          closedir(fwd);
02189       } else 
02190          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02191    }
02192 
02193    /* Clean up leftovers */
02194    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02195       if (!cur->dead)
02196          continue;
02197       AST_LIST_REMOVE_CURRENT(list);
02198       destroy_firmware(cur);
02199    }
02200    AST_LIST_TRAVERSE_SAFE_END;
02201 
02202    AST_LIST_UNLOCK(&firmwares);
02203 }
02204 
02205 /*!
02206  * \note This function assumes that iaxsl[callno] is locked when called.
02207  *
02208  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02209  * was valid before calling it, it may no longer be valid after calling it.
02210  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02211  * associated with this callno, meaning that another thread may grab it and destroy the call.
02212  */
02213 static int __do_deliver(void *data)
02214 {
02215    /* Just deliver the packet by using queueing.  This is called by
02216      the IAX thread with the iaxsl lock held. */
02217    struct iax_frame *fr = data;
02218    fr->retrans = -1;
02219    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02220    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02221       iax2_queue_frame(fr->callno, &fr->af);
02222    /* Free our iax frame */
02223    iax2_frame_free(fr);
02224    /* And don't run again */
02225    return 0;
02226 }
02227 
02228 static int handle_error(void)
02229 {
02230    /* XXX Ideally we should figure out why an error occurred and then abort those
02231       rather than continuing to try.  Unfortunately, the published interface does
02232       not seem to work XXX */
02233 #if 0
02234    struct sockaddr_in *sin;
02235    int res;
02236    struct msghdr m;
02237    struct sock_extended_err e;
02238    m.msg_name = NULL;
02239    m.msg_namelen = 0;
02240    m.msg_iov = NULL;
02241    m.msg_control = &e;
02242    m.msg_controllen = sizeof(e);
02243    m.msg_flags = 0;
02244    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02245    if (res < 0)
02246       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02247    else {
02248       if (m.msg_controllen) {
02249          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02250          if (sin) 
02251             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02252          else
02253             ast_log(LOG_WARNING, "No address detected??\n");
02254       } else {
02255          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02256       }
02257    }
02258 #endif
02259    return 0;
02260 }
02261 
02262 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02263 {
02264    int res;
02265    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02266                sizeof(*sin));
02267    if (res < 0) {
02268       ast_debug(1, "Received error: %s\n", strerror(errno));
02269       handle_error();
02270    } else
02271       res = 0;
02272    return res;
02273 }
02274 
02275 static int send_packet(struct iax_frame *f)
02276 {
02277    int res;
02278    int callno = f->callno;
02279 
02280    /* Don't send if there was an error, but return error instead */
02281    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02282        return -1;
02283    
02284    /* Called with iaxsl held */
02285    if (iaxdebug)
02286       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));
02287    if (f->transfer) {
02288       if (iaxdebug)
02289          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02290       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02291                sizeof(iaxs[callno]->transfer));
02292    } else {
02293       if (iaxdebug)
02294          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02295       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02296                sizeof(iaxs[callno]->addr));
02297    }
02298    if (res < 0) {
02299       if (iaxdebug)
02300          ast_debug(1, "Received error: %s\n", strerror(errno));
02301       handle_error();
02302    } else
02303       res = 0;
02304    return res;
02305 }
02306 
02307 /*!
02308  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02309  *       for the given call number may disappear during its execution.
02310  */
02311 static int iax2_predestroy(int callno)
02312 {
02313    struct ast_channel *c = NULL;
02314    struct chan_iax2_pvt *pvt = iaxs[callno];
02315 
02316    if (!pvt)
02317       return -1;
02318 
02319    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02320       iax2_destroy_helper(pvt);
02321       ast_set_flag(pvt, IAX_ALREADYGONE); 
02322    }
02323 
02324    if ((c = pvt->owner)) {
02325       c->tech_pvt = NULL;
02326       iax2_queue_hangup(callno);
02327       pvt->owner = NULL;
02328       ast_module_unref(ast_module_info->self);
02329    }
02330 
02331    return 0;
02332 }
02333 
02334 static void iax2_destroy(int callno)
02335 {
02336    struct chan_iax2_pvt *pvt = NULL;
02337    struct ast_channel *owner = NULL;
02338 
02339 retry:
02340    pvt = iaxs[callno];
02341    lastused[callno] = ast_tvnow();
02342    
02343    owner = pvt ? pvt->owner : NULL;
02344 
02345    if (owner) {
02346       if (ast_channel_trylock(owner)) {
02347          ast_debug(3, "Avoiding IAX destroy deadlock\n");
02348          ast_mutex_unlock(&iaxsl[callno]);
02349          usleep(1);
02350          ast_mutex_lock(&iaxsl[callno]);
02351          goto retry;
02352       }
02353    }
02354 
02355    if (!owner) {
02356       iaxs[callno] = NULL;
02357    }
02358 
02359    if (pvt) {
02360       if (!owner) {
02361          pvt->owner = NULL;
02362       } else {
02363          /* If there's an owner, prod it to give up */
02364          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
02365           * because we already hold the owner channel lock. */
02366          ast_queue_hangup(owner);
02367       }
02368 
02369       if (pvt->peercallno) {
02370          remove_by_peercallno(pvt);
02371       }
02372 
02373       if (pvt->transfercallno) {
02374          remove_by_transfercallno(pvt);
02375       }
02376 
02377       if (!owner) {
02378          ao2_ref(pvt, -1);
02379          pvt = NULL;
02380       }
02381    }
02382 
02383    if (owner) {
02384       ast_channel_unlock(owner);
02385    }
02386 
02387    if (callno & 0x4000) {
02388       update_max_trunk();
02389    }
02390 }
02391 
02392 static int update_packet(struct iax_frame *f)
02393 {
02394    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02395    struct ast_iax2_full_hdr *fh = f->data;
02396    struct ast_frame af;
02397 
02398    /* if frame is encrypted. decrypt before updating it. */
02399    if (f->encmethods) {
02400       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02401    }
02402    /* Mark this as a retransmission */
02403    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02404    /* Update iseqno */
02405    f->iseqno = iaxs[f->callno]->iseqno;
02406    fh->iseqno = f->iseqno;
02407 
02408    /* Now re-encrypt the frame */
02409    if (f->encmethods) {
02410    /* since this is a retransmit frame, create a new random padding
02411     * before re-encrypting. */
02412       build_rand_pad(f->semirand, sizeof(f->semirand));
02413       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02414    }
02415    return 0;
02416 }
02417 
02418 static int attempt_transmit(const void *data);
02419 static void __attempt_transmit(const void *data)
02420 {
02421    /* Attempt to transmit the frame to the remote peer...
02422       Called without iaxsl held. */
02423    struct iax_frame *f = (struct iax_frame *)data;
02424    int freeme = 0;
02425    int callno = f->callno;
02426    /* Make sure this call is still active */
02427    if (callno) 
02428       ast_mutex_lock(&iaxsl[callno]);
02429    if (callno && iaxs[callno]) {
02430       if ((f->retries < 0) /* Already ACK'd */ ||
02431           (f->retries >= max_retries) /* Too many attempts */) {
02432             /* Record an error if we've transmitted too many times */
02433             if (f->retries >= max_retries) {
02434                if (f->transfer) {
02435                   /* Transfer timeout */
02436                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02437                } else if (f->final) {
02438                   if (f->final) 
02439                      iax2_destroy(callno);
02440                } else {
02441                   if (iaxs[callno]->owner)
02442                      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);
02443                   iaxs[callno]->error = ETIMEDOUT;
02444                   if (iaxs[callno]->owner) {
02445                      struct ast_frame fr = { 0, };
02446                      /* Hangup the fd */
02447                      fr.frametype = AST_FRAME_CONTROL;
02448                      fr.subclass = AST_CONTROL_HANGUP;
02449                      iax2_queue_frame(callno, &fr); /* XXX */
02450                      /* Remember, owner could disappear */
02451                      if (iaxs[callno] && iaxs[callno]->owner)
02452                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02453                   } else {
02454                      if (iaxs[callno]->reg) {
02455                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02456                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02457                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02458                      }
02459                      iax2_destroy(callno);
02460                   }
02461                }
02462 
02463             }
02464             freeme = 1;
02465       } else {
02466          /* Update it if it needs it */
02467          update_packet(f);
02468          /* Attempt transmission */
02469          send_packet(f);
02470          f->retries++;
02471          /* Try again later after 10 times as long */
02472          f->retrytime *= 10;
02473          if (f->retrytime > MAX_RETRY_TIME)
02474             f->retrytime = MAX_RETRY_TIME;
02475          /* Transfer messages max out at one second */
02476          if (f->transfer && (f->retrytime > 1000))
02477             f->retrytime = 1000;
02478          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02479       }
02480    } else {
02481       /* Make sure it gets freed */
02482       f->retries = -1;
02483       freeme = 1;
02484    }
02485    if (callno)
02486       ast_mutex_unlock(&iaxsl[callno]);
02487    /* Do not try again */
02488    if (freeme) {
02489       /* Don't attempt delivery, just remove it from the queue */
02490       AST_LIST_LOCK(&frame_queue);
02491       AST_LIST_REMOVE(&frame_queue, f, list);
02492       AST_LIST_UNLOCK(&frame_queue);
02493       f->retrans = -1;
02494       /* Free the IAX frame */
02495       iax2_frame_free(f);
02496    }
02497 }
02498 
02499 static int attempt_transmit(const void *data)
02500 {
02501 #ifdef SCHED_MULTITHREADED
02502    if (schedule_action(__attempt_transmit, data))
02503 #endif      
02504       __attempt_transmit(data);
02505    return 0;
02506 }
02507 
02508 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02509 {
02510    struct iax2_peer *peer = NULL;
02511    struct iax2_user *user = NULL;
02512 
02513    switch (cmd) {
02514    case CLI_INIT:
02515       e->command = "iax2 prune realtime";
02516       e->usage =
02517          "Usage: iax2 prune realtime [<peername>|all]\n"
02518          "       Prunes object(s) from the cache\n";
02519       return NULL;
02520    case CLI_GENERATE:
02521       return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
02522    }
02523    if (a->argc != 4)
02524         return CLI_SHOWUSAGE;
02525    if (!strcmp(a->argv[3], "all")) {
02526       prune_users();
02527       prune_peers();
02528       ast_cli(a->fd, "Cache flushed successfully.\n");
02529       return CLI_SUCCESS;
02530    }
02531    peer = find_peer(a->argv[3], 0);
02532    user = find_user(a->argv[3]);
02533    if (peer || user) {
02534       if (peer) {
02535          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02536             ast_set_flag(peer, IAX_RTAUTOCLEAR);
02537             expire_registry(peer_ref(peer));
02538             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
02539          } else {
02540             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
02541          }
02542          peer_unref(peer);
02543       }
02544       if (user) {
02545          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02546             ast_set_flag(user, IAX_RTAUTOCLEAR);
02547             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
02548          } else {
02549             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
02550          }
02551          ao2_unlink(users,user);
02552          user_unref(user);
02553       }
02554    } else {
02555       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
02556    }
02557 
02558    return CLI_SUCCESS;
02559 }
02560 
02561 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02562 {
02563    switch (cmd) {
02564    case CLI_INIT:
02565       e->command = "iax2 test losspct";
02566       e->usage =
02567          "Usage: iax2 test losspct <percentage>\n"
02568          "       For testing, throws away <percentage> percent of incoming packets\n";
02569       return NULL;
02570    case CLI_GENERATE:
02571       return NULL;
02572    }
02573    if (a->argc != 4)
02574       return CLI_SHOWUSAGE;
02575 
02576    test_losspct = atoi(a->argv[3]);
02577 
02578    return CLI_SUCCESS;
02579 }
02580 
02581 #ifdef IAXTESTS
02582 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02583 {
02584    switch (cmd) {
02585    case CLI_INIT:
02586       e->command = "iax2 test late";
02587       e->usage =
02588          "Usage: iax2 test late <ms>\n"
02589          "       For testing, count the next frame as <ms> ms late\n";
02590       return NULL;
02591    case CLI_GENERATE:
02592       return NULL;
02593    }
02594 
02595    if (a->argc != 4)
02596       return CLI_SHOWUSAGE;
02597 
02598    test_late = atoi(a->argv[3]);
02599 
02600    return CLI_SUCCESS;
02601 }
02602 
02603 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02604 {
02605    switch (cmd) {
02606    case CLI_INIT:
02607       e->command = "iax2 test resync";
02608       e->usage =
02609          "Usage: iax2 test resync <ms>\n"
02610          "       For testing, adjust all future frames by <ms> ms\n";
02611       return NULL;
02612    case CLI_GENERATE:
02613       return NULL;
02614    }
02615 
02616    if (a->argc != 4)
02617       return CLI_SHOWUSAGE;
02618 
02619    test_resync = atoi(a->argv[3]);
02620 
02621    return CLI_SUCCESS;
02622 }
02623 
02624 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02625 {
02626    switch (cmd) {
02627    case CLI_INIT:
02628       e->command = "iax2 test jitter";
02629       e->usage =
02630          "Usage: iax2 test jitter <ms> <pct>\n"
02631          "       For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
02632          "       percentage of packets. If <pct> is not specified, adds\n"
02633          "       jitter to all packets.\n";
02634       return NULL;
02635    case CLI_GENERATE:
02636       return NULL;
02637    }
02638 
02639    if (a->argc < 4 || a->argc > 5)
02640       return CLI_SHOWUSAGE;
02641 
02642    test_jit = atoi(a->argv[3]);
02643    if (a->argc == 5)
02644       test_jitpct = atoi(a->argv[4]);
02645 
02646    return CLI_SUCCESS;
02647 }
02648 #endif /* IAXTESTS */
02649 
02650 /*! \brief  peer_status: Report Peer status in character string */
02651 /*    returns 1 if peer is online, -1 if unmonitored */
02652 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02653 {
02654    int res = 0;
02655    if (peer->maxms) {
02656       if (peer->lastms < 0) {
02657          ast_copy_string(status, "UNREACHABLE", statuslen);
02658       } else if (peer->lastms > peer->maxms) {
02659          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02660          res = 1;
02661       } else if (peer->lastms) {
02662          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02663          res = 1;
02664       } else {
02665          ast_copy_string(status, "UNKNOWN", statuslen);
02666       }
02667    } else { 
02668       ast_copy_string(status, "Unmonitored", statuslen);
02669       res = -1;
02670    }
02671    return res;
02672 }
02673 
02674 /*! \brief Show one peer in detail */
02675 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02676 {
02677    char status[30];
02678    char cbuf[256];
02679    struct iax2_peer *peer;
02680    char codec_buf[512];
02681    int x = 0, codec = 0, load_realtime = 0;
02682 
02683    switch (cmd) {
02684    case CLI_INIT:
02685       e->command = "iax2 show peer";
02686       e->usage =
02687          "Usage: iax2 show peer <name>\n"
02688          "       Display details on specific IAX peer\n";
02689       return NULL;
02690    case CLI_GENERATE:
02691       return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
02692    }
02693 
02694    if (a->argc < 4)
02695       return CLI_SHOWUSAGE;
02696 
02697    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
02698 
02699    peer = find_peer(a->argv[3], load_realtime);
02700    if (peer) {
02701       ast_cli(a->fd, "\n\n");
02702       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
02703       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
02704       ast_cli(a->fd, "  Context      : %s\n", peer->context);
02705       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
02706       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
02707       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
02708       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02709       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
02710       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
02711       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));
02712       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02713       ast_cli(a->fd, "  Username     : %s\n", peer->username);
02714       ast_cli(a->fd, "  Codecs       : ");
02715       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02716       ast_cli(a->fd, "%s\n", codec_buf);
02717 
02718       ast_cli(a->fd, "  Codec Order  : (");
02719       for(x = 0; x < 32 ; x++) {
02720          codec = ast_codec_pref_index(&peer->prefs,x);
02721          if(!codec)
02722             break;
02723          ast_cli(a->fd, "%s", ast_getformatname(codec));
02724          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02725             ast_cli(a->fd, "|");
02726       }
02727 
02728       if (!x)
02729          ast_cli(a->fd, "none");
02730       ast_cli(a->fd, ")\n");
02731 
02732       ast_cli(a->fd, "  Status       : ");
02733       peer_status(peer, status, sizeof(status));   
02734       ast_cli(a->fd, "%s\n",status);
02735       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");
02736       ast_cli(a->fd, "\n");
02737       peer_unref(peer);
02738    } else {
02739       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
02740       ast_cli(a->fd, "\n");
02741    }
02742 
02743    return CLI_SUCCESS;
02744 }
02745 
02746 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02747 {
02748    int which = 0;
02749    struct iax2_peer *peer;
02750    char *res = NULL;
02751    int wordlen = strlen(word);
02752    struct ao2_iterator i;
02753 
02754    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02755    if (pos != 3)
02756       return NULL;
02757 
02758    i = ao2_iterator_init(peers, 0);
02759    while ((peer = ao2_iterator_next(&i))) {
02760       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02761          res = ast_strdup(peer->name);
02762          peer_unref(peer);
02763          break;
02764       }
02765       peer_unref(peer);
02766    }
02767 
02768    return res;
02769 }
02770 
02771 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02772 {
02773    struct iax_frame *cur;
02774    int cnt = 0, dead = 0, final = 0;
02775 
02776    switch (cmd) {
02777    case CLI_INIT:
02778       e->command = "iax2 show stats";
02779       e->usage =
02780          "Usage: iax2 show stats\n"
02781          "       Display statistics on IAX channel driver.\n";
02782       return NULL;
02783    case CLI_GENERATE:
02784       return NULL;
02785    }
02786 
02787    if (a->argc != 3)
02788       return CLI_SHOWUSAGE;
02789 
02790    AST_LIST_LOCK(&frame_queue);
02791    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
02792       if (cur->retries < 0)
02793          dead++;
02794       if (cur->final)
02795          final++;
02796       cnt++;
02797    }
02798    AST_LIST_UNLOCK(&frame_queue);
02799 
02800    ast_cli(a->fd, "    IAX Statistics\n");
02801    ast_cli(a->fd, "---------------------\n");
02802    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02803    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
02804       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
02805    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02806 
02807    trunk_timed = trunk_untimed = 0;
02808    if (trunk_maxmtu > trunk_nmaxmtu)
02809       trunk_nmaxmtu = trunk_maxmtu;
02810 
02811    return CLI_SUCCESS;
02812 }
02813 
02814 /*! \brief Set trunk MTU from CLI */
02815 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02816 {
02817    int mtuv;
02818 
02819    switch (cmd) {
02820    case CLI_INIT:
02821       e->command = "iax2 set mtu";
02822       e->usage =
02823          "Usage: iax2 set mtu <value>\n"
02824          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
02825          "       zero to disable. Disabling means that the operating system\n"
02826          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
02827          "       packet exceeds the UDP payload size. This is substantially\n"
02828          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
02829          "       greater for G.711 samples.\n";
02830       return NULL;
02831    case CLI_GENERATE:
02832       return NULL;
02833    }
02834 
02835    if (a->argc != 4)
02836       return CLI_SHOWUSAGE; 
02837    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
02838       mtuv = MAX_TRUNK_MTU;
02839    else
02840       mtuv = atoi(a->argv[3]);
02841 
02842    if (mtuv == 0) {
02843       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
02844       global_max_trunk_mtu = 0; 
02845       return CLI_SUCCESS; 
02846    }
02847    if (mtuv < 172 || mtuv > 4000) {
02848       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
02849       return CLI_SHOWUSAGE; 
02850    }
02851    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
02852    global_max_trunk_mtu = mtuv; 
02853    return CLI_SUCCESS;
02854 }
02855 
02856 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02857 {
02858    struct iax2_dpcache *dp = NULL;
02859    char tmp[1024], *pc = NULL;
02860    int s, x, y;
02861    struct timeval tv = ast_tvnow();
02862 
02863    switch (cmd) {
02864    case CLI_INIT:
02865       e->command = "iax2 show cache";
02866       e->usage =
02867          "Usage: iax2 show cache\n"
02868          "       Display currently cached IAX Dialplan results.\n";
02869       return NULL;
02870    case CLI_GENERATE:
02871       return NULL;
02872    }
02873 
02874    AST_LIST_LOCK(&dpcache);
02875 
02876    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02877 
02878    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
02879       s = dp->expiry.tv_sec - tv.tv_sec;
02880       tmp[0] = '\0';
02881       if (dp->flags & CACHE_FLAG_EXISTS)
02882          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02883       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02884          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02885       if (dp->flags & CACHE_FLAG_CANEXIST)
02886          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02887       if (dp->flags & CACHE_FLAG_PENDING)
02888          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02889       if (dp->flags & CACHE_FLAG_TIMEOUT)
02890          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02891       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02892          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02893       if (dp->flags & CACHE_FLAG_MATCHMORE)
02894          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02895       if (dp->flags & CACHE_FLAG_UNKNOWN)
02896          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02897       /* Trim trailing pipe */
02898       if (!ast_strlen_zero(tmp)) {
02899          tmp[strlen(tmp) - 1] = '\0';
02900       } else {
02901          ast_copy_string(tmp, "(none)", sizeof(tmp));
02902       }
02903       y = 0;
02904       pc = strchr(dp->peercontext, '@');
02905       if (!pc) {
02906          pc = dp->peercontext;
02907       } else {
02908          pc++;
02909       }
02910       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
02911          if (dp->waiters[x] > -1)
02912             y++;
02913       }
02914       if (s > 0) {
02915          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02916       } else {
02917          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02918       }
02919    }
02920 
02921    AST_LIST_LOCK(&dpcache);
02922 
02923    return CLI_SUCCESS;
02924 }
02925 
02926 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02927 
02928 static void unwrap_timestamp(struct iax_frame *fr)
02929 {
02930    /* Video mini frames only encode the lower 15 bits of the session
02931     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
02932    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02933    const int lower_mask = (1 << ts_shift) - 1;
02934    const int upper_mask = ~lower_mask;
02935    const int last_upper = iaxs[fr->callno]->last & upper_mask;
02936 
02937    if ( (fr->ts & upper_mask) == last_upper ) {
02938       const int x = fr->ts - iaxs[fr->callno]->last;
02939       const int threshold = (ts_shift == 15) ? 25000 : 50000;
02940 
02941       if (x < -threshold) {
02942          /* Sudden big jump backwards in timestamp:
02943             What likely happened here is that miniframe timestamp has circled but we haven't
02944             gotten the update from the main packet.  We'll just pretend that we did, and
02945             update the timestamp appropriately. */
02946          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02947          if (iaxdebug)
02948             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
02949       } else if (x > threshold) {
02950          /* Sudden apparent big jump forwards in timestamp:
02951             What's likely happened is this is an old miniframe belonging to the previous
02952             top 15 or 16-bit timestamp that has turned up out of order.
02953             Adjust the timestamp appropriately. */
02954          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02955          if (iaxdebug)
02956             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
02957       }
02958    }
02959 }
02960 
02961 static int get_from_jb(const void *p);
02962 
02963 static void update_jbsched(struct chan_iax2_pvt *pvt)
02964 {
02965    int when;
02966    
02967    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02968    
02969    when = jb_next(pvt->jb) - when;
02970 
02971    if (when <= 0) {
02972       /* XXX should really just empty until when > 0.. */
02973       when = 1;
02974    }
02975    
02976    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
02977       CALLNO_TO_PTR(pvt->callno));
02978 }
02979 
02980 static void __get_from_jb(const void *p) 
02981 {
02982    int callno = PTR_TO_CALLNO(p);
02983    struct chan_iax2_pvt *pvt = NULL;
02984    struct iax_frame *fr;
02985    jb_frame frame;
02986    int ret;
02987    long now;
02988    long next;
02989    struct timeval tv = ast_tvnow();
02990    
02991    /* Make sure we have a valid private structure before going on */
02992    ast_mutex_lock(&iaxsl[callno]);
02993    pvt = iaxs[callno];
02994    if (!pvt) {
02995       /* No go! */
02996       ast_mutex_unlock(&iaxsl[callno]);
02997       return;
02998    }
02999 
03000    pvt->jbid = -1;
03001    
03002    /* round up a millisecond since ast_sched_runq does; */
03003    /* prevents us from spinning while waiting for our now */
03004    /* to catch up with runq's now */
03005    tv.tv_usec += 1000;
03006    
03007    now = ast_tvdiff_ms(tv, pvt->rxcore);
03008    
03009    if(now >= (next = jb_next(pvt->jb))) {
03010       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
03011       switch(ret) {
03012       case JB_OK:
03013          fr = frame.data;
03014          __do_deliver(fr);
03015          /* __do_deliver() can cause the call to disappear */
03016          pvt = iaxs[callno];
03017          break;
03018       case JB_INTERP:
03019       {
03020          struct ast_frame af = { 0, };
03021          
03022          /* create an interpolation frame */
03023          af.frametype = AST_FRAME_VOICE;
03024          af.subclass = pvt->voiceformat;
03025          af.samples  = frame.ms * 8;
03026          af.src  = "IAX2 JB interpolation";
03027          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03028          af.offset = AST_FRIENDLY_OFFSET;
03029          
03030          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03031           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03032          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03033             iax2_queue_frame(callno, &af);
03034             /* iax2_queue_frame() could cause the call to disappear */
03035             pvt = iaxs[callno];
03036          }
03037       }
03038          break;
03039       case JB_DROP:
03040          iax2_frame_free(frame.data);
03041          break;
03042       case JB_NOFRAME:
03043       case JB_EMPTY:
03044          /* do nothing */
03045          break;
03046       default:
03047          /* shouldn't happen */
03048          break;
03049       }
03050    }
03051    if (pvt)
03052       update_jbsched(pvt);
03053    ast_mutex_unlock(&iaxsl[callno]);
03054 }
03055 
03056 static int get_from_jb(const void *data)
03057 {
03058 #ifdef SCHED_MULTITHREADED
03059    if (schedule_action(__get_from_jb, data))
03060 #endif      
03061       __get_from_jb(data);
03062    return 0;
03063 }
03064 
03065 /*!
03066  * \note This function assumes fr->callno is locked
03067  *
03068  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
03069  * was valid before calling it, it may no longer be valid after calling it.
03070  */
03071 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03072 {
03073    int type, len;
03074    int ret;
03075    int needfree = 0;
03076    struct ast_channel *owner = NULL;
03077    struct ast_channel *bridge = NULL;
03078    
03079    /* Attempt to recover wrapped timestamps */
03080    unwrap_timestamp(fr);
03081 
03082    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
03083    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03084       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03085    else {
03086 #if 0
03087       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03088 #endif
03089       fr->af.delivery = ast_tv(0,0);
03090    }
03091 
03092    type = JB_TYPE_CONTROL;
03093    len = 0;
03094 
03095    if(fr->af.frametype == AST_FRAME_VOICE) {
03096       type = JB_TYPE_VOICE;
03097       len = ast_codec_get_samples(&fr->af) / 8;
03098    } else if(fr->af.frametype == AST_FRAME_CNG) {
03099       type = JB_TYPE_SILENCE;
03100    }
03101 
03102    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03103       if (tsout)
03104          *tsout = fr->ts;
03105       __do_deliver(fr);
03106       return -1;
03107    }
03108 
03109    if ((owner = iaxs[fr->callno]->owner))
03110       bridge = ast_bridged_channel(owner);
03111 
03112    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
03113     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
03114    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03115       jb_frame frame;
03116 
03117       /* deliver any frames in the jb */
03118       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03119          __do_deliver(frame.data);
03120          /* __do_deliver() can make the call disappear */
03121          if (!iaxs[fr->callno])
03122             return -1;
03123       }
03124 
03125       jb_reset(iaxs[fr->callno]->jb);
03126 
03127       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03128 
03129       /* deliver this frame now */
03130       if (tsout)
03131          *tsout = fr->ts;
03132       __do_deliver(fr);
03133       return -1;
03134    }
03135 
03136    /* insert into jitterbuffer */
03137    /* TODO: Perhaps we could act immediately if it's not droppable and late */
03138    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03139          calc_rxstamp(iaxs[fr->callno],fr->ts));
03140    if (ret == JB_DROP) {
03141       needfree++;
03142    } else if (ret == JB_SCHED) {
03143       update_jbsched(iaxs[fr->callno]);
03144    }
03145    if (tsout)
03146       *tsout = fr->ts;
03147    if (needfree) {
03148       /* Free our iax frame */
03149       iax2_frame_free(fr);
03150       return -1;
03151    }
03152    return 0;
03153 }
03154 
03155 static int iax2_transmit(struct iax_frame *fr)
03156 {
03157    /* Lock the queue and place this packet at the end */
03158    /* By setting this to 0, the network thread will send it for us, and
03159       queue retransmission if necessary */
03160    fr->sentyet = 0;
03161    AST_LIST_LOCK(&frame_queue);
03162    AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03163    AST_LIST_UNLOCK(&frame_queue);
03164    /* Wake up the network and scheduler thread */
03165    if (netthreadid != AST_PTHREADT_NULL)
03166       pthread_kill(netthreadid, SIGURG);
03167    signal_condition(&sched_lock, &sched_cond);
03168    return 0;
03169 }
03170 
03171 
03172 
03173 static int iax2_digit_begin(struct ast_channel *c, char digit)
03174 {
03175    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03176 }
03177 
03178 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03179 {
03180    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03181 }
03182 
03183 static int iax2_sendtext(struct ast_channel *c, const char *text)
03184 {
03185    
03186    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03187       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03188 }
03189 
03190 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03191 {
03192    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
03193 }
03194 
03195 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03196 {
03197    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03198 }
03199 
03200 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03201 {
03202    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03203    ast_mutex_lock(&iaxsl[callno]);
03204    if (iaxs[callno])
03205       iaxs[callno]->owner = newchan;
03206    else
03207       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03208    ast_mutex_unlock(&iaxsl[callno]);
03209    return 0;
03210 }
03211 
03212 /*!
03213  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
03214  *       so do not call this with a pvt lock held.
03215  */
03216 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03217 {
03218    struct ast_variable *var = NULL;
03219    struct ast_variable *tmp;
03220    struct iax2_peer *peer=NULL;
03221    time_t regseconds = 0, nowtime;
03222    int dynamic=0;
03223 
03224    if (peername) {
03225       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
03226       if (!var && sin)
03227          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03228    } else if (sin) {
03229       char porta[25];
03230       sprintf(porta, "%d", ntohs(sin->sin_port));
03231       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03232       if (var) {
03233          /* We'll need the peer name in order to build the structure! */
03234          for (tmp = var; tmp; tmp = tmp->next) {
03235             if (!strcasecmp(tmp->name, "name"))
03236                peername = tmp->value;
03237          }
03238       }
03239    }
03240    if (!var && peername) { /* Last ditch effort */
03241       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
03242       /*!\note
03243        * If this one loaded something, then we need to ensure that the host
03244        * field matched.  The only reason why we can't have this as a criteria
03245        * is because we only have the IP address and the host field might be
03246        * set as a name (and the reverse PTR might not match).
03247        */
03248       if (var && sin) {
03249          for (tmp = var; tmp; tmp = tmp->next) {
03250             if (!strcasecmp(tmp->name, "host")) {
03251                struct ast_hostent ahp;
03252                struct hostent *hp;
03253                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03254                   /* No match */
03255                   ast_variables_destroy(var);
03256                   var = NULL;
03257                }
03258                break;
03259             }
03260          }
03261       }
03262    }
03263    if (!var)
03264       return NULL;
03265 
03266    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03267    
03268    if (!peer) {
03269       ast_variables_destroy(var);
03270       return NULL;
03271    }
03272 
03273    for (tmp = var; tmp; tmp = tmp->next) {
03274       /* Make sure it's not a user only... */
03275       if (!strcasecmp(tmp->name, "type")) {
03276          if (strcasecmp(tmp->value, "friend") &&
03277              strcasecmp(tmp->value, "peer")) {
03278             /* Whoops, we weren't supposed to exist! */
03279             peer = peer_unref(peer);
03280             break;
03281          } 
03282       } else if (!strcasecmp(tmp->name, "regseconds")) {
03283          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
03284       } else if (!strcasecmp(tmp->name, "ipaddr")) {
03285          inet_aton(tmp->value, &(peer->addr.sin_addr));
03286       } else if (!strcasecmp(tmp->name, "port")) {
03287          peer->addr.sin_port = htons(atoi(tmp->value));
03288       } else if (!strcasecmp(tmp->name, "host")) {
03289          if (!strcasecmp(tmp->value, "dynamic"))
03290             dynamic = 1;
03291       }
03292    }
03293 
03294    ast_variables_destroy(var);
03295 
03296    if (!peer)
03297       return NULL;
03298 
03299    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03300       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03301       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03302          if (peer->expire > -1) {
03303             if (!ast_sched_del(sched, peer->expire)) {
03304                peer->expire = -1;
03305                peer_unref(peer);
03306             }
03307          }
03308          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03309          if (peer->expire == -1)
03310             peer_unref(peer);
03311       }
03312       ao2_link(peers, peer);
03313       if (ast_test_flag(peer, IAX_DYNAMIC))
03314          reg_source_db(peer);
03315    } else {
03316       ast_set_flag(peer, IAX_TEMPONLY);   
03317    }
03318 
03319    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03320       time(&nowtime);
03321       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03322          memset(&peer->addr, 0, sizeof(peer->addr));
03323          realtime_update_peer(peer->name, &peer->addr, 0);
03324          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03325             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03326       }
03327       else {
03328          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03329             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03330       }
03331    }
03332 
03333    return peer;
03334 }
03335 
03336 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03337 {
03338    struct ast_variable *var;
03339    struct ast_variable *tmp;
03340    struct iax2_user *user=NULL;
03341 
03342    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03343    if (!var)
03344       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03345    if (!var && sin) {
03346       char porta[6];
03347       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03348       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03349       if (!var)
03350          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03351    }
03352    if (!var) { /* Last ditch effort */
03353       var = ast_load_realtime("iaxusers", "name", username, NULL);
03354       /*!\note
03355        * If this one loaded something, then we need to ensure that the host
03356        * field matched.  The only reason why we can't have this as a criteria
03357        * is because we only have the IP address and the host field might be
03358        * set as a name (and the reverse PTR might not match).
03359        */
03360       if (var) {
03361          for (tmp = var; tmp; tmp = tmp->next) {
03362             if (!strcasecmp(tmp->name, "host")) {
03363                struct ast_hostent ahp;
03364                struct hostent *hp;
03365                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03366                   /* No match */
03367                   ast_variables_destroy(var);
03368                   var = NULL;
03369                }
03370                break;
03371             }
03372          }
03373       }
03374    }
03375    if (!var)
03376       return NULL;
03377 
03378    tmp = var;
03379    while(tmp) {
03380       /* Make sure it's not a peer only... */
03381       if (!strcasecmp(tmp->name, "type")) {
03382          if (strcasecmp(tmp->value, "friend") &&
03383              strcasecmp(tmp->value, "user")) {
03384             return NULL;
03385          } 
03386       }
03387       tmp = tmp->next;
03388    }
03389 
03390    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03391 
03392    ast_variables_destroy(var);
03393 
03394    if (!user)
03395       return NULL;
03396 
03397    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03398       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03399       ao2_link(users, user);
03400    } else {
03401       ast_set_flag(user, IAX_TEMPONLY);   
03402    }
03403 
03404    return user;
03405 }
03406 
03407 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03408 {
03409    char port[10];
03410    char regseconds[20];
03411    
03412    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03413    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03414    ast_update_realtime("iaxpeers", "name", peername, 
03415       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03416       "regseconds", regseconds, NULL);
03417 }
03418 
03419 struct create_addr_info {
03420    int capability;
03421    unsigned int flags;
03422    int maxtime;
03423    int encmethods;
03424    int found;
03425    int sockfd;
03426    int adsi;
03427    char username[80];
03428    char secret[80];
03429    char outkey[80];
03430    char timezone[80];
03431    char prefs[32];
03432    char context[AST_MAX_CONTEXT];
03433    char peercontext[AST_MAX_CONTEXT];
03434    char mohinterpret[MAX_MUSICCLASS];
03435    char mohsuggest[MAX_MUSICCLASS];
03436 };
03437 
03438 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03439 {
03440    struct iax2_peer *peer;
03441    int res = -1;
03442    struct ast_codec_pref ourprefs;
03443 
03444    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03445    cai->sockfd = defaultsockfd;
03446    cai->maxtime = 0;
03447    sin->sin_family = AF_INET;
03448 
03449    if (!(peer = find_peer(peername, 1))) {
03450       cai->found = 0;
03451       if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
03452          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03453          return -1;
03454       }
03455       sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03456       /* use global iax prefs for unknown peer/user */
03457       /* But move the calling channel's native codec to the top of the preference list */
03458       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03459       if (c)
03460          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03461       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03462       return 0;
03463    }
03464 
03465    cai->found = 1;
03466    
03467    /* if the peer has no address (current or default), return failure */
03468    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03469       goto return_unref;
03470 
03471    /* if the peer is being monitored and is currently unreachable, return failure */
03472    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03473       goto return_unref;
03474 
03475    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03476    cai->maxtime = peer->maxms;
03477    cai->capability = peer->capability;
03478    cai->encmethods = peer->encmethods;
03479    cai->sockfd = peer->sockfd;
03480    cai->adsi = peer->adsi;
03481    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03482    /* Move the calling channel's native codec to the top of the preference list */
03483    if (c) {
03484       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03485       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03486    }
03487    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03488    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03489    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03490    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03491    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03492    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03493    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03494    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03495    if (ast_strlen_zero(peer->dbsecret)) {
03496       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03497    } else {
03498       char *family;
03499       char *key = NULL;
03500 
03501       family = ast_strdupa(peer->dbsecret);
03502       key = strchr(family, '/');
03503       if (key)
03504          *key++ = '\0';
03505       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03506          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03507          goto return_unref;
03508       }
03509    }
03510 
03511    if (peer->addr.sin_addr.s_addr) {
03512       sin->sin_addr = peer->addr.sin_addr;
03513       sin->sin_port = peer->addr.sin_port;
03514    } else {
03515       sin->sin_addr = peer->defaddr.sin_addr;
03516       sin->sin_port = peer->defaddr.sin_port;
03517    }
03518 
03519    res = 0;
03520 
03521 return_unref:
03522    peer_unref(peer);
03523 
03524    return res;
03525 }
03526 
03527 static void __auto_congest(const void *nothing)
03528 {
03529    int callno = PTR_TO_CALLNO(nothing);
03530    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03531    ast_mutex_lock(&iaxsl[callno]);
03532    if (iaxs[callno]) {
03533       iaxs[callno]->initid = -1;
03534       iax2_queue_frame(callno, &f);
03535       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03536    }
03537    ast_mutex_unlock(&iaxsl[callno]);
03538 }
03539 
03540 static int auto_congest(const void *data)
03541 {
03542 #ifdef SCHED_MULTITHREADED
03543    if (schedule_action(__auto_congest, data))
03544 #endif      
03545       __auto_congest(data);
03546    return 0;
03547 }
03548 
03549 static unsigned int iax2_datetime(const char *tz)
03550 {
03551    struct timeval t = ast_tvnow();
03552    struct ast_tm tm;
03553    unsigned int tmp;
03554    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
03555    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03556    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03557    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03558    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03559    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03560    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03561    return tmp;
03562 }
03563 
03564 struct parsed_dial_string {
03565    char *username;
03566    char *password;
03567    char *key;
03568    char *peer;
03569    char *port;
03570    char *exten;
03571    char *context;
03572    char *options;
03573 };
03574 
03575 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03576 {
03577    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03578       .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03579       .csub = compress_subclass(command) };
03580 
03581    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03582 }
03583 
03584 /*!
03585  * \brief Parses an IAX dial string into its component parts.
03586  * \param data the string to be parsed
03587  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03588  * \return nothing
03589  *
03590  * This function parses the string and fills the structure
03591  * with pointers to its component parts. The input string
03592  * will be modified.
03593  *
03594  * \note This function supports both plaintext passwords and RSA
03595  * key names; if the password string is formatted as '[keyname]',
03596  * then the keyname will be placed into the key field, and the
03597  * password field will be set to NULL.
03598  *
03599  * \note The dial string format is:
03600  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03601  */
03602 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03603 {
03604    if (ast_strlen_zero(data))
03605       return;
03606 
03607    pds->peer = strsep(&data, "/");
03608    pds->exten = strsep(&data, "/");
03609    pds->options = data;
03610 
03611    if (pds->exten) {
03612       data = pds->exten;
03613       pds->exten = strsep(&data, "@");
03614       pds->context = data;
03615    }
03616 
03617    if (strchr(pds->peer, '@')) {
03618       data = pds->peer;
03619       pds->username = strsep(&data, "@");
03620       pds->peer = data;
03621    }
03622 
03623    if (pds->username) {
03624       data = pds->username;
03625       pds->username = strsep(&data, ":");
03626       pds->password = data;
03627    }
03628 
03629    data = pds->peer;
03630    pds->peer = strsep(&data, ":");
03631    pds->port = data;
03632 
03633    /* check for a key name wrapped in [] in the secret position, if found,
03634       move it to the key field instead
03635    */
03636    if (pds->password && (pds->password[0] == '[')) {
03637       pds->key = ast_strip_quoted(pds->password, "[", "]");
03638       pds->password = NULL;
03639    }
03640 }
03641 
03642 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03643 {
03644    struct sockaddr_in sin;
03645    char *l=NULL, *n=NULL, *tmpstr;
03646    struct iax_ie_data ied;
03647    char *defaultrdest = "s";
03648    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03649    struct parsed_dial_string pds;
03650    struct create_addr_info cai;
03651    struct ast_var_t *var;
03652    struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
03653    const char* osp_token_ptr;
03654    unsigned int osp_token_length;
03655    unsigned char osp_block_index;
03656    unsigned int osp_block_length;
03657    unsigned char osp_buffer[256];
03658 
03659    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03660       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03661       return -1;
03662    }
03663 
03664    memset(&cai, 0, sizeof(cai));
03665    cai.encmethods = iax2_encryption;
03666 
03667    memset(&pds, 0, sizeof(pds));
03668    tmpstr = ast_strdupa(dest);
03669    parse_dial_string(tmpstr, &pds);
03670 
03671    if (ast_strlen_zero(pds.peer)) {
03672       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03673       return -1;
03674    }
03675 
03676    if (!pds.exten) {
03677       pds.exten = defaultrdest;
03678    }
03679 
03680    if (create_addr(pds.peer, c, &sin, &cai)) {
03681       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03682       return -1;
03683    }
03684 
03685    if (!pds.username && !ast_strlen_zero(cai.username))
03686       pds.username = cai.username;
03687    if (!pds.password && !ast_strlen_zero(cai.secret))
03688       pds.password = cai.secret;
03689    if (!pds.key && !ast_strlen_zero(cai.outkey))
03690       pds.key = cai.outkey;
03691    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03692       pds.context = cai.peercontext;
03693 
03694    /* Keep track of the context for outgoing calls too */
03695    ast_copy_string(c->context, cai.context, sizeof(c->context));
03696 
03697    if (pds.port)
03698       sin.sin_port = htons(atoi(pds.port));
03699 
03700    l = c->cid.cid_num;
03701    n = c->cid.cid_name;
03702 
03703    /* Now build request */ 
03704    memset(&ied, 0, sizeof(ied));
03705 
03706    /* On new call, first IE MUST be IAX version of caller */
03707    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03708    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03709    if (pds.options && strchr(pds.options, 'a')) {
03710       /* Request auto answer */
03711       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03712    }
03713 
03714    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03715 
03716    if (l) {
03717       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03718       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03719    } else {
03720       if (n)
03721          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03722       else
03723          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03724    }
03725 
03726    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03727    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03728 
03729    if (n)
03730       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03731    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03732       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03733 
03734    if (!ast_strlen_zero(c->language))
03735       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03736    if (!ast_strlen_zero(c->cid.cid_dnid))
03737       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03738    if (!ast_strlen_zero(c->cid.cid_rdnis))
03739       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03740 
03741    if (pds.context)
03742       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03743 
03744    if (pds.username)
03745       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03746 
03747    if (cai.encmethods)
03748       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03749 
03750    ast_mutex_lock(&iaxsl[callno]);
03751 
03752    if (!ast_strlen_zero(c->context))
03753       ast_string_field_set(iaxs[callno], context, c->context);
03754 
03755    if (pds.username)
03756       ast_string_field_set(iaxs[callno], username, pds.username);
03757 
03758    iaxs[callno]->encmethods = cai.encmethods;
03759 
03760    iaxs[callno]->adsi = cai.adsi;
03761    
03762    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03763    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03764 
03765    if (pds.key)
03766       ast_string_field_set(iaxs[callno], outkey, pds.key);
03767    if (pds.password)
03768       ast_string_field_set(iaxs[callno], secret, pds.password);
03769 
03770    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03771    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03772    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03773    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03774 
03775    if (iaxs[callno]->maxtime) {
03776       /* Initialize pingtime and auto-congest time */
03777       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03778       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03779    } else if (autokill) {
03780       iaxs[callno]->pingtime = autokill / 2;
03781       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03782    }
03783 
03784    /* Check if there is an OSP token set by IAXCHANINFO function */
03785    osp_token_ptr = iaxs[callno]->osptoken;
03786    if (!ast_strlen_zero(osp_token_ptr)) {
03787       if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
03788          osp_block_index = 0;
03789          while (osp_token_length > 0) {
03790             osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
03791             osp_buffer[0] = osp_block_index;
03792             memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
03793             iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
03794             osp_block_index++;
03795             osp_token_ptr += osp_block_length;
03796             osp_token_length -= osp_block_length;
03797          } 
03798       } else
03799          ast_log(LOG_WARNING, "OSP token is too long\n");
03800    } else if (iaxdebug)
03801       ast_debug(1, "OSP token is undefined\n");
03802 
03803    /* send the command using the appropriate socket for this peer */
03804    iaxs[callno]->sockfd = cai.sockfd;
03805 
03806    /* Add remote vars */
03807    if (variablestore) {
03808       AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
03809       ast_debug(1, "Found an IAX variable store on this channel\n");
03810       AST_LIST_LOCK(variablelist);
03811       AST_LIST_TRAVERSE(variablelist, var, entries) {
03812          char tmp[256];
03813          int i;
03814          ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
03815          /* Automatically divide the value up into sized chunks */
03816          for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
03817             snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
03818             iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
03819          }
03820       }
03821       AST_LIST_UNLOCK(variablelist);
03822    }
03823 
03824    /* Transmit the string in a "NEW" request */
03825    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03826 
03827    ast_mutex_unlock(&iaxsl[callno]);
03828    ast_setstate(c, AST_STATE_RINGING);
03829 
03830    return 0;
03831 }
03832 
03833 static int iax2_hangup(struct ast_channel *c) 
03834 {
03835    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03836    struct iax_ie_data ied;
03837    int alreadygone;
03838    memset(&ied, 0, sizeof(ied));
03839    ast_mutex_lock(&iaxsl[callno]);
03840    if (callno && iaxs[callno]) {
03841       ast_debug(1, "We're hanging up %s now...\n", c->name);
03842       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03843       /* Send the hangup unless we have had a transmission error or are already gone */
03844       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03845       if (!iaxs[callno]->error && !alreadygone) {
03846          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03847             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03848          }
03849          if (!iaxs[callno]) {
03850             ast_mutex_unlock(&iaxsl[callno]);
03851             return 0;
03852          }
03853       }
03854       /* Explicitly predestroy it */
03855       iax2_predestroy(callno);
03856       /* If we were already gone to begin with, destroy us now */
03857       if (iaxs[callno] && alreadygone) {
03858          ast_debug(1, "Really destroying %s now...\n", c->name);
03859          iax2_destroy(callno);
03860       } else if (iaxs[callno]) {
03861          if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
03862             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
03863             iax2_destroy(callno);
03864          }
03865       }
03866    } else if (c->tech_pvt) {
03867       /* If this call no longer exists, but the channel still
03868        * references it we need to set the channel's tech_pvt to null
03869        * to avoid ast_channel_free() trying to free it.
03870        */
03871       c->tech_pvt = NULL;
03872    }
03873    ast_mutex_unlock(&iaxsl[callno]);
03874    ast_verb(3, "Hungup '%s'\n", c->name);
03875    return 0;
03876 }
03877 
03878 /*!
03879  * \note expects the pvt to be locked
03880  */
03881 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03882 {
03883    unsigned short callno = pvt->callno;
03884 
03885    if (!pvt->peercallno) {
03886       /* We don't know the remote side's call number, yet.  :( */
03887       int count = 10;
03888       while (count-- && pvt && !pvt->peercallno) {
03889          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03890          pvt = iaxs[callno];
03891       }
03892       if (!pvt->peercallno) {
03893          return -1;
03894       }
03895    }
03896 
03897    return 0;
03898 }
03899 
03900 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03901 {
03902    struct ast_option_header *h;
03903    int res;
03904 
03905    switch (option) {
03906    case AST_OPTION_TXGAIN:
03907    case AST_OPTION_RXGAIN:
03908       /* these two cannot be sent, because they require a result */
03909       errno = ENOSYS;
03910       return -1;
03911    default:
03912    {
03913       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03914       struct chan_iax2_pvt *pvt;
03915 
03916       ast_mutex_lock(&iaxsl[callno]);
03917       pvt = iaxs[callno];
03918 
03919       if (wait_for_peercallno(pvt)) {
03920          ast_mutex_unlock(&iaxsl[callno]);
03921          return -1;
03922       }
03923 
03924       ast_mutex_unlock(&iaxsl[callno]);
03925 
03926       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03927          return -1;
03928       }
03929 
03930       h->flag = AST_OPTION_FLAG_REQUEST;
03931       h->option = htons(option);
03932       memcpy(h->data, data, datalen);
03933       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03934                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03935                  datalen + sizeof(*h), -1);
03936       ast_free(h);
03937       return res;
03938    }
03939    }
03940 }
03941 
03942 static struct ast_frame *iax2_read(struct ast_channel *c) 
03943 {
03944    ast_log(LOG_NOTICE, "I should never be called!\n");
03945    return &ast_null_frame;
03946 }
03947 
03948 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03949 {
03950    int res;
03951    struct iax_ie_data ied0;
03952    struct iax_ie_data ied1;
03953    unsigned int transferid = (unsigned int)ast_random();
03954    memset(&ied0, 0, sizeof(ied0));
03955    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03956    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03957    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03958 
03959    memset(&ied1, 0, sizeof(ied1));
03960    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03961    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03962    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03963    
03964    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03965    if (res)
03966       return -1;
03967    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03968    if (res)
03969       return -1;
03970    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03971    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03972    return 0;
03973 }
03974 
03975 static void lock_both(unsigned short callno0, unsigned short callno1)
03976 {
03977    ast_mutex_lock(&iaxsl[callno0]);
03978    while (ast_mutex_trylock(&iaxsl[callno1])) {
03979       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03980    }
03981 }
03982 
03983 static void unlock_both(unsigned short callno0, unsigned short callno1)
03984 {
03985    ast_mutex_unlock(&iaxsl[callno1]);
03986    ast_mutex_unlock(&iaxsl[callno0]);
03987 }
03988 
03989 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)
03990 {
03991    struct ast_channel *cs[3];
03992    struct ast_channel *who, *other;
03993    int to = -1;
03994    int res = -1;
03995    int transferstarted=0;
03996    struct ast_frame *f;
03997    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03998    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03999    struct timeval waittimer = {0, 0}, tv;
04000 
04001    /* We currently do not support native bridging if a timeoutms value has been provided */
04002    if (timeoutms > 0) {
04003       return AST_BRIDGE_FAILED;
04004    }
04005 
04006    timeoutms = -1;
04007 
04008    lock_both(callno0, callno1);
04009    if (!iaxs[callno0] || !iaxs[callno1]) {
04010       unlock_both(callno0, callno1);
04011       return AST_BRIDGE_FAILED;
04012    }
04013    /* Put them in native bridge mode */
04014    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04015       iaxs[callno0]->bridgecallno = callno1;
04016       iaxs[callno1]->bridgecallno = callno0;
04017    }
04018    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
04019    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
04020       transferstarted = 1;
04021    }
04022    unlock_both(callno0, callno1);
04023 
04024    /* If not, try to bridge until we can execute a transfer, if we can */
04025    cs[0] = c0;
04026    cs[1] = c1;
04027    for (/* ever */;;) {
04028       /* Check in case we got masqueraded into */
04029       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04030          ast_verb(3, "Can't masquerade, we're different...\n");
04031          /* Remove from native mode */
04032          if (c0->tech == &iax2_tech) {
04033             ast_mutex_lock(&iaxsl[callno0]);
04034             iaxs[callno0]->bridgecallno = 0;
04035             ast_mutex_unlock(&iaxsl[callno0]);
04036          }
04037          if (c1->tech == &iax2_tech) {
04038             ast_mutex_lock(&iaxsl[callno1]);
04039             iaxs[callno1]->bridgecallno = 0;
04040             ast_mutex_unlock(&iaxsl[callno1]);
04041          }
04042          return AST_BRIDGE_FAILED_NOWARN;
04043       }
04044       if (c0->nativeformats != c1->nativeformats) {
04045             char buf0[255];
04046             char buf1[255];
04047             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04048             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04049          ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04050          /* Remove from native mode */
04051          lock_both(callno0, callno1);
04052          if (iaxs[callno0])
04053             iaxs[callno0]->bridgecallno = 0;
04054          if (iaxs[callno1])
04055             iaxs[callno1]->bridgecallno = 0;
04056          unlock_both(callno0, callno1);
04057          return AST_BRIDGE_FAILED_NOWARN;
04058       }
04059       /* check if transfered and if we really want native bridging */
04060       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04061          /* Try the transfer */
04062          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04063                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04064             ast_log(LOG_WARNING, "Unable to start the transfer\n");
04065          transferstarted = 1;
04066       }
04067       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04068          /* Call has been transferred.  We're no longer involved */
04069          tv = ast_tvnow();
04070          if (ast_tvzero(waittimer)) {
04071             waittimer = tv;
04072          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04073             c0->_softhangup |= AST_SOFTHANGUP_DEV;
04074             c1->_softhangup |= AST_SOFTHANGUP_DEV;
04075             *fo = NULL;
04076             *rc = c0;
04077             res = AST_BRIDGE_COMPLETE;
04078             break;
04079          }
04080       }
04081       to = 1000;
04082       who = ast_waitfor_n(cs, 2, &to);
04083       if (timeoutms > -1) {
04084          timeoutms -= (1000 - to);
04085          if (timeoutms < 0)
04086             timeoutms = 0;
04087       }
04088       if (!who) {
04089          if (!timeoutms) {
04090             res = AST_BRIDGE_RETRY;
04091             break;
04092          }
04093          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04094             res = AST_BRIDGE_FAILED;
04095             break;
04096          }
04097          continue;
04098       }
04099       f = ast_read(who);
04100       if (!f) {
04101          *fo = NULL;
04102          *rc = who;
04103          res = AST_BRIDGE_COMPLETE;
04104          break;
04105       }
04106       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04107          *fo = f;
04108          *rc = who;
04109          res =  AST_BRIDGE_COMPLETE;
04110          break;
04111       }
04112       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
04113       if ((f->frametype == AST_FRAME_VOICE) ||
04114          (f->frametype == AST_FRAME_TEXT) ||
04115          (f->frametype == AST_FRAME_VIDEO) || 
04116          (f->frametype == AST_FRAME_IMAGE) ||
04117          (f->frametype == AST_FRAME_DTMF) ||
04118          (f->frametype == AST_FRAME_CONTROL)) {
04119          /* monitored dtmf take out of the bridge.
04120           * check if we monitor the specific source.
04121           */
04122          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04123          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04124             *rc = who;
04125             *fo = f;
04126             res = AST_BRIDGE_COMPLETE;
04127             /* Remove from native mode */
04128             break;
04129          }
04130          /* everything else goes to the other side */
04131          ast_write(other, f);
04132       }
04133       ast_frfree(f);
04134       /* Swap who gets priority */
04135       cs[2] = cs[0];
04136       cs[0] = cs[1];
04137       cs[1] = cs[2];
04138    }
04139    lock_both(callno0, callno1);
04140    if(iaxs[callno0])
04141       iaxs[callno0]->bridgecallno = 0;
04142    if(iaxs[callno1])
04143       iaxs[callno1]->bridgecallno = 0;
04144    unlock_both(callno0, callno1);
04145    return res;
04146 }
04147 
04148 static int iax2_answer(struct ast_channel *c)
04149 {
04150    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04151    ast_debug(1, "Answering IAX2 call\n");
04152    ast_mutex_lock(&iaxsl[callno]);
04153    if (iaxs[callno])
04154       iax2_ami_channelupdate(iaxs[callno]);
04155    ast_mutex_unlock(&iaxsl[callno]);
04156    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04157 }
04158 
04159 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
04160 {
04161    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04162    struct chan_iax2_pvt *pvt;
04163    int res = 0;
04164 
04165    if (iaxdebug)
04166       ast_debug(1, "Indicating condition %d\n", condition);
04167 
04168    ast_mutex_lock(&iaxsl[callno]);
04169    pvt = iaxs[callno];
04170 
04171    if (wait_for_peercallno(pvt)) {
04172       res = -1;
04173       goto done;
04174    }
04175 
04176    switch (condition) {
04177    case AST_CONTROL_HOLD:
04178       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04179          ast_moh_start(c, data, pvt->mohinterpret);
04180          goto done;
04181       }
04182       break;
04183    case AST_CONTROL_UNHOLD:
04184       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04185          ast_moh_stop(c);
04186          goto done;
04187       }
04188    }
04189 
04190    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04191 
04192 done:
04193    ast_mutex_unlock(&iaxsl[callno]);
04194 
04195    return res;
04196 }
04197    
04198 static int iax2_transfer(struct ast_channel *c, const char *dest)
04199 {
04200    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04201    struct iax_ie_data ied = { "", };
04202    char tmp[256], *context;
04203    ast_copy_string(tmp, dest, sizeof(tmp));
04204    context = strchr(tmp, '@');
04205    if (context) {
04206       *context = '\0';
04207       context++;
04208    }
04209    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04210    if (context)
04211       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04212    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
04213    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04214 }
04215    
04216 static int iax2_getpeertrunk(struct sockaddr_in sin)
04217 {
04218    struct iax2_peer *peer;
04219    int res = 0;
04220    struct ao2_iterator i;
04221 
04222    i = ao2_iterator_init(peers, 0);
04223    while ((peer = ao2_iterator_next(&i))) {
04224       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04225           (peer->addr.sin_port == sin.sin_port)) {
04226          res = ast_test_flag(peer, IAX_TRUNK);
04227          peer_unref(peer);
04228          break;
04229       }
04230       peer_unref(peer);
04231    }
04232 
04233    return res;
04234 }
04235 
04236 /*! \brief  Create new call, interface with the PBX core */
04237 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
04238 {
04239    struct ast_channel *tmp;
04240    struct chan_iax2_pvt *i;
04241    struct ast_variable *v = NULL;
04242 
04243    if (!(i = iaxs[callno])) {
04244       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04245       return NULL;
04246    }
04247 
04248    /* Don't hold call lock */
04249    ast_mutex_unlock(&iaxsl[callno]);
04250    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);
04251    ast_mutex_lock(&iaxsl[callno]);
04252    if (i != iaxs[callno]) {
04253       if (tmp) {
04254          /* unlock and relock iaxsl[callno] to preserve locking order */
04255          ast_mutex_unlock(&iaxsl[callno]);
04256          ast_channel_free(tmp);
04257          ast_mutex_lock(&iaxsl[callno]);
04258       }
04259       return NULL;
04260    }
04261    iax2_ami_channelupdate(i);
04262    if (!tmp)
04263       return NULL;
04264    tmp->tech = &iax2_tech;
04265    /* We can support any format by default, until we get restricted */
04266    tmp->nativeformats = capability;
04267    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04268    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04269    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04270 
04271    /* Don't use ast_set_callerid() here because it will
04272     * generate a NewCallerID event before the NewChannel event */
04273    if (!ast_strlen_zero(i->ani))
04274       tmp->cid.cid_ani = ast_strdup(i->ani);
04275    else
04276       tmp->cid.cid_ani = ast_strdup(i->cid_num);
04277    tmp->cid.cid_dnid = ast_strdup(i->dnid);
04278    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04279    tmp->cid.cid_pres = i->calling_pres;
04280    tmp->cid.cid_ton = i->calling_ton;
04281    tmp->cid.cid_tns = i->calling_tns;
04282    if (!ast_strlen_zero(i->language))
04283       ast_string_field_set(tmp, language, i->language);
04284    if (!ast_strlen_zero(i->accountcode))
04285       ast_string_field_set(tmp, accountcode, i->accountcode);
04286    if (i->amaflags)
04287       tmp->amaflags = i->amaflags;
04288    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04289    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04290    if (i->adsi)
04291       tmp->adsicpe = i->peeradsicpe;
04292    else
04293       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04294    i->owner = tmp;
04295    i->capability = capability;
04296 
04297    /* Set inherited variables */
04298    if (i->vars) {
04299       for (v = i->vars ; v ; v = v->next)
04300          pbx_builtin_setvar_helper(tmp, v->name, v->value);
04301    }
04302    if (i->iaxvars) {
04303       struct ast_datastore *variablestore;
04304       struct ast_variable *var, *prev = NULL;
04305       AST_LIST_HEAD(, ast_var_t) *varlist;
04306       ast_debug(1, "Loading up the channel with IAXVARs\n");
04307       varlist = ast_calloc(1, sizeof(*varlist));
04308       variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
04309       if (variablestore && varlist) {
04310          variablestore->data = varlist;
04311          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
04312          AST_LIST_HEAD_INIT(varlist);
04313          for (var = i->iaxvars; var; var = var->next) {
04314             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
04315             if (prev)
04316                ast_free(prev);
04317             prev = var;
04318             if (!newvar) {
04319                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
04320                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
04321             } else {
04322                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
04323             }
04324          }
04325          if (prev)
04326             ast_free(prev);
04327          i->iaxvars = NULL;
04328          ast_channel_datastore_add(i->owner, variablestore);
04329       } else {
04330          if (variablestore) {
04331             ast_channel_datastore_free(variablestore);
04332          }
04333          if (varlist) {
04334             ast_free(varlist);
04335          }
04336       }
04337    }
04338 
04339    if (state != AST_STATE_DOWN) {
04340       if (ast_pbx_start(tmp)) {
04341          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04342          ast_hangup(tmp);
04343          i->owner = NULL;
04344          return NULL;
04345       }
04346    }
04347 
04348    ast_module_ref(ast_module_info->self);
04349    return tmp;
04350 }
04351 
04352 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
04353 {
04354    unsigned long int mssincetx; /* unsigned to handle overflows */
04355    long int ms, pred;
04356 
04357    tpeer->trunkact = *tv;
04358    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
04359    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04360       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
04361       tpeer->txtrunktime = *tv;
04362       tpeer->lastsent = 999999;
04363    }
04364    /* Update last transmit time now */
04365    tpeer->lasttxtime = *tv;
04366    
04367    /* Calculate ms offset */
04368    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04369    /* Predict from last value */
04370    pred = tpeer->lastsent + sampms;
04371    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04372       ms = pred;
04373    
04374    /* We never send the same timestamp twice, so fudge a little if we must */
04375    if (ms == tpeer->lastsent)
04376       ms = tpeer->lastsent + 1;
04377    tpeer->lastsent = ms;
04378    return ms;
04379 }
04380 
04381 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
04382 {
04383    long ms; /* NOT unsigned */
04384    if (ast_tvzero(iaxs[callno]->rxcore)) {
04385       /* Initialize rxcore time if appropriate */
04386       iaxs[callno]->rxcore = ast_tvnow();
04387       /* Round to nearest 20ms so traces look pretty */
04388       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04389    }
04390    /* Calculate difference between trunk and channel */
04391    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04392    /* Return as the sum of trunk time and the difference between trunk and real time */
04393    return ms + ts;
04394 }
04395 
04396 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04397 {
04398    int ms;
04399    int voice = 0;
04400    int genuine = 0;
04401    int adjust;
04402    struct timeval *delivery = NULL;
04403 
04404 
04405    /* What sort of frame do we have?: voice is self-explanatory
04406       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
04407       non-genuine frames are CONTROL frames [ringing etc], DTMF
04408       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
04409       the others need a timestamp slaved to the voice frames so that they go in sequence
04410    */
04411    if (f) {
04412       if (f->frametype == AST_FRAME_VOICE) {
04413          voice = 1;
04414          delivery = &f->delivery;
04415       } else if (f->frametype == AST_FRAME_IAX) {
04416          genuine = 1;
04417       } else if (f->frametype == AST_FRAME_CNG) {
04418          p->notsilenttx = 0;  
04419       }
04420    }
04421    if (ast_tvzero(p->offset)) {
04422       p->offset = ast_tvnow();
04423       /* Round to nearest 20ms for nice looking traces */
04424       p->offset.tv_usec -= p->offset.tv_usec % 20000;
04425    }
04426    /* If the timestamp is specified, just send it as is */
04427    if (ts)
04428       return ts;
04429    /* If we have a time that the frame arrived, always use it to make our timestamp */
04430    if (delivery && !ast_tvzero(*delivery)) {
04431       ms = ast_tvdiff_ms(*delivery, p->offset);
04432       if (ms < 0) {
04433          ms = 0;
04434       }
04435       if (iaxdebug)
04436          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04437    } else {
04438       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04439       if (ms < 0)
04440          ms = 0;
04441       if (voice) {
04442          /* On a voice frame, use predicted values if appropriate */
04443          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04444             /* Adjust our txcore, keeping voice and non-voice synchronized */
04445             /* AN EXPLANATION:
04446                When we send voice, we usually send "calculated" timestamps worked out
04447                on the basis of the number of samples sent. When we send other frames,
04448                we usually send timestamps worked out from the real clock.
04449                The problem is that they can tend to drift out of step because the 
04450                   source channel's clock and our clock may not be exactly at the same rate.
04451                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
04452                for this call.  Moving it adjusts timestamps for non-voice frames.
04453                We make the adjustment in the style of a moving average.  Each time we
04454                adjust p->offset by 10% of the difference between our clock-derived
04455                timestamp and the predicted timestamp.  That's why you see "10000"
04456                below even though IAX2 timestamps are in milliseconds.
04457                The use of a moving average avoids offset moving too radically.
04458                Generally, "adjust" roams back and forth around 0, with offset hardly
04459                changing at all.  But if a consistent different starts to develop it
04460                will be eliminated over the course of 10 frames (200-300msecs) 
04461             */
04462             adjust = (ms - p->nextpred);
04463             if (adjust < 0)
04464                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04465             else if (adjust > 0)
04466                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04467 
04468             if (!p->nextpred) {
04469                p->nextpred = ms; /*f->samples / 8;*/
04470                if (p->nextpred <= p->lastsent)
04471                   p->nextpred = p->lastsent + 3;
04472             }
04473             ms = p->nextpred;
04474          } else {
04475                 /* in this case, just use the actual
04476             * time, since we're either way off
04477             * (shouldn't happen), or we're  ending a
04478             * silent period -- and seed the next
04479             * predicted time.  Also, round ms to the
04480             * next multiple of frame size (so our
04481             * silent periods are multiples of
04482             * frame size too) */
04483 
04484             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04485                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04486                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04487 
04488             if (f->samples >= 8) /* check to make sure we dont core dump */
04489             {
04490                int diff = ms % (f->samples / 8);
04491                if (diff)
04492                    ms += f->samples/8 - diff;
04493             }
04494 
04495             p->nextpred = ms;
04496             p->notsilenttx = 1;
04497          }
04498       } else if ( f->frametype == AST_FRAME_VIDEO ) {
04499          /*
04500          * IAX2 draft 03 says that timestamps MUST be in order.
04501          * It does not say anything about several frames having the same timestamp
04502          * When transporting video, we can have a frame that spans multiple iax packets
04503          * (so called slices), so it would make sense to use the same timestamp for all of
04504          * them
04505          * We do want to make sure that frames don't go backwards though
04506          */
04507          if ( (unsigned int)ms < p->lastsent )
04508             ms = p->lastsent;
04509       } else {
04510          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
04511             it's a genuine frame */
04512          if (genuine) {
04513             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
04514             if (ms <= p->lastsent)
04515                ms = p->lastsent + 3;
04516          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04517             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
04518             ms = p->lastsent + 3;
04519          }
04520       }
04521    }
04522    p->lastsent = ms;
04523    if (voice)
04524       p->nextpred = p->nextpred + f->samples / 8;
04525    return ms;
04526 }
04527 
04528 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04529 {
04530    /* Returns where in "receive time" we are.  That is, how many ms
04531       since we received (or would have received) the frame with timestamp 0 */
04532    int ms;
04533 #ifdef IAXTESTS
04534    int jit;
04535 #endif /* IAXTESTS */
04536    /* Setup rxcore if necessary */
04537    if (ast_tvzero(p->rxcore)) {
04538       p->rxcore = ast_tvnow();
04539       if (iaxdebug)
04540          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04541                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04542       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04543 #if 1
04544       if (iaxdebug)
04545          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04546                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04547 #endif
04548    }
04549 
04550    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04551 #ifdef IAXTESTS
04552    if (test_jit) {
04553       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04554          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04555          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04556             jit = -jit;
04557          ms += jit;
04558       }
04559    }
04560    if (test_late) {
04561       ms += test_late;
04562       test_late = 0;
04563    }
04564 #endif /* IAXTESTS */
04565    return ms;
04566 }
04567 
04568 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04569 {
04570    struct iax2_trunk_peer *tpeer = NULL;
04571    
04572    /* Finds and locks trunk peer */
04573    AST_LIST_LOCK(&tpeers);
04574 
04575    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
04576       if (!inaddrcmp(&tpeer->addr, sin)) {
04577          ast_mutex_lock(&tpeer->lock);
04578          break;
04579       }
04580    }
04581 
04582    if (!tpeer) {
04583       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04584          ast_mutex_init(&tpeer->lock);
04585          tpeer->lastsent = 9999;
04586          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04587          tpeer->trunkact = ast_tvnow();
04588          ast_mutex_lock(&tpeer->lock);
04589          tpeer->sockfd = fd;
04590 #ifdef SO_NO_CHECK
04591          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04592 #endif
04593          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04594          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
04595       }
04596    }
04597 
04598    AST_LIST_UNLOCK(&tpeers);
04599 
04600    return tpeer;
04601 }
04602 
04603 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04604 {
04605    struct ast_frame *f;
04606    struct iax2_trunk_peer *tpeer;
04607    void *tmp, *ptr;
04608    struct timeval now;
04609    int res; 
04610    struct ast_iax2_meta_trunk_entry *met;
04611    struct ast_iax2_meta_trunk_mini *mtm;
04612 
04613    f = &fr->af;
04614    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04615    if (tpeer) {
04616       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04617          /* Need to reallocate space */
04618          if (tpeer->trunkdataalloc < trunkmaxsize) {
04619             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04620                ast_mutex_unlock(&tpeer->lock);
04621                return -1;
04622             }
04623             
04624             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04625             tpeer->trunkdata = tmp;
04626             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);
04627          } else {
04628             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));
04629             ast_mutex_unlock(&tpeer->lock);
04630             return -1;
04631          }
04632       }
04633 
04634       /* Append to meta frame */
04635       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04636       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04637          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04638          mtm->len = htons(f->datalen);
04639          mtm->mini.callno = htons(pvt->callno);
04640          mtm->mini.ts = htons(0xffff & fr->ts);
04641          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04642          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04643       } else {
04644          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04645          /* Store call number and length in meta header */
04646          met->callno = htons(pvt->callno);
04647          met->len = htons(f->datalen);
04648          /* Advance pointers/decrease length past trunk entry header */
04649          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04650          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04651       }
04652       /* Copy actual trunk data */
04653       memcpy(ptr, f->data, f->datalen);
04654       tpeer->trunkdatalen += f->datalen;
04655 
04656       tpeer->calls++;
04657 
04658       /* track the largest mtu we actually have sent */
04659       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
04660          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
04661 
04662       /* if we have enough for a full MTU, ship it now without waiting */
04663       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
04664          now = ast_tvnow();
04665          res = send_trunk(tpeer, &now); 
04666          trunk_untimed ++; 
04667       }
04668 
04669       ast_mutex_unlock(&tpeer->lock);
04670    }
04671    return 0;
04672 }
04673 
04674 /* IAX2 encryption requires 16 to 32 bytes of random padding to be present
04675  * before the encryption data.  This function randomizes that data. */
04676 static void build_rand_pad(unsigned char *buf, ssize_t len)
04677 {
04678    long tmp;
04679    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
04680       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
04681       buf += sizeof(tmp);
04682       len -= sizeof(tmp);
04683    }
04684 }
04685 
04686 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04687 {
04688    build_ecx_key(digest, pvt);
04689    ast_aes_decrypt_key(digest, &pvt->dcx);
04690 }
04691 
04692 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04693 {
04694    /* it is required to hold the corresponding decrypt key to our encrypt key
04695     * in the pvt struct because queued frames occasionally need to be decrypted and
04696     * re-encrypted when updated for a retransmission */
04697    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
04698    ast_aes_encrypt_key(digest, &pvt->ecx);
04699    ast_aes_decrypt_key(digest, &pvt->mydcx);
04700 }
04701 
04702 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
04703 {
04704 #if 0
04705    /* Debug with "fake encryption" */
04706    int x;
04707    if (len % 16)
04708       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04709    for (x=0;x<len;x++)
04710       dst[x] = src[x] ^ 0xff;
04711 #else 
04712    unsigned char lastblock[16] = { 0 };
04713    int x;
04714    while(len > 0) {
04715       ast_aes_decrypt(src, dst, dcx);
04716       for (x=0;x<16;x++)
04717          dst[x] ^= lastblock[x];
04718       memcpy(lastblock, src, sizeof(lastblock));
04719       dst += 16;
04720       src += 16;
04721       len -= 16;
04722    }
04723 #endif
04724 }
04725 
04726 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
04727 {
04728 #if 0
04729    /* Debug with "fake encryption" */
04730    int x;
04731    if (len % 16)
04732       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04733    for (x=0;x<len;x++)
04734       dst[x] = src[x] ^ 0xff;
04735 #else
04736    unsigned char curblock[16] = { 0 };
04737    int x;
04738    while(len > 0) {
04739       for (x=0;x<16;x++)
04740          curblock[x] ^= src[x];
04741       ast_aes_encrypt(curblock, dst, ecx);
04742       memcpy(curblock, dst, sizeof(curblock)); 
04743       dst += 16;
04744       src += 16;
04745       len -= 16;
04746    }
04747 #endif
04748 }
04749 
04750 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04751 {
04752    int padding;
04753    unsigned char *workspace;
04754 
04755    workspace = alloca(*datalen);
04756    memset(f, 0, sizeof(*f));
04757    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04758       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04759       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04760          return -1;
04761       /* Decrypt */
04762       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04763 
04764       padding = 16 + (workspace[15] & 0x0f);
04765       if (iaxdebug)
04766          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04767       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04768          return -1;
04769 
04770       *datalen -= padding;
04771       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04772       f->frametype = fh->type;
04773       if (f->frametype == AST_FRAME_VIDEO) {
04774          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04775       } else {
04776          f->subclass = uncompress_subclass(fh->csub);
04777       }
04778    } else {
04779       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04780       if (iaxdebug)
04781          ast_debug(1, "Decoding mini with length %d\n", *datalen);
04782       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04783          return -1;
04784       /* Decrypt */
04785       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04786       padding = 16 + (workspace[15] & 0x0f);
04787       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04788          return -1;
04789       *datalen -= padding;
04790       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04791    }
04792    return 0;
04793 }
04794 
04795 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04796 {
04797    int padding;
04798    unsigned char *workspace;
04799    workspace = alloca(*datalen + 32);
04800    if (!workspace)
04801       return -1;
04802    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04803       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04804       if (iaxdebug)
04805          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04806       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04807       padding = 16 + (padding & 0xf);
04808       memcpy(workspace, poo, padding);
04809       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04810       workspace[15] &= 0xf0;
04811       workspace[15] |= (padding & 0xf);
04812       if (iaxdebug)
04813          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04814       *datalen += padding;
04815       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04816       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04817          memcpy(poo, workspace + *datalen - 32, 32);
04818    } else {
04819       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04820       if (iaxdebug)
04821          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
04822       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04823       padding = 16 + (padding & 0xf);
04824       memcpy(workspace, poo, padding);
04825       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04826       workspace[15] &= 0xf0;
04827       workspace[15] |= (padding & 0x0f);
04828       *datalen += padding;
04829       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04830       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04831          memcpy(poo, workspace + *datalen - 32, 32);
04832    }
04833    return 0;
04834 }
04835 
04836 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04837 {
04838    int res=-1;
04839    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04840       /* Search for possible keys, given secrets */
04841       struct MD5Context md5;
04842       unsigned char digest[16];
04843       char *tmppw, *stringp;
04844       
04845       tmppw = ast_strdupa(iaxs[callno]->secret);
04846       stringp = tmppw;
04847       while ((tmppw = strsep(&stringp, ";"))) {
04848          MD5Init(&md5);
04849          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04850          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04851          MD5Final(digest, &md5);
04852          build_encryption_keys(digest, iaxs[callno]);
04853          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04854          if (!res) {
04855             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04856             break;
04857          }
04858       }
04859    } else 
04860       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04861    return res;
04862 }
04863 
04864 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04865 {
04866    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04867       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04868       or delayed, with retransmission */
04869    struct ast_iax2_full_hdr *fh;
04870    struct ast_iax2_mini_hdr *mh;
04871    struct ast_iax2_video_hdr *vh;
04872    struct {
04873       struct iax_frame fr2;
04874       unsigned char buffer[4096];
04875    } frb;
04876    struct iax_frame *fr;
04877    int res;
04878    int sendmini=0;
04879    unsigned int lastsent;
04880    unsigned int fts;
04881 
04882    frb.fr2.afdatalen = sizeof(frb.buffer);
04883 
04884    if (!pvt) {
04885       ast_log(LOG_WARNING, "No private structure for packet?\n");
04886       return -1;
04887    }
04888    
04889    lastsent = pvt->lastsent;
04890 
04891    /* Calculate actual timestamp */
04892    fts = calc_timestamp(pvt, ts, f);
04893 
04894    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04895     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04896     * increment the "predicted timestamps" for voice, if we're predicting */
04897    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04898        return 0;
04899 
04900 
04901    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04902          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04903          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04904       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04905        (f->frametype == AST_FRAME_VOICE) 
04906       /* is a voice frame */ &&
04907       (f->subclass == pvt->svoiceformat) 
04908       /* is the same type */ ) {
04909          /* Force immediate rather than delayed transmission */
04910          now = 1;
04911          /* Mark that mini-style frame is appropriate */
04912          sendmini = 1;
04913    }
04914    if ( f->frametype == AST_FRAME_VIDEO ) {
04915       /*
04916        * If the lower 15 bits of the timestamp roll over, or if
04917        * the video format changed then send a full frame.
04918        * Otherwise send a mini video frame
04919        */
04920       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04921           ((f->subclass & ~0x1) == pvt->svideoformat)
04922          ) {
04923          now = 1;
04924          sendmini = 1;
04925       } else {
04926          now = 0;
04927          sendmini = 0;
04928       }
04929       pvt->lastvsent = fts;
04930    }
04931    if (f->frametype == AST_FRAME_IAX) {
04932       /* 0x8000 marks this message as TX:, this bit will be stripped later */
04933       pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
04934       if (!pvt->first_iax_message) {
04935          pvt->first_iax_message = pvt->last_iax_message;
04936       }
04937    }
04938    /* Allocate an iax_frame */
04939    if (now) {
04940       fr = &frb.fr2;
04941    } else
04942       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));
04943    if (!fr) {
04944       ast_log(LOG_WARNING, "Out of memory\n");
04945       return -1;
04946    }
04947    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04948    iax_frame_wrap(fr, f);
04949 
04950    fr->ts = fts;
04951    fr->callno = pvt->callno;
04952    fr->transfer = transfer;
04953    fr->final = final;
04954    fr->encmethods = 0;
04955    if (!sendmini) {
04956       /* We need a full frame */
04957       if (seqno > -1)
04958          fr->oseqno = seqno;
04959       else
04960          fr->oseqno = pvt->oseqno++;
04961       fr->iseqno = pvt->iseqno;
04962       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04963       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04964       fh->ts = htonl(fr->ts);
04965       fh->oseqno = fr->oseqno;
04966       if (transfer) {
04967          fh->iseqno = 0;
04968       } else
04969          fh->iseqno = fr->iseqno;
04970       /* Keep track of the last thing we've acknowledged */
04971       if (!transfer)
04972          pvt->aseqno = fr->iseqno;
04973       fh->type = fr->af.frametype & 0xFF;
04974       if (fr->af.frametype == AST_FRAME_VIDEO)
04975          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04976       else
04977          fh->csub = compress_subclass(fr->af.subclass);
04978       if (transfer) {
04979          fr->dcallno = pvt->transfercallno;
04980       } else
04981          fr->dcallno = pvt->peercallno;
04982       fh->dcallno = htons(fr->dcallno);
04983       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04984       fr->data = fh;
04985       fr->retries = 0;
04986       /* Retry after 2x the ping time has passed */
04987       fr->retrytime = pvt->pingtime * 2;
04988       if (fr->retrytime < MIN_RETRY_TIME)
04989          fr->retrytime = MIN_RETRY_TIME;
04990       if (fr->retrytime > MAX_RETRY_TIME)
04991          fr->retrytime = MAX_RETRY_TIME;
04992       /* Acks' don't get retried */
04993       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04994          fr->retries = -1;
04995       else if (f->frametype == AST_FRAME_VOICE)
04996          pvt->svoiceformat = f->subclass;
04997       else if (f->frametype == AST_FRAME_VIDEO)
04998          pvt->svideoformat = f->subclass & ~0x1;
04999       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05000          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05001             if (iaxdebug) {
05002                if (fr->transfer)
05003                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05004                else
05005                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05006             }
05007             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05008             fr->encmethods = pvt->encmethods;
05009             fr->ecx = pvt->ecx;
05010             fr->mydcx = pvt->mydcx;
05011             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05012          } else
05013             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05014       }
05015 
05016       if (now) {
05017          res = send_packet(fr);
05018       } else
05019          res = iax2_transmit(fr);
05020    } else {
05021       if (ast_test_flag(pvt, IAX_TRUNK)) {
05022          iax2_trunk_queue(pvt, fr);
05023          res = 0;
05024       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05025          /* Video frame have no sequence number */
05026          fr->oseqno = -1;
05027          fr->iseqno = -1;
05028          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
05029          vh->zeros = 0;
05030          vh->callno = htons(0x8000 | fr->callno);
05031          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05032          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05033          fr->data = vh;
05034          fr->retries = -1;
05035          res = send_packet(fr);        
05036       } else {
05037          /* Mini-frames have no sequence number */
05038          fr->oseqno = -1;
05039          fr->iseqno = -1;
05040          /* Mini frame will do */
05041          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
05042          mh->callno = htons(fr->callno);
05043          mh->ts = htons(fr->ts & 0xFFFF);
05044          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05045          fr->data = mh;
05046          fr->retries = -1;
05047          if (pvt->transferring == TRANSFER_MEDIAPASS)
05048             fr->transfer = 1;
05049          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05050             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05051                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05052             } else
05053                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05054          }
05055          res = send_packet(fr);
05056       }
05057    }
05058    return res;
05059 }
05060 
05061 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05062 {
05063    regex_t regexbuf;
05064    int havepattern = 0;
05065 
05066 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
05067 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
05068 
05069    struct iax2_user *user = NULL;
05070    char auth[90];
05071    char *pstr = "";
05072    struct ao2_iterator i;
05073 
05074    switch (cmd) {
05075    case CLI_INIT:
05076       e->command = "iax2 show users [like]";
05077       e->usage =
05078          "Usage: iax2 show users [like <pattern>]\n"
05079          "       Lists all known IAX2 users.\n"
05080          "       Optional regular expression pattern is used to filter the user list.\n";
05081       return NULL;
05082    case CLI_GENERATE:
05083       return NULL;
05084    }
05085 
05086    switch (a->argc) {
05087    case 5:
05088       if (!strcasecmp(a->argv[3], "like")) {
05089          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
05090             return CLI_SHOWUSAGE;
05091          havepattern = 1;
05092       } else
05093          return CLI_SHOWUSAGE;
05094    case 3:
05095       break;
05096    default:
05097       return CLI_SHOWUSAGE;
05098    }
05099 
05100    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05101    i = ao2_iterator_init(users, 0);
05102    for (user = ao2_iterator_next(&i); user; 
05103       user_unref(user), user = ao2_iterator_next(&i)) {
05104       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
05105          continue;
05106       
05107       if (!ast_strlen_zero(user->secret)) {
05108          ast_copy_string(auth,user->secret, sizeof(auth));
05109       } else if (!ast_strlen_zero(user->inkeys)) {
05110          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05111       } else
05112          ast_copy_string(auth, "-no secret-", sizeof(auth));
05113       
05114       if(ast_test_flag(user,IAX_CODEC_NOCAP))
05115          pstr = "REQ Only";
05116       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05117          pstr = "Disabled";
05118       else
05119          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05120       
05121       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
05122          user->contexts ? user->contexts->context : context,
05123          user->ha ? "Yes" : "No", pstr);
05124    }
05125 
05126    if (havepattern)
05127       regfree(&regexbuf);
05128 
05129    return CLI_SUCCESS;
05130 #undef FORMAT
05131 #undef FORMAT2
05132 }
05133 
05134 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
05135 {
05136    regex_t regexbuf;
05137    int havepattern = 0;
05138    int total_peers = 0;
05139    int online_peers = 0;
05140    int offline_peers = 0;
05141    int unmonitored_peers = 0;
05142    struct ao2_iterator i;
05143 
05144 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
05145 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
05146 
05147    struct iax2_peer *peer = NULL;
05148    char name[256];
05149    int registeredonly=0;
05150    char *term = manager ? "\r\n" : "\n";
05151    char idtext[256] = "";
05152    switch (argc) {
05153    case 6:
05154       if (!strcasecmp(argv[3], "registered"))
05155          registeredonly = 1;
05156       else
05157          return RESULT_SHOWUSAGE;
05158       if (!strcasecmp(argv[4], "like")) {
05159          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05160             return RESULT_SHOWUSAGE;
05161          havepattern = 1;
05162       } else
05163          return RESULT_SHOWUSAGE;
05164       break;
05165    case 5:
05166       if (!strcasecmp(argv[3], "like")) {
05167          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05168             return RESULT_SHOWUSAGE;
05169          havepattern = 1;
05170       } else
05171          return RESULT_SHOWUSAGE;
05172       break;
05173    case 4:
05174       if (!strcasecmp(argv[3], "registered"))
05175          registeredonly = 1;
05176       else
05177          return RESULT_SHOWUSAGE;
05178       break;
05179    case 3:
05180       break;
05181    default:
05182       return RESULT_SHOWUSAGE;
05183    }
05184 
05185 
05186    if (!s)
05187       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05188 
05189    i = ao2_iterator_init(peers, 0);
05190    for (peer = ao2_iterator_next(&i); peer; 
05191       peer_unref(peer), peer = ao2_iterator_next(&i)) {
05192       char nm[20];
05193       char status[20];
05194       char srch[2000];
05195       int retstatus;
05196 
05197       if (registeredonly && !peer->addr.sin_addr.s_addr)
05198          continue;
05199       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
05200          continue;
05201 
05202       if (!ast_strlen_zero(peer->username))
05203          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05204       else
05205          ast_copy_string(name, peer->name, sizeof(name));
05206       
05207       retstatus = peer_status(peer, status, sizeof(status));
05208       if (retstatus > 0)
05209          online_peers++;
05210       else if (!retstatus)
05211          offline_peers++;
05212       else
05213          unmonitored_peers++;
05214       
05215       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05216       
05217       snprintf(srch, sizeof(srch), FORMAT, name, 
05218           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05219           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05220           nm,
05221           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05222           peer->encmethods ? "(E)" : "   ", status, term);
05223       
05224       if (s)
05225          astman_append(s, 
05226             "Event: PeerEntry\r\n%s"
05227             "Channeltype: IAX2\r\n"
05228             "ChanObjectType: peer\r\n"
05229             "ObjectName: %s\r\n"
05230             "IPaddress: %s\r\n"
05231             "IPport: %d\r\n"
05232             "Dynamic: %s\r\n"
05233             "Status: %s\r\n\r\n",
05234             idtext,
05235             name,
05236             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
05237             ntohs(peer->addr.sin_port),
05238             ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
05239             status);
05240       
05241       else
05242          ast_cli(fd, FORMAT, name, 
05243             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05244             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05245             nm,
05246             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05247             peer->encmethods ? "(E)" : "   ", status, term);
05248       total_peers++;
05249    }
05250 
05251    if (!s)
05252       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05253 
05254    if (havepattern)
05255       regfree(&regexbuf);
05256 
05257    return RESULT_SUCCESS;
05258 #undef FORMAT
05259 #undef FORMAT2
05260 }
05261 
05262 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05263 {
05264    struct iax2_thread *thread = NULL;
05265    time_t t;
05266    int threadcount = 0, dynamiccount = 0;
05267    char type;
05268 
05269    switch (cmd) {
05270    case CLI_INIT:
05271       e->command = "iax2 show threads";
05272       e->usage =
05273          "Usage: iax2 show threads\n"
05274          "       Lists status of IAX helper threads\n";
05275       return NULL;
05276    case CLI_GENERATE:
05277       return NULL;
05278    }
05279    if (a->argc != 3)
05280       return CLI_SHOWUSAGE;
05281       
05282    ast_cli(a->fd, "IAX2 Thread Information\n");
05283    time(&t);
05284    ast_cli(a->fd, "Idle Threads:\n");
05285    AST_LIST_LOCK(&idle_list);
05286    AST_LIST_TRAVERSE(&idle_list, thread, list) {
05287 #ifdef DEBUG_SCHED_MULTITHREAD
05288       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
05289          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05290 #else
05291       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
05292          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05293 #endif
05294       threadcount++;
05295    }
05296    AST_LIST_UNLOCK(&idle_list);
05297    ast_cli(a->fd, "Active Threads:\n");
05298    AST_LIST_LOCK(&active_list);
05299    AST_LIST_TRAVERSE(&active_list, thread, list) {
05300       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
05301          type = 'D';
05302       else
05303          type = 'P';
05304 #ifdef DEBUG_SCHED_MULTITHREAD
05305       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
05306          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05307 #else
05308       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
05309          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05310 #endif
05311       threadcount++;
05312    }
05313    AST_LIST_UNLOCK(&active_list);
05314    ast_cli(a->fd, "Dynamic Threads:\n");
05315    AST_LIST_LOCK(&dynamic_list);
05316    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05317 #ifdef DEBUG_SCHED_MULTITHREAD
05318       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05319          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05320 #else
05321       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05322          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05323 #endif
05324       dynamiccount++;
05325    }
05326    AST_LIST_UNLOCK(&dynamic_list);
05327    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05328    return CLI_SUCCESS;
05329 }
05330 
05331 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05332 {
05333    struct iax2_peer *p;
05334 
05335    switch (cmd) {
05336    case CLI_INIT:
05337       e->command = "iax2 unregister";
05338       e->usage =
05339          "Usage: iax2 unregister <peername>\n"
05340          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
05341       return NULL;
05342    case CLI_GENERATE:
05343       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
05344    }
05345 
05346    if (a->argc != 3)
05347       return CLI_SHOWUSAGE;
05348 
05349    p = find_peer(a->argv[2], 1);
05350    if (p) {
05351       if (p->expire > 0) {
05352          struct iax2_peer tmp_peer = {
05353             .name = a->argv[2],
05354          };
05355          struct iax2_peer *peer;
05356 
05357          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
05358          if (peer) {
05359             expire_registry(peer_ref(peer)); /* will release its own reference when done */
05360             peer_unref(peer); /* ref from ao2_find() */
05361             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
05362          } else {
05363             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
05364          }
05365       } else {
05366          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
05367       }
05368    } else {
05369       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
05370    }
05371    return CLI_SUCCESS;
05372 }
05373 
05374 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
05375 {
05376    int which = 0;
05377    struct iax2_peer *p = NULL;
05378    char *res = NULL;
05379    int wordlen = strlen(word);
05380 
05381    /* 0 - iax2; 1 - unregister; 2 - <peername> */
05382    if (pos == 2) {
05383       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05384       while ((p = ao2_iterator_next(&i))) {
05385          if (!strncasecmp(p->name, word, wordlen) && 
05386             ++which > state && p->expire > 0) {
05387             res = ast_strdup(p->name);
05388             peer_unref(p);
05389             break;
05390          }
05391          peer_unref(p);
05392       }
05393    }
05394 
05395    return res;
05396 }
05397 
05398 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05399 {
05400    switch (cmd) {
05401    case CLI_INIT:
05402       e->command = "iax2 show peers";
05403       e->usage =
05404          "Usage: iax2 show peers [registered] [like <pattern>]\n"
05405          "       Lists all known IAX2 peers.\n"
05406          "       Optional 'registered' argument lists only peers with known addresses.\n"
05407          "       Optional regular expression pattern is used to filter the peer list.\n";
05408       return NULL;
05409    case CLI_GENERATE:
05410       return NULL;
05411    }
05412 
05413    switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
05414    case RESULT_SHOWUSAGE:
05415       return CLI_SHOWUSAGE;
05416    case RESULT_FAILURE:
05417       return CLI_FAILURE;
05418    default:
05419       return CLI_SUCCESS;
05420    }
05421 }
05422 
05423 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
05424 {
05425    ast_cli_netstats(s, -1, 0);
05426    astman_append(s, "\r\n");
05427    return RESULT_SUCCESS;
05428 }
05429 
05430 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05431 {
05432    struct iax_firmware *cur = NULL;
05433 
05434    switch (cmd) {
05435    case CLI_INIT:
05436       e->command = "iax2 show firmware";
05437       e->usage =
05438          "Usage: iax2 show firmware\n"
05439          "       Lists all known IAX firmware images.\n";
05440       return NULL;
05441    case CLI_GENERATE:
05442       return NULL;
05443    }
05444 
05445    if (a->argc != 3 && a->argc != 4)
05446       return CLI_SHOWUSAGE;
05447 
05448    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
05449    AST_LIST_LOCK(&firmwares);
05450    AST_LIST_TRAVERSE(&firmwares, cur, list) {
05451       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
05452          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
05453             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
05454       }
05455    }
05456    AST_LIST_UNLOCK(&firmwares);
05457 
05458    return CLI_SUCCESS;
05459 }
05460 
05461 /*! \brief callback to display iax peers in manager */
05462 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05463 {
05464    char *a[] = { "iax2", "show", "users" };
05465    const char *id = astman_get_header(m,"ActionID");
05466    char idtext[256] = "";
05467 
05468    if (!ast_strlen_zero(id))
05469       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05470    astman_send_ack(s, m, "Peer status list will follow");
05471    return __iax2_show_peers(1, -1, s, 3, a );
05472 } 
05473 
05474 /*! \brief callback to display iax peers in manager format */
05475 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
05476 {
05477    struct iax2_peer *peer = NULL;
05478    int peer_count = 0;
05479    char nm[20];
05480    char status[20];
05481    const char *id = astman_get_header(m,"ActionID");
05482    char idtext[256] = "";
05483    struct ao2_iterator i;
05484 
05485    if (!ast_strlen_zero(id))
05486       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05487 
05488    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
05489 
05490 
05491    i = ao2_iterator_init(peers, 0);
05492    for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
05493 
05494       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
05495       if (!ast_strlen_zero(peer->username)) {
05496          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
05497       } else {
05498          astman_append(s, "ObjectName: %s\r\n", peer->name);
05499       }
05500       astman_append(s, "ChanObjectType: peer\r\n");
05501       astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
05502       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05503       astman_append(s, "Mask: %s\r\n", nm);
05504       astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
05505       astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
05506       peer_status(peer, status, sizeof(status));
05507       astman_append(s, "Status: %s\r\n\r\n", status);
05508       peer_count++;
05509    }
05510 
05511    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
05512    return RESULT_SUCCESS;
05513 }
05514 
05515 
05516 static char *regstate2str(int regstate)
05517 {
05518    switch(regstate) {
05519    case REG_STATE_UNREGISTERED:
05520       return "Unregistered";
05521    case REG_STATE_REGSENT:
05522       return "Request Sent";
05523    case REG_STATE_AUTHSENT:
05524       return "Auth. Sent";
05525    case REG_STATE_REGISTERED:
05526       return "Registered";
05527    case REG_STATE_REJECTED:
05528       return "Rejected";
05529    case REG_STATE_TIMEOUT:
05530       return "Timeout";
05531    case REG_STATE_NOAUTH:
05532       return "No Authentication";
05533    default:
05534       return "Unknown";
05535    }
05536 }
05537 
05538 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05539 {
05540 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
05541 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
05542    struct iax2_registry *reg = NULL;
05543    char host[80];
05544    char perceived[80];
05545    int counter = 0;
05546 
05547    switch (cmd) {
05548    case CLI_INIT:
05549       e->command = "iax2 show registry";
05550       e->usage =
05551          "Usage: iax2 show registry\n"
05552          "       Lists all registration requests and status.\n";
05553       return NULL;
05554    case CLI_GENERATE:
05555       return NULL;
05556    }
05557    if (a->argc != 3)
05558       return CLI_SHOWUSAGE;
05559    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05560    AST_LIST_LOCK(&registrations);
05561    AST_LIST_TRAVERSE(&registrations, reg, entry) {
05562       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05563       if (reg->us.sin_addr.s_addr) 
05564          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05565       else
05566          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05567       ast_cli(a->fd, FORMAT, host, 
05568                (reg->dnsmgr) ? "Y" : "N", 
05569                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05570       counter++;
05571    }
05572    AST_LIST_UNLOCK(&registrations);
05573    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
05574    return CLI_SUCCESS;
05575 #undef FORMAT
05576 #undef FORMAT2
05577 }
05578 
05579 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05580 {
05581 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
05582 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
05583 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
05584    int x;
05585    int numchans = 0;
05586    char first_message[10] = { 0, };
05587    char last_message[10] = { 0, };
05588 
05589    switch (cmd) {
05590    case CLI_INIT:
05591       e->command = "iax2 show channels";
05592       e->usage =
05593          "Usage: iax2 show channels\n"
05594          "       Lists all currently active IAX channels.\n";
05595       return NULL;
05596    case CLI_GENERATE:
05597       return NULL;
05598    }
05599 
05600    if (a->argc != 3)
05601       return CLI_SHOWUSAGE;
05602    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
05603    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05604       ast_mutex_lock(&iaxsl[x]);
05605       if (iaxs[x]) {
05606          int lag, jitter, localdelay;
05607          jb_info jbinfo;
05608          if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05609             jb_getinfo(iaxs[x]->jb, &jbinfo);
05610             jitter = jbinfo.jitter;
05611             localdelay = jbinfo.current - jbinfo.min;
05612          } else {
05613             jitter = -1;
05614             localdelay = 0;
05615          }
05616 
05617          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05618          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05619          lag = iaxs[x]->remote_rr.delay;
05620          ast_cli(a->fd, FORMAT,
05621             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05622             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
05623             S_OR(iaxs[x]->username, "(None)"),
05624             iaxs[x]->callno, iaxs[x]->peercallno,
05625             iaxs[x]->oseqno, iaxs[x]->iseqno,
05626             lag,
05627             jitter,
05628             localdelay,
05629             ast_getformatname(iaxs[x]->voiceformat),
05630             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05631             first_message,
05632             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05633             last_message);
05634          numchans++;
05635       }
05636       ast_mutex_unlock(&iaxsl[x]);
05637    }
05638    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05639    return CLI_SUCCESS;
05640 #undef FORMAT
05641 #undef FORMAT2
05642 #undef FORMATB
05643 }
05644 
05645 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05646 {
05647    int x;
05648    int numchans = 0;
05649    char first_message[10] = { 0, };
05650    char last_message[10] = { 0, };
05651 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
05652 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
05653    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05654       ast_mutex_lock(&iaxsl[x]);
05655       if (iaxs[x]) {
05656          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05657          jb_info jbinfo;
05658          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05659          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05660 
05661          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05662             jb_getinfo(iaxs[x]->jb, &jbinfo);
05663             localjitter = jbinfo.jitter;
05664             localdelay = jbinfo.current - jbinfo.min;
05665             locallost = jbinfo.frames_lost;
05666             locallosspct = jbinfo.losspct/1000;
05667             localdropped = jbinfo.frames_dropped;
05668             localooo = jbinfo.frames_ooo;
05669          } else {
05670             localjitter = -1;
05671             localdelay = 0;
05672             locallost = -1;
05673             locallosspct = -1;
05674             localdropped = 0;
05675             localooo = -1;
05676          }
05677          if (s)
05678             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05679                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05680                iaxs[x]->pingtime,
05681                localjitter,
05682                localdelay,
05683                locallost,
05684                locallosspct,
05685                localdropped,
05686                localooo,
05687                iaxs[x]->frames_received/1000,
05688                iaxs[x]->remote_rr.jitter,
05689                iaxs[x]->remote_rr.delay,
05690                iaxs[x]->remote_rr.losscnt,
05691                iaxs[x]->remote_rr.losspct,
05692                iaxs[x]->remote_rr.dropped,
05693                iaxs[x]->remote_rr.ooo,
05694                iaxs[x]->remote_rr.packets/1000,
05695                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05696                first_message,
05697                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05698                last_message);
05699          else
05700             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05701                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05702                iaxs[x]->pingtime,
05703                localjitter,
05704                localdelay,
05705                locallost,
05706                locallosspct,
05707                localdropped,
05708                localooo,
05709                iaxs[x]->frames_received/1000,
05710                iaxs[x]->remote_rr.jitter,
05711                iaxs[x]->remote_rr.delay,
05712                iaxs[x]->remote_rr.losscnt,
05713                iaxs[x]->remote_rr.losspct,
05714                iaxs[x]->remote_rr.dropped,
05715                iaxs[x]->remote_rr.ooo,
05716                iaxs[x]->remote_rr.packets/1000,
05717                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05718                first_message,
05719                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05720                last_message);
05721          numchans++;
05722       }
05723       ast_mutex_unlock(&iaxsl[x]);
05724    }
05725 
05726    return numchans;
05727 }
05728 
05729 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05730 {
05731    int numchans = 0;
05732 
05733    switch (cmd) {
05734    case CLI_INIT:
05735       e->command = "iax2 show netstats";
05736       e->usage =
05737          "Usage: iax2 show netstats\n"
05738          "       Lists network status for all currently active IAX channels.\n";
05739       return NULL;
05740    case CLI_GENERATE:
05741       return NULL;
05742    }
05743    if (a->argc != 3)
05744       return CLI_SHOWUSAGE;
05745    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
05746    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
05747    numchans = ast_cli_netstats(NULL, a->fd, 1);
05748    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05749    return CLI_SUCCESS;
05750 }
05751 
05752 static char *handle_cli_iax2_set_debug_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05753 {
05754    switch (cmd) {
05755    case CLI_INIT:
05756       e->command = "iax2 set debug [off]";
05757       e->usage =
05758          "Usage: iax2 set debug [off]\n"
05759          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
05760       return NULL;
05761    case CLI_GENERATE:
05762       return NULL;
05763    }
05764    if (a->argc < 3 || a->argc > 4)
05765       return CLI_SHOWUSAGE;
05766    if (a->argc == 3) {
05767       iaxdebug = 1;
05768       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05769    } else {
05770       iaxdebug = 0;
05771       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05772    }
05773    return CLI_SUCCESS;
05774 }
05775 
05776 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05777 {
05778    switch (cmd) {
05779    case CLI_INIT:
05780       e->command = "iax2 set debug {on|off}";
05781       e->usage =
05782          "Usage: iax2 set debug {on|off}\n"
05783          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
05784       return NULL;
05785    case CLI_GENERATE:
05786       return NULL;
05787    }
05788 
05789    if (a->argc != e->args)
05790       return CLI_SHOWUSAGE;
05791 
05792    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05793       iaxdebug = 1;
05794       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05795    } else {
05796       iaxdebug = 0;
05797       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05798    }
05799    return CLI_SUCCESS;
05800 }
05801 
05802 
05803 static char *handle_cli_iax2_set_debug_trunk_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05804 {
05805    switch (cmd) {
05806    case CLI_INIT:
05807       e->command = "iax2 set debug trunk [off]";
05808       e->usage =
05809          "Usage: iax2 set debug trunk [off]\n"
05810          "       Enables/Disables debugging of IAX trunking\n";
05811       return NULL;
05812    case CLI_GENERATE:
05813       return NULL;
05814    }
05815 
05816    if (a->argc < 4 || a->argc > 5)
05817       return CLI_SHOWUSAGE;
05818 
05819    if (a->argc == 4) {
05820       iaxtrunkdebug = 1;
05821       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05822    } else {
05823       iaxtrunkdebug = 0;
05824       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05825    }
05826    return CLI_SUCCESS;
05827 }
05828 
05829 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05830 {
05831    switch (cmd) {
05832    case CLI_INIT:
05833       e->command = "iax2 set debug trunk {on|off}";
05834       e->usage =
05835          "Usage: iax2 set debug trunk {on|off}\n"
05836          "       Enables/Disables debugging of IAX trunking\n";
05837       return NULL;
05838    case CLI_GENERATE:
05839       return NULL;
05840    }
05841 
05842    if (a->argc != e->args)
05843       return CLI_SHOWUSAGE;
05844 
05845    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
05846       iaxtrunkdebug = 1;
05847       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05848    } else {
05849       iaxtrunkdebug = 0;
05850       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05851    }
05852    return CLI_SUCCESS;
05853 }
05854 
05855 static char *handle_cli_iax2_set_debug_jb_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05856 {
05857    switch (cmd) {
05858    case CLI_INIT:
05859       e->command = "iax2 set debug jb [off]";
05860       e->usage =
05861          "Usage: iax2 set debug jb [off]\n"
05862          "       Enables/Disables jitterbuffer debugging information\n";
05863       return NULL;
05864    case CLI_GENERATE:
05865       return NULL;
05866    }
05867 
05868    if (a->argc < 4 || a->argc > 5)
05869       return CLI_SHOWUSAGE;
05870    
05871    if (a->argc == 4) {
05872       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05873       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05874    } else {
05875       jb_setoutput(jb_error_output, jb_warning_output, NULL);
05876       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05877    }
05878    return CLI_SUCCESS;
05879 }
05880 
05881 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05882 {
05883    switch (cmd) {
05884    case CLI_INIT:
05885       e->command = "iax2 set debug jb {on|off}";
05886       e->usage =
05887          "Usage: iax2 set debug jb {on|off}\n"
05888          "       Enables/Disables jitterbuffer debugging information\n";
05889       return NULL;
05890    case CLI_GENERATE:
05891       return NULL;
05892    }
05893 
05894    if (a->argc != e->args)
05895       return CLI_SHOWUSAGE;
05896    
05897    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05898       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05899       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05900    } else {
05901       jb_setoutput(jb_error_output, jb_warning_output, NULL);
05902       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05903    }
05904    return CLI_SUCCESS;
05905 }
05906 
05907 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05908 {
05909    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05910    int res = -1;
05911    ast_mutex_lock(&iaxsl[callno]);
05912    if (iaxs[callno]) {
05913    /* If there's an outstanding error, return failure now */
05914       if (!iaxs[callno]->error) {
05915          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05916             res = 0;
05917             /* Don't waste bandwidth sending null frames */
05918          else if (f->frametype == AST_FRAME_NULL)
05919             res = 0;
05920          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05921             res = 0;
05922          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05923             res = 0;
05924          else
05925          /* Simple, just queue for transmission */
05926             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05927       } else {
05928          ast_debug(1, "Write error: %s\n", strerror(errno));
05929       }
05930    }
05931    /* If it's already gone, just return */
05932    ast_mutex_unlock(&iaxsl[callno]);
05933    return res;
05934 }
05935 
05936 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05937       int now, int transfer, int final)
05938 {
05939    struct ast_frame f = { 0, };
05940 
05941    f.frametype = type;
05942    f.subclass = command;
05943    f.datalen = datalen;
05944    f.src = __FUNCTION__;
05945    f.data = (void *) data;
05946 
05947    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05948 }
05949 
05950 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05951 {
05952    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05953 }
05954 
05955 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05956 {
05957    int res;
05958    ast_mutex_lock(&iaxsl[callno]);
05959    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05960    ast_mutex_unlock(&iaxsl[callno]);
05961    return res;
05962 }
05963 
05964 /*!
05965  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05966  *       the pvt struct for the given call number may disappear during its 
05967  *       execution.
05968  */
05969 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)
05970 {
05971    int call_num = i->callno;
05972    /* It is assumed that the callno has already been locked */
05973    iax2_predestroy(i->callno);
05974    if (!iaxs[call_num])
05975       return -1;
05976    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05977 }
05978 
05979 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)
05980 {
05981    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05982 }
05983 
05984 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05985 {
05986    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05987 }
05988 
05989 static int apply_context(struct iax2_context *con, const char *context)
05990 {
05991    while(con) {
05992       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05993          return -1;
05994       con = con->next;
05995    }
05996    return 0;
05997 }
05998 
05999 
06000 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06001 {
06002    /* Start pessimistic */
06003    int res = -1;
06004    int version = 2;
06005    struct iax2_user *user = NULL, *best = NULL;
06006    int bestscore = 0;
06007    int gotcapability = 0;
06008    struct ast_variable *v = NULL, *tmpvar = NULL;
06009    struct ao2_iterator i;
06010 
06011    if (!iaxs[callno])
06012       return res;
06013    if (ies->called_number)
06014       ast_string_field_set(iaxs[callno], exten, ies->called_number);
06015    if (ies->calling_number) {
06016       ast_shrink_phone_number(ies->calling_number);
06017       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06018    }
06019    if (ies->calling_name)
06020       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06021    if (ies->calling_ani)
06022       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06023    if (ies->dnid)
06024       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06025    if (ies->rdnis)
06026       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06027    if (ies->called_context)
06028       ast_string_field_set(iaxs[callno], context, ies->called_context);
06029    if (ies->language)
06030       ast_string_field_set(iaxs[callno], language, ies->language);
06031    if (ies->username)
06032       ast_string_field_set(iaxs[callno], username, ies->username);
06033    if (ies->calling_ton > -1)
06034       iaxs[callno]->calling_ton = ies->calling_ton;
06035    if (ies->calling_tns > -1)
06036       iaxs[callno]->calling_tns = ies->calling_tns;
06037    if (ies->calling_pres > -1)
06038       iaxs[callno]->calling_pres = ies->calling_pres;
06039    if (ies->format)
06040       iaxs[callno]->peerformat = ies->format;
06041    if (ies->adsicpe)
06042       iaxs[callno]->peeradsicpe = ies->adsicpe;
06043    if (ies->capability) {
06044       gotcapability = 1;
06045       iaxs[callno]->peercapability = ies->capability;
06046    } 
06047    if (ies->version)
06048       version = ies->version;
06049 
06050    /* Use provided preferences until told otherwise for actual preferences */
06051    if(ies->codec_prefs) {
06052       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06053       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06054    }
06055 
06056    if (!gotcapability) 
06057       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06058    if (version > IAX_PROTO_VERSION) {
06059       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
06060          ast_inet_ntoa(sin->sin_addr), version);
06061       return res;
06062    }
06063    /* Search the userlist for a compatible entry, and fill in the rest */
06064    i = ao2_iterator_init(users, 0);
06065    while ((user = ao2_iterator_next(&i))) {
06066       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
06067          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
06068          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
06069          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
06070               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
06071          if (!ast_strlen_zero(iaxs[callno]->username)) {
06072             /* Exact match, stop right now. */
06073             if (best)
06074                user_unref(best);
06075             best = user;
06076             break;
06077          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06078             /* No required authentication */
06079             if (user->ha) {
06080                /* There was host authentication and we passed, bonus! */
06081                if (bestscore < 4) {
06082                   bestscore = 4;
06083                   if (best)
06084                      user_unref(best);
06085                   best = user;
06086                   continue;
06087                }
06088             } else {
06089                /* No host access, but no secret, either, not bad */
06090                if (bestscore < 3) {
06091                   bestscore = 3;
06092                   if (best)
06093                      user_unref(best);
06094                   best = user;
06095                   continue;
06096                }
06097             }
06098          } else {
06099             if (user->ha) {
06100                /* Authentication, but host access too, eh, it's something.. */
06101                if (bestscore < 2) {
06102                   bestscore = 2;
06103                   if (best)
06104                      user_unref(best);
06105                   best = user;
06106                   continue;
06107                }
06108             } else {
06109                /* Authentication and no host access...  This is our baseline */
06110                if (bestscore < 1) {
06111                   bestscore = 1;
06112                   if (best)
06113                      user_unref(best);
06114                   best = user;
06115                   continue;
06116                }
06117             }
06118          }
06119       }
06120       user_unref(user);
06121    }
06122    user = best;
06123    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06124       user = realtime_user(iaxs[callno]->username, sin);
06125       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
06126           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
06127          user = user_unref(user);
06128       }
06129    }
06130    if (user) {
06131       /* We found our match (use the first) */
06132       /* copy vars */
06133       for (v = user->vars ; v ; v = v->next) {
06134          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
06135             tmpvar->next = iaxs[callno]->vars; 
06136             iaxs[callno]->vars = tmpvar;
06137          }
06138       }
06139       /* If a max AUTHREQ restriction is in place, activate it */
06140       if (user->maxauthreq > 0)
06141          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06142       iaxs[callno]->prefs = user->prefs;
06143       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06144       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06145       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06146       iaxs[callno]->encmethods = user->encmethods;
06147       /* Store the requested username if not specified */
06148       if (ast_strlen_zero(iaxs[callno]->username))
06149          ast_string_field_set(iaxs[callno], username, user->name);
06150       /* Store whether this is a trunked call, too, of course, and move if appropriate */
06151       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06152       iaxs[callno]->capability = user->capability;
06153       /* And use the default context */
06154       if (ast_strlen_zero(iaxs[callno]->context)) {
06155          if (user->contexts)
06156             ast_string_field_set(iaxs[callno], context, user->contexts->context);
06157          else
06158             ast_string_field_set(iaxs[callno], context, context);
06159       }
06160       /* And any input keys */
06161       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06162       /* And the permitted authentication methods */
06163       iaxs[callno]->authmethods = user->authmethods;
06164       iaxs[callno]->adsi = user->adsi;
06165       /* If the user has callerid, override the remote caller id. */
06166       if (ast_test_flag(user, IAX_HASCALLERID)) {
06167          iaxs[callno]->calling_tns = 0;
06168          iaxs[callno]->calling_ton = 0;
06169          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06170          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06171          ast_string_field_set(iaxs[callno], ani, user->cid_num);
06172          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06173       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06174          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06175       } /* else user is allowed to set their own CID settings */
06176       if (!ast_strlen_zero(user->accountcode))
06177          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06178       if (!ast_strlen_zero(user->mohinterpret))
06179          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06180       if (!ast_strlen_zero(user->mohsuggest))
06181          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06182       if (user->amaflags)
06183          iaxs[callno]->amaflags = user->amaflags;
06184       if (!ast_strlen_zero(user->language))
06185          ast_string_field_set(iaxs[callno], language, user->language);
06186       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
06187       /* Keep this check last */
06188       if (!ast_strlen_zero(user->dbsecret)) {
06189          char *family, *key=NULL;
06190          char buf[80];
06191          family = ast_strdupa(user->dbsecret);
06192          key = strchr(family, '/');
06193          if (key) {
06194             *key = '\0';
06195             key++;
06196          }
06197          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06198             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06199          else
06200             ast_string_field_set(iaxs[callno], secret, buf);
06201       } else
06202          ast_string_field_set(iaxs[callno], secret, user->secret);
06203       res = 0;
06204       user = user_unref(user);
06205    } else {
06206        /* user was not found, but we should still fake an AUTHREQ.
06207         * Set authmethods to the last known authmethod used by the system
06208         * Set a fake secret, it's not looked at, just required to attempt authentication.
06209         * Set authrej so the AUTHREP is rejected without even looking at its contents */
06210       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06211       ast_string_field_set(iaxs[callno], secret, "badsecret");
06212       iaxs[callno]->authrej = 1;
06213       if (!ast_strlen_zero(iaxs[callno]->username)) {
06214          /* only send the AUTHREQ if a username was specified. */
06215          res = 0;
06216       }
06217    }
06218    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
06219    return res;
06220 }
06221 
06222 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
06223 {
06224    struct ast_iax2_full_hdr fh;
06225    fh.scallno = htons(src | IAX_FLAG_FULL);
06226    fh.dcallno = htons(dst);
06227    fh.ts = 0;
06228    fh.oseqno = 0;
06229    fh.iseqno = 0;
06230    fh.type = AST_FRAME_IAX;
06231    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06232    if (iaxdebug)
06233        iax_showframe(NULL, &fh, 0, sin, 0);
06234 #if 0
06235    if (option_debug)
06236 #endif   
06237       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06238          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06239    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06240 }
06241 
06242 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
06243 {
06244    /* Select exactly one common encryption if there are any */
06245    p->encmethods &= enc;
06246    if (p->encmethods) {
06247       if (p->encmethods & IAX_ENCRYPT_AES128)
06248          p->encmethods = IAX_ENCRYPT_AES128;
06249       else
06250          p->encmethods = 0;
06251    }
06252 }
06253 
06254 /*!
06255  * \pre iaxsl[call_num] is locked
06256  *
06257  * \note Since this function calls send_command_final(), the pvt struct for the given
06258  *       call number may disappear while executing this function.
06259  */
06260 static int authenticate_request(int call_num)
06261 {
06262    struct iax_ie_data ied;
06263    int res = -1, authreq_restrict = 0;
06264    char challenge[10];
06265    struct chan_iax2_pvt *p = iaxs[call_num];
06266 
06267    memset(&ied, 0, sizeof(ied));
06268 
06269    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
06270    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06271       struct iax2_user *user, tmp_user = {
06272          .name = p->username, 
06273       };
06274 
06275       user = ao2_find(users, &tmp_user, OBJ_POINTER);
06276       if (user) {
06277          if (user->curauthreq == user->maxauthreq)
06278             authreq_restrict = 1;
06279          else
06280             user->curauthreq++;
06281          user = user_unref(user);
06282       }
06283    }
06284 
06285    /* If the AUTHREQ limit test failed, send back an error */
06286    if (authreq_restrict) {
06287       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06288       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06289       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06290       return 0;
06291    }
06292 
06293    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06294    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06295       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06296       ast_string_field_set(p, challenge, challenge);
06297       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
06298       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06299    }
06300    if (p->encmethods)
06301       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06302 
06303    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06304 
06305    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06306 
06307    if (p->encmethods)
06308       ast_set_flag(p, IAX_ENCRYPTED);
06309 
06310    return res;
06311 }
06312 
06313 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
06314 {
06315    char requeststr[256];
06316    char md5secret[256] = "";
06317    char secret[256] = "";
06318    char rsasecret[256] = "";
06319    int res = -1; 
06320    int x;
06321    struct iax2_user *user, tmp_user = {
06322       .name = p->username, 
06323    };
06324 
06325    if (p->authrej) {
06326       return res;
06327    }
06328    user = ao2_find(users, &tmp_user, OBJ_POINTER);
06329    if (user) {
06330       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06331          ast_atomic_fetchadd_int(&user->curauthreq, -1);
06332          ast_clear_flag(p, IAX_MAXAUTHREQ);
06333       }
06334       ast_string_field_set(p, host, user->name);
06335       user = user_unref(user);
06336    }
06337 
06338    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06339       return res;
06340    if (ies->password)
06341       ast_copy_string(secret, ies->password, sizeof(secret));
06342    if (ies->md5_result)
06343       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06344    if (ies->rsa_result)
06345       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06346    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06347       struct ast_key *key;
06348       char *keyn;
06349       char tmpkey[256];
06350       char *stringp=NULL;
06351       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06352       stringp=tmpkey;
06353       keyn = strsep(&stringp, ":");
06354       while(keyn) {
06355          key = ast_key_get(keyn, AST_KEY_PUBLIC);
06356          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06357             res = 0;
06358             break;
06359          } else if (!key)
06360             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06361          keyn = strsep(&stringp, ":");
06362       }
06363    } else if (p->authmethods & IAX_AUTH_MD5) {
06364       struct MD5Context md5;
06365       unsigned char digest[16];
06366       char *tmppw, *stringp;
06367       
06368       tmppw = ast_strdupa(p->secret);
06369       stringp = tmppw;
06370       while((tmppw = strsep(&stringp, ";"))) {
06371          MD5Init(&md5);
06372          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06373          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06374          MD5Final(digest, &md5);
06375          /* If they support md5, authenticate with it.  */
06376          for (x=0;x<16;x++)
06377             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06378          if (!strcasecmp(requeststr, md5secret)) {
06379             res = 0;
06380             break;
06381          }
06382       }
06383    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06384       if (!strcmp(secret, p->secret))
06385          res = 0;
06386    }
06387    return res;
06388 }
06389 
06390 /*! \brief Verify inbound registration */
06391 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06392 {
06393    char requeststr[256] = "";
06394    char peer[256] = "";
06395    char md5secret[256] = "";
06396    char rsasecret[256] = "";
06397    char secret[256] = "";
06398    struct iax2_peer *p = NULL;
06399    struct ast_key *key;
06400    char *keyn;
06401    int x;
06402    int expire = 0;
06403    int res = -1;
06404 
06405    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06406    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
06407    if (ies->username)
06408       ast_copy_string(peer, ies->username, sizeof(peer));
06409    if (ies->password)
06410       ast_copy_string(secret, ies->password, sizeof(secret));
06411    if (ies->md5_result)
06412       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06413    if (ies->rsa_result)
06414       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06415    if (ies->refresh)
06416       expire = ies->refresh;
06417 
06418    if (ast_strlen_zero(peer)) {
06419       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06420       return -1;
06421    }
06422 
06423    /* SLD: first call to lookup peer during registration */
06424    ast_mutex_unlock(&iaxsl[callno]);
06425    p = find_peer(peer, 1);
06426    ast_mutex_lock(&iaxsl[callno]);
06427    if (!p || !iaxs[callno]) {
06428       if (iaxs[callno]) {
06429          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06430          /* Anything, as long as it's non-blank */
06431          ast_string_field_set(iaxs[callno], secret, "badsecret");
06432          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
06433           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
06434           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
06435           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
06436           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
06437           *
06438           * If none of these cases exist, res will be returned as 0 without authentication indicating
06439           * an AUTHREQ needs to be sent out. */
06440 
06441          if (ast_strlen_zero(iaxs[callno]->challenge) &&
06442             !(!ast_strlen_zero(secret) && plaintext)) {
06443             /* by setting res to 0, an REGAUTH will be sent */
06444             res = 0;
06445          }
06446       }
06447       if (authdebug && !p)
06448          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06449       goto return_unref;
06450    }
06451 
06452    if (!ast_test_flag(p, IAX_DYNAMIC)) {
06453       if (authdebug)
06454          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06455       goto return_unref;
06456    }
06457 
06458    if (!ast_apply_ha(p->ha, sin)) {
06459       if (authdebug)
06460          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06461       goto return_unref;
06462    }
06463    ast_string_field_set(iaxs[callno], secret, p->secret);
06464    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06465    /* Check secret against what we have on file */
06466    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06467       if (!ast_strlen_zero(p->inkeys)) {
06468          char tmpkeys[256];
06469          char *stringp=NULL;
06470          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06471          stringp=tmpkeys;
06472          keyn = strsep(&stringp, ":");
06473          while(keyn) {
06474             key = ast_key_get(keyn, AST_KEY_PUBLIC);
06475             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06476                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06477                break;
06478             } else if (!key)
06479                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06480             keyn = strsep(&stringp, ":");
06481          }
06482          if (!keyn) {
06483             if (authdebug)
06484                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06485             goto return_unref;
06486          }
06487       } else {
06488          if (authdebug)
06489             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06490          goto return_unref;
06491       }
06492    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06493       struct MD5Context md5;
06494       unsigned char digest[16];
06495       char *tmppw, *stringp;
06496 
06497       tmppw = ast_strdupa(p->secret);
06498       stringp = tmppw;
06499       while((tmppw = strsep(&stringp, ";"))) {
06500          MD5Init(&md5);
06501          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06502          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06503          MD5Final(digest, &md5);
06504          for (x=0;x<16;x++)
06505             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06506          if (!strcasecmp(requeststr, md5secret))
06507             break;
06508       }
06509       if (tmppw) {
06510          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06511       } else {
06512          if (authdebug)
06513             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06514          goto return_unref;
06515       }
06516    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06517       /* They've provided a plain text password and we support that */
06518       if (strcmp(secret, p->secret)) {
06519          if (authdebug)
06520             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06521          goto return_unref;
06522       } else
06523          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06524    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06525       /* if challenge has been sent, but no challenge response if given, reject. */
06526       goto return_unref;
06527    }
06528    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
06529 
06530    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
06531    res = 0;
06532 
06533 return_unref:
06534    if (iaxs[callno]) {
06535       ast_string_field_set(iaxs[callno], peer, peer);
06536 
06537       /* Choose lowest expiry number */
06538       if (expire && (expire < iaxs[callno]->expiry)) {
06539          iaxs[callno]->expiry = expire;
06540       }
06541    }
06542 
06543    if (p) {
06544       peer_unref(p);
06545    }
06546    return res;
06547 }
06548 
06549 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)
06550 {
06551    int res = -1;
06552    int x;
06553    if (!ast_strlen_zero(keyn)) {
06554       if (!(authmethods & IAX_AUTH_RSA)) {
06555          if (ast_strlen_zero(secret)) 
06556             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));
06557       } else if (ast_strlen_zero(challenge)) {
06558          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06559       } else {
06560          char sig[256];
06561          struct ast_key *key;
06562          key = ast_key_get(keyn, AST_KEY_PRIVATE);
06563          if (!key) {
06564             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06565          } else {
06566             if (ast_sign(key, (char*)challenge, sig)) {
06567                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06568                res = -1;
06569             } else {
06570                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06571                res = 0;
06572             }
06573          }
06574       }
06575    } 
06576    /* Fall back */
06577    if (res && !ast_strlen_zero(secret)) {
06578       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06579          struct MD5Context md5;
06580          unsigned char digest[16];
06581          char digres[128];
06582          MD5Init(&md5);
06583          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06584          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06585          MD5Final(digest, &md5);
06586          /* If they support md5, authenticate with it.  */
06587          for (x=0;x<16;x++)
06588             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
06589          if (pvt) {
06590             build_encryption_keys(digest, pvt);
06591          }
06592          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06593          res = 0;
06594       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06595          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06596          res = 0;
06597       } else
06598          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06599    }
06600    return res;
06601 }
06602 
06603 /*!
06604  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
06605  *       so do not call this function with a pvt lock held.
06606  */
06607 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
06608 {
06609    struct iax2_peer *peer = NULL;
06610    /* Start pessimistic */
06611    int res = -1;
06612    int authmethods = 0;
06613    struct iax_ie_data ied;
06614    uint16_t callno = p->callno;
06615 
06616    memset(&ied, 0, sizeof(ied));
06617    
06618    if (ies->username)
06619       ast_string_field_set(p, username, ies->username);
06620    if (ies->challenge)
06621       ast_string_field_set(p, challenge, ies->challenge);
06622    if (ies->authmethods)
06623       authmethods = ies->authmethods;
06624    if (authmethods & IAX_AUTH_MD5)
06625       merge_encryption(p, ies->encmethods);
06626    else
06627       p->encmethods = 0;
06628 
06629    /* Check for override RSA authentication first */
06630    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06631       /* Normal password authentication */
06632       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06633    } else {
06634       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06635       while ((peer = ao2_iterator_next(&i))) {
06636          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
06637              /* No peer specified at our end, or this is the peer */
06638              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06639              /* No username specified in peer rule, or this is the right username */
06640              && (!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)))
06641              /* No specified host, or this is our host */
06642             ) {
06643             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06644             if (!res) {
06645                peer_unref(peer);
06646                break;
06647             }
06648          }
06649          peer_unref(peer);
06650       }
06651       if (!peer) {
06652          /* We checked our list and didn't find one.  It's unlikely, but possible, 
06653             that we're trying to authenticate *to* a realtime peer */
06654          const char *peer_name = ast_strdupa(p->peer);
06655          ast_mutex_unlock(&iaxsl[callno]);
06656          if ((peer = realtime_peer(peer_name, NULL))) {
06657             ast_mutex_lock(&iaxsl[callno]);
06658             if (!(p = iaxs[callno])) {
06659                peer_unref(peer);
06660                return -1;
06661             }
06662             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06663             peer_unref(peer);
06664          }
06665          if (!peer) {
06666             ast_mutex_lock(&iaxsl[callno]);
06667             if (!(p = iaxs[callno]))
06668                return -1;
06669          }
06670       }
06671    }
06672    if (ies->encmethods)
06673       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06674    if (!res) {
06675       struct ast_datastore *variablestore;
06676       struct ast_variable *var, *prev = NULL;
06677       AST_LIST_HEAD(, ast_var_t) *varlist;
06678       varlist = ast_calloc(1, sizeof(*varlist));
06679       variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
06680       if (variablestore && varlist && p->owner) {
06681          variablestore->data = varlist;
06682          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
06683          AST_LIST_HEAD_INIT(varlist);
06684          for (var = ies->vars; var; var = var->next) {
06685             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
06686             if (prev)
06687                ast_free(prev);
06688             prev = var;
06689             if (!newvar) {
06690                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
06691                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06692             } else {
06693                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
06694             }
06695          }
06696          if (prev)
06697             ast_free(prev);
06698          ies->vars = NULL;
06699          ast_channel_datastore_add(p->owner, variablestore);
06700       } else {
06701          if (p->owner)
06702             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06703          if (variablestore)
06704             ast_channel_datastore_free(variablestore);
06705          if (varlist)
06706             ast_free(varlist);
06707       }
06708    }
06709 
06710    if (!res)
06711       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06712    return res;
06713 }
06714 
06715 static int iax2_do_register(struct iax2_registry *reg);
06716 
06717 static void __iax2_do_register_s(const void *data)
06718 {
06719    struct iax2_registry *reg = (struct iax2_registry *)data;
06720    reg->expire = -1;
06721    iax2_do_register(reg);
06722 }
06723 
06724 static int iax2_do_register_s(const void *data)
06725 {
06726 #ifdef SCHED_MULTITHREADED
06727    if (schedule_action(__iax2_do_register_s, data))
06728 #endif      
06729       __iax2_do_register_s(data);
06730    return 0;
06731 }
06732 
06733 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06734 {
06735    int newcall = 0;
06736    char newip[256];
06737    struct iax_ie_data ied;
06738    struct sockaddr_in new;
06739    
06740    
06741    memset(&ied, 0, sizeof(ied));
06742    if (ies->apparent_addr)
06743       memmove(&new, ies->apparent_addr, sizeof(new));
06744    if (ies->callno)
06745       newcall = ies->callno;
06746    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
06747       ast_log(LOG_WARNING, "Invalid transfer request\n");
06748       return -1;
06749    }
06750    pvt->transfercallno = newcall;
06751    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
06752    inet_aton(newip, &pvt->transfer.sin_addr);
06753    pvt->transfer.sin_family = AF_INET;
06754    pvt->transferring = TRANSFER_BEGIN;
06755    pvt->transferid = ies->transferid;
06756    store_by_transfercallno(pvt);
06757    if (ies->transferid)
06758       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
06759    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
06760    return 0;
06761 }
06762 
06763 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06764 {
06765    char exten[256] = "";
06766    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
06767    struct iax2_dpcache *dp = NULL;
06768    
06769    if (ies->called_number)
06770       ast_copy_string(exten, ies->called_number, sizeof(exten));
06771    
06772    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
06773       status = CACHE_FLAG_EXISTS;
06774    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
06775       status = CACHE_FLAG_CANEXIST;
06776    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
06777       status = CACHE_FLAG_NONEXISTENT;
06778 
06779    if (ies->refresh)
06780       expiry = ies->refresh;
06781    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
06782       matchmore = CACHE_FLAG_MATCHMORE;
06783    
06784    AST_LIST_LOCK(&dpcache);
06785    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
06786       if (strcmp(dp->exten, exten))
06787          continue;
06788       AST_LIST_REMOVE_CURRENT(peer_list);
06789       dp->callno = 0;
06790       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06791       if (dp->flags & CACHE_FLAG_PENDING) {
06792          dp->flags &= ~CACHE_FLAG_PENDING;
06793          dp->flags |= status;
06794          dp->flags |= matchmore;
06795       }
06796       /* Wake up waiters */
06797       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06798          if (dp->waiters[x] > -1) {
06799             if (write(dp->waiters[x], "asdf", 4) < 0) {
06800             }
06801          }
06802       }
06803    }
06804    AST_LIST_TRAVERSE_SAFE_END;
06805    AST_LIST_UNLOCK(&dpcache);
06806 
06807    return 0;
06808 }
06809 
06810 static int complete_transfer(int callno, struct iax_ies *ies)
06811 {
06812    int peercallno = 0;
06813    struct chan_iax2_pvt *pvt = iaxs[callno];
06814    struct iax_frame *cur;
06815    jb_frame frame;
06816 
06817    if (ies->callno)
06818       peercallno = ies->callno;
06819 
06820    if (peercallno < 1) {
06821       ast_log(LOG_WARNING, "Invalid transfer request\n");
06822       return -1;
06823    }
06824    remove_by_transfercallno(pvt);
06825    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06826    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06827    /* Reset sequence numbers */
06828    pvt->oseqno = 0;
06829    pvt->rseqno = 0;
06830    pvt->iseqno = 0;
06831    pvt->aseqno = 0;
06832 
06833    if (pvt->peercallno) {
06834       remove_by_peercallno(pvt);
06835    }
06836    pvt->peercallno = peercallno;
06837    /*this is where the transfering call swiches hash tables */
06838    store_by_peercallno(pvt);
06839    pvt->transferring = TRANSFER_NONE;
06840    pvt->svoiceformat = -1;
06841    pvt->voiceformat = 0;
06842    pvt->svideoformat = -1;
06843    pvt->videoformat = 0;
06844    pvt->transfercallno = -1;
06845    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06846    memset(&pvt->offset, 0, sizeof(pvt->offset));
06847    /* reset jitterbuffer */
06848    while(jb_getall(pvt->jb,&frame) == JB_OK)
06849       iax2_frame_free(frame.data);
06850    jb_reset(pvt->jb);
06851    pvt->lag = 0;
06852    pvt->last = 0;
06853    pvt->lastsent = 0;
06854    pvt->nextpred = 0;
06855    pvt->pingtime = DEFAULT_RETRY_TIME;
06856    AST_LIST_LOCK(&frame_queue);
06857    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
06858       /* We must cancel any packets that would have been transmitted
06859          because now we're talking to someone new.  It's okay, they
06860          were transmitted to someone that didn't care anyway. */
06861       if (callno == cur->callno) 
06862          cur->retries = -1;
06863    }
06864    AST_LIST_UNLOCK(&frame_queue);
06865    return 0; 
06866 }
06867 
06868 /*! \brief Acknowledgment received for OUR registration */
06869 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06870 {
06871    struct iax2_registry *reg;
06872    /* Start pessimistic */
06873    char peer[256] = "";
06874    char msgstatus[60];
06875    int refresh = 60;
06876    char ourip[256] = "<Unspecified>";
06877    struct sockaddr_in oldus;
06878    struct sockaddr_in us;
06879    int oldmsgs;
06880 
06881    memset(&us, 0, sizeof(us));
06882    if (ies->apparent_addr)
06883       memmove(&us, ies->apparent_addr, sizeof(us));
06884    if (ies->username)
06885       ast_copy_string(peer, ies->username, sizeof(peer));
06886    if (ies->refresh)
06887       refresh = ies->refresh;
06888    if (ies->calling_number) {
06889       /* We don't do anything with it really, but maybe we should */
06890    }
06891    reg = iaxs[callno]->reg;
06892    if (!reg) {
06893       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06894       return -1;
06895    }
06896    memcpy(&oldus, &reg->us, sizeof(oldus));
06897    oldmsgs = reg->messages;
06898    if (inaddrcmp(&reg->addr, sin)) {
06899       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06900       return -1;
06901    }
06902    memcpy(&reg->us, &us, sizeof(reg->us));
06903    if (ies->msgcount >= 0)
06904       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
06905    /* always refresh the registration at the interval requested by the server
06906       we are registering to
06907    */
06908    reg->refresh = refresh;
06909    reg->expire = iax2_sched_replace(reg->expire, sched, 
06910       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06911    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
06912          if (reg->messages > 255)
06913             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06914          else if (reg->messages > 1)
06915             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06916          else if (reg->messages > 0)
06917             ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
06918          else
06919             ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
06920          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06921       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06922       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06923    }
06924    reg->regstate = REG_STATE_REGISTERED;
06925    return 0;
06926 }
06927 
06928 static int iax2_append_register(const char *hostname, const char *username,
06929    const char *secret, const char *porta)
06930 {
06931    struct iax2_registry *reg;
06932 
06933    if (!(reg = ast_calloc(1, sizeof(*reg))))
06934       return -1;
06935 
06936    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06937       ast_free(reg);
06938       return -1;
06939    }
06940 
06941    ast_copy_string(reg->username, username, sizeof(reg->username));
06942 
06943    if (secret)
06944       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06945 
06946    reg->expire = -1;
06947    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06948    reg->addr.sin_family = AF_INET;
06949    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06950 
06951    AST_LIST_LOCK(&registrations);
06952    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06953    AST_LIST_UNLOCK(&registrations);
06954    
06955    return 0;
06956 }
06957 
06958 static int iax2_register(const char *value, int lineno)
06959 {
06960    char copy[256];
06961    char *username, *hostname, *secret;
06962    char *porta;
06963    char *stringp=NULL;
06964    
06965    if (!value)
06966       return -1;
06967 
06968    ast_copy_string(copy, value, sizeof(copy));
06969    stringp = copy;
06970    username = strsep(&stringp, "@");
06971    hostname = strsep(&stringp, "@");
06972 
06973    if (!hostname) {
06974       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06975       return -1;
06976    }
06977 
06978    stringp = username;
06979    username = strsep(&stringp, ":");
06980    secret = strsep(&stringp, ":");
06981    stringp = hostname;
06982    hostname = strsep(&stringp, ":");
06983    porta = strsep(&stringp, ":");
06984    
06985    if (porta && !atoi(porta)) {
06986       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06987       return -1;
06988    }
06989 
06990    return iax2_append_register(hostname, username, secret, porta);
06991 }
06992 
06993 
06994 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06995 {
06996    char multi[256];
06997    char *stringp, *ext;
06998    if (!ast_strlen_zero(regcontext)) {
06999       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07000       stringp = multi;
07001       while((ext = strsep(&stringp, "&"))) {
07002          if (onoff) {
07003             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07004                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07005                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07006          } else
07007             ast_context_remove_extension(regcontext, ext, 1, NULL);
07008       }
07009    }
07010 }
07011 static void prune_peers(void);
07012 
07013 static void unlink_peer(struct iax2_peer *peer)
07014 {
07015    if (peer->expire > -1) {
07016       if (!ast_sched_del(sched, peer->expire)) {
07017          peer->expire = -1;
07018          peer_unref(peer);
07019       }
07020    }
07021 
07022    if (peer->pokeexpire > -1) {
07023       if (!ast_sched_del(sched, peer->pokeexpire)) {
07024          peer->pokeexpire = -1;
07025          peer_unref(peer);
07026       }
07027    }
07028 
07029    ao2_unlink(peers, peer);
07030 }
07031 
07032 static void __expire_registry(const void *data)
07033 {
07034    struct iax2_peer *peer = (struct iax2_peer *) data;
07035 
07036    if (!peer)
07037       return;
07038 
07039    peer->expire = -1;
07040 
07041    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
07042    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07043       realtime_update_peer(peer->name, &peer->addr, 0);
07044    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07045    /* Reset the address */
07046    memset(&peer->addr, 0, sizeof(peer->addr));
07047    /* Reset expiry value */
07048    peer->expiry = min_reg_expire;
07049    if (!ast_test_flag(peer, IAX_TEMPONLY))
07050       ast_db_del("IAX/Registry", peer->name);
07051    register_peer_exten(peer, 0);
07052    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07053    if (iax2_regfunk)
07054       iax2_regfunk(peer->name, 0);
07055 
07056    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07057       unlink_peer(peer);
07058 
07059    peer_unref(peer);
07060 }
07061 
07062 static int expire_registry(const void *data)
07063 {
07064 #ifdef SCHED_MULTITHREADED
07065    if (schedule_action(__expire_registry, data))
07066 #endif      
07067       __expire_registry(data);
07068    return 0;
07069 }
07070 
07071 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
07072 
07073 static void reg_source_db(struct iax2_peer *p)
07074 {
07075    char data[80];
07076    struct in_addr in;
07077    char *c, *d;
07078    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07079       c = strchr(data, ':');
07080       if (c) {
07081          *c = '\0';
07082          c++;
07083          if (inet_aton(data, &in)) {
07084             d = strchr(c, ':');
07085             if (d) {
07086                *d = '\0';
07087                d++;
07088                ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
07089                   ast_inet_ntoa(in), atoi(c), atoi(d));
07090                iax2_poke_peer(p, 0);
07091                p->expiry = atoi(d);
07092                memset(&p->addr, 0, sizeof(p->addr));
07093                p->addr.sin_family = AF_INET;
07094                p->addr.sin_addr = in;
07095                p->addr.sin_port = htons(atoi(c));
07096                if (p->expire > -1) {
07097                   if (!ast_sched_del(sched, p->expire)) {
07098                      p->expire = -1;
07099                      peer_unref(p);
07100                   }
07101                }
07102                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07103                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07104                if (p->expire == -1)
07105                   peer_unref(p);
07106                if (iax2_regfunk)
07107                   iax2_regfunk(p->name, 1);
07108                register_peer_exten(p, 1);
07109             }              
07110                
07111          }
07112       }
07113    }
07114 }
07115 
07116 /*!
07117  * \pre iaxsl[callno] is locked
07118  *
07119  * \note Since this function calls send_command_final(), the pvt struct for
07120  *       the given call number may disappear while executing this function.
07121  */
07122 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
07123 {
07124    /* Called from IAX thread only, with proper iaxsl lock */
07125    struct iax_ie_data ied;
07126    struct iax2_peer *p;
07127    int msgcount;
07128    char data[80];
07129    int version;
07130    const char *peer_name;
07131    int res = -1;
07132 
07133    memset(&ied, 0, sizeof(ied));
07134 
07135    peer_name = ast_strdupa(iaxs[callno]->peer);
07136 
07137    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
07138    ast_mutex_unlock(&iaxsl[callno]);
07139    if (!(p = find_peer(peer_name, 1))) {
07140       ast_mutex_lock(&iaxsl[callno]);
07141       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07142       return -1;
07143    }
07144    ast_mutex_lock(&iaxsl[callno]);
07145    if (!iaxs[callno])
07146       goto return_unref;
07147 
07148    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07149       if (sin->sin_addr.s_addr) {
07150          time_t nowtime;
07151          time(&nowtime);
07152          realtime_update_peer(peer_name, sin, nowtime);
07153       } else {
07154          realtime_update_peer(peer_name, sin, 0);
07155       }
07156    }
07157    if (inaddrcmp(&p->addr, sin)) {
07158       if (iax2_regfunk)
07159          iax2_regfunk(p->name, 1);
07160       /* Stash the IP address from which they registered */
07161       memcpy(&p->addr, sin, sizeof(p->addr));
07162       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07163       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07164          ast_db_put("IAX/Registry", p->name, data);
07165          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
07166                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07167          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07168          register_peer_exten(p, 1);
07169          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07170       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07171          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
07172                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07173          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07174          register_peer_exten(p, 0);
07175          ast_db_del("IAX/Registry", p->name);
07176          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07177       }
07178       /* Update the host */
07179       /* Verify that the host is really there */
07180       iax2_poke_peer(p, callno);
07181    }     
07182 
07183    /* Make sure our call still exists, an INVAL at the right point may make it go away */
07184    if (!iaxs[callno]) {
07185       res = -1;
07186       goto return_unref;
07187    }
07188 
07189    /* Store socket fd */
07190    p->sockfd = fd;
07191    /* Setup the expiry */
07192    if (p->expire > -1) {
07193       if (!ast_sched_del(sched, p->expire)) {
07194          p->expire = -1;
07195          peer_unref(p);
07196       }
07197    }
07198    /* treat an unspecified refresh interval as the minimum */
07199    if (!refresh)
07200       refresh = min_reg_expire;
07201    if (refresh > max_reg_expire) {
07202       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07203          p->name, max_reg_expire, refresh);
07204       p->expiry = max_reg_expire;
07205    } else if (refresh < min_reg_expire) {
07206       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07207          p->name, min_reg_expire, refresh);
07208       p->expiry = min_reg_expire;
07209    } else {
07210       p->expiry = refresh;
07211    }
07212    if (p->expiry && sin->sin_addr.s_addr) {
07213       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07214       if (p->expire == -1)
07215          peer_unref(p);
07216    }
07217    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07218    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07219    if (sin->sin_addr.s_addr) {
07220       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07221       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07222       if (!ast_strlen_zero(p->mailbox)) {
07223          struct ast_event *event;
07224          int new, old;
07225          char *mailbox, *context;
07226 
07227          context = mailbox = ast_strdupa(p->mailbox);
07228          strsep(&context, "@");
07229          if (ast_strlen_zero(context))
07230             context = "default";
07231 
07232          event = ast_event_get_cached(AST_EVENT_MWI,
07233             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
07234             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
07235             AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
07236             AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
07237             AST_EVENT_IE_END);
07238          if (event) {
07239             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07240             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
07241             ast_event_destroy(event);
07242          } else /* Fall back on checking the mailbox directly */
07243             ast_app_inboxcount(p->mailbox, &new, &old);
07244 
07245          if (new > 255)
07246             new = 255;
07247          if (old > 255)
07248             old = 255;
07249          msgcount = (old << 8) | new;
07250 
07251          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07252       }
07253       if (ast_test_flag(p, IAX_HASCALLERID)) {
07254          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07255          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07256       }
07257    }
07258    version = iax_check_version(devtype);
07259    if (version) 
07260       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07261 
07262    res = 0;
07263 
07264 return_unref:
07265    peer_unref(p);
07266 
07267    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07268 }
07269 
07270 static int registry_authrequest(int callno)
07271 {
07272    struct iax_ie_data ied;
07273    struct iax2_peer *p;
07274    char challenge[10];
07275    const char *peer_name;
07276    int sentauthmethod;
07277 
07278    peer_name = ast_strdupa(iaxs[callno]->peer);
07279 
07280    /* SLD: third call to find_peer in registration */
07281    ast_mutex_unlock(&iaxsl[callno]);
07282    if ((p = find_peer(peer_name, 1))) {
07283       last_authmethod = p->authmethods;
07284    }
07285 
07286    ast_mutex_lock(&iaxsl[callno]);
07287    if (!iaxs[callno])
07288       goto return_unref;
07289 
07290    memset(&ied, 0, sizeof(ied));
07291    /* The selection of which delayed reject is sent may leak information,
07292     * if it sets a static response.  For example, if a host is known to only
07293     * use MD5 authentication, then an RSA response would indicate that the
07294     * peer does not exist, and vice-versa.
07295     * Therefore, we use whatever the last peer used (which may vary over the
07296     * course of a server, which should leak minimal information). */
07297    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07298    if (!p) {
07299       iaxs[callno]->authmethods = sentauthmethod;
07300    }
07301    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07302    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07303       /* Build the challenge */
07304       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07305       ast_string_field_set(iaxs[callno], challenge, challenge);
07306       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07307    }
07308    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07309 
07310 return_unref:
07311    if (p) {
07312       peer_unref(p);
07313    }
07314 
07315    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07316 }
07317 
07318 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
07319 {
07320    struct iax2_registry *reg;
07321    /* Start pessimistic */
07322    struct iax_ie_data ied;
07323    char peer[256] = "";
07324    char challenge[256] = "";
07325    int res;
07326    int authmethods = 0;
07327    if (ies->authmethods)
07328       authmethods = ies->authmethods;
07329    if (ies->username)
07330       ast_copy_string(peer, ies->username, sizeof(peer));
07331    if (ies->challenge)
07332       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07333    memset(&ied, 0, sizeof(ied));
07334    reg = iaxs[callno]->reg;
07335    if (reg) {
07336          if (inaddrcmp(&reg->addr, sin)) {
07337             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07338             return -1;
07339          }
07340          if (ast_strlen_zero(reg->secret)) {
07341             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07342             reg->regstate = REG_STATE_NOAUTH;
07343             return -1;
07344          }
07345          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07346          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07347          if (reg->secret[0] == '[') {
07348             char tmpkey[256];
07349             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07350             tmpkey[strlen(tmpkey) - 1] = '\0';
07351             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07352          } else
07353             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07354          if (!res) {
07355             reg->regstate = REG_STATE_AUTHSENT;
07356             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07357          } else
07358             return -1;
07359          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07360    } else   
07361       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07362    return -1;
07363 }
07364 
07365 static void stop_stuff(int callno)
07366 {
07367    iax2_destroy_helper(iaxs[callno]);
07368 }
07369 
07370 static void __auth_reject(const void *nothing)
07371 {
07372    /* Called from IAX thread only, without iaxs lock */
07373    int callno = (int)(long)(nothing);
07374    struct iax_ie_data ied;
07375    ast_mutex_lock(&iaxsl[callno]);
07376    if (iaxs[callno]) {
07377       memset(&ied, 0, sizeof(ied));
07378       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07379          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07380          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07381       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07382          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07383          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07384       }
07385       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07386    }
07387    ast_mutex_unlock(&iaxsl[callno]);
07388 }
07389 
07390 static int auth_reject(const void *data)
07391 {
07392    int callno = (int)(long)(data);
07393    ast_mutex_lock(&iaxsl[callno]);
07394    if (iaxs[callno])
07395       iaxs[callno]->authid = -1;
07396    ast_mutex_unlock(&iaxsl[callno]);
07397 #ifdef SCHED_MULTITHREADED
07398    if (schedule_action(__auth_reject, data))
07399 #endif      
07400       __auth_reject(data);
07401    return 0;
07402 }
07403 
07404 static int auth_fail(int callno, int failcode)
07405 {
07406    /* Schedule sending the authentication failure in one second, to prevent
07407       guessing */
07408    if (iaxs[callno]) {
07409       iaxs[callno]->authfail = failcode;
07410       if (delayreject) {
07411          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
07412             sched, 1000, auth_reject, (void *)(long)callno);
07413       } else
07414          auth_reject((void *)(long)callno);
07415    }
07416    return 0;
07417 }
07418 
07419 static void __auto_hangup(const void *nothing)
07420 {
07421    /* Called from IAX thread only, without iaxs lock */
07422    int callno = (int)(long)(nothing);
07423    struct iax_ie_data ied;
07424    ast_mutex_lock(&iaxsl[callno]);
07425    if (iaxs[callno]) {
07426       memset(&ied, 0, sizeof(ied));
07427       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07428       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07429       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07430    }
07431    ast_mutex_unlock(&iaxsl[callno]);
07432 }
07433 
07434 static int auto_hangup(const void *data)
07435 {
07436    int callno = (int)(long)(data);
07437    ast_mutex_lock(&iaxsl[callno]);
07438    if (iaxs[callno]) {
07439       iaxs[callno]->autoid = -1;
07440    }
07441    ast_mutex_unlock(&iaxsl[callno]);
07442 #ifdef SCHED_MULTITHREADED
07443    if (schedule_action(__auto_hangup, data))
07444 #endif      
07445       __auto_hangup(data);
07446    return 0;
07447 }
07448 
07449 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
07450 {
07451    struct iax_ie_data ied;
07452    /* Auto-hangup with 30 seconds of inactivity */
07453    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
07454       sched, 30000, auto_hangup, (void *)(long)callno);
07455    memset(&ied, 0, sizeof(ied));
07456    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07457    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07458    dp->flags |= CACHE_FLAG_TRANSMITTED;
07459 }
07460 
07461 static int iax2_vnak(int callno)
07462 {
07463    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07464 }
07465 
07466 static void vnak_retransmit(int callno, int last)
07467 {
07468    struct iax_frame *f;
07469 
07470    AST_LIST_LOCK(&frame_queue);
07471    AST_LIST_TRAVERSE(&frame_queue, f, list) {
07472       /* Send a copy immediately */
07473       if ((f->callno == callno) && iaxs[f->callno] &&
07474          ((unsigned char ) (f->oseqno - last) < 128) &&
07475          (f->retries >= 0)) {
07476          send_packet(f);
07477       }
07478    }
07479    AST_LIST_UNLOCK(&frame_queue);
07480 }
07481 
07482 static void __iax2_poke_peer_s(const void *data)
07483 {
07484    struct iax2_peer *peer = (struct iax2_peer *)data;
07485    iax2_poke_peer(peer, 0);
07486    peer_unref(peer);
07487 }
07488 
07489 static int iax2_poke_peer_s(const void *data)
07490 {
07491    struct iax2_peer *peer = (struct iax2_peer *)data;
07492    peer->pokeexpire = -1;
07493 #ifdef SCHED_MULTITHREADED
07494    if (schedule_action(__iax2_poke_peer_s, data))
07495 #endif      
07496       __iax2_poke_peer_s(data);
07497    return 0;
07498 }
07499 
07500 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
07501 {
07502    int res = 0;
07503    struct iax_frame *fr;
07504    struct ast_iax2_meta_hdr *meta;
07505    struct ast_iax2_meta_trunk_hdr *mth;
07506    int calls = 0;
07507    
07508    /* Point to frame */
07509    fr = (struct iax_frame *)tpeer->trunkdata;
07510    /* Point to meta data */
07511    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07512    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07513    if (tpeer->trunkdatalen) {
07514       /* We're actually sending a frame, so fill the meta trunk header and meta header */
07515       meta->zeros = 0;
07516       meta->metacmd = IAX_META_TRUNK;
07517       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07518          meta->cmddata = IAX_META_TRUNK_MINI;
07519       else
07520          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07521       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07522       /* And the rest of the ast_iax2 header */
07523       fr->direction = DIRECTION_OUTGRESS;
07524       fr->retrans = -1;
07525       fr->transfer = 0;
07526       /* Any appropriate call will do */
07527       fr->data = fr->afdata;
07528       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07529       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07530       calls = tpeer->calls;
07531 #if 0
07532       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));
07533 #endif      
07534       /* Reset transmit trunk side data */
07535       tpeer->trunkdatalen = 0;
07536       tpeer->calls = 0;
07537    }
07538    if (res < 0)
07539       return res;
07540    return calls;
07541 }
07542 
07543 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
07544 {
07545    /* Drop when trunk is about 5 seconds idle */
07546    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
07547       return 1;
07548    return 0;
07549 }
07550 
07551 static int timing_read(int *id, int fd, short events, void *cbdata)
07552 {
07553    char buf[1024];
07554    int res, processed = 0, totalcalls = 0;
07555    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
07556 #ifdef DAHDI_TIMERACK
07557    int x = 1;
07558 #endif
07559    struct timeval now = ast_tvnow();
07560    if (iaxtrunkdebug)
07561       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
07562    if (events & AST_IO_PRI) {
07563 #ifdef DAHDI_TIMERACK
07564       /* Great, this is a timing interface, just call the ioctl */
07565       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
07566          ast_log(LOG_WARNING, "Unable to acknowledge DAHDI timer. IAX trunking will fail!\n");
07567          usleep(1);
07568          return -1;
07569       }
07570 #endif      
07571    } else {
07572       /* Read and ignore from the pseudo channel for timing */
07573       res = read(fd, buf, sizeof(buf));
07574       if (res < 1) {
07575          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
07576          return 1;
07577       }
07578    }
07579    /* For each peer that supports trunking... */
07580    AST_LIST_LOCK(&tpeers);
07581    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
07582       processed++;
07583       res = 0;
07584       ast_mutex_lock(&tpeer->lock);
07585       /* We can drop a single tpeer per pass.  That makes all this logic
07586          substantially easier */
07587       if (!drop && iax2_trunk_expired(tpeer, &now)) {
07588          /* Take it out of the list, but don't free it yet, because it
07589             could be in use */
07590          AST_LIST_REMOVE_CURRENT(list);
07591          drop = tpeer;
07592       } else {
07593          res = send_trunk(tpeer, &now);
07594          trunk_timed++; 
07595          if (iaxtrunkdebug)
07596             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);
07597       }     
07598       totalcalls += res;   
07599       res = 0;
07600       ast_mutex_unlock(&tpeer->lock);
07601    }
07602    AST_LIST_TRAVERSE_SAFE_END;
07603    AST_LIST_UNLOCK(&tpeers);
07604 
07605    if (drop) {
07606       ast_mutex_lock(&drop->lock);
07607       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
07608          because by the time they could get tpeerlock, we've already grabbed it */
07609       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07610       if (drop->trunkdata) {
07611          ast_free(drop->trunkdata);
07612          drop->trunkdata = NULL;
07613       }
07614       ast_mutex_unlock(&drop->lock);
07615       ast_mutex_destroy(&drop->lock);
07616       ast_free(drop);
07617       
07618    }
07619 
07620    if (iaxtrunkdebug)
07621       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07622    iaxtrunkdebug = 0;
07623 
07624    return 1;
07625 }
07626 
07627 struct dpreq_data {
07628    int callno;
07629    char context[AST_MAX_EXTENSION];
07630    char callednum[AST_MAX_EXTENSION];
07631    char *callerid;
07632 };
07633 
07634 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
07635 {
07636    unsigned short dpstatus = 0;
07637    struct iax_ie_data ied1;
07638    int mm;
07639 
07640    memset(&ied1, 0, sizeof(ied1));
07641    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07642    /* Must be started */
07643    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07644       dpstatus = IAX_DPSTATUS_EXISTS;
07645    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07646       dpstatus = IAX_DPSTATUS_CANEXIST;
07647    } else {
07648       dpstatus = IAX_DPSTATUS_NONEXISTENT;
07649    }
07650    if (ast_ignore_pattern(context, callednum))
07651       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07652    if (mm)
07653       dpstatus |= IAX_DPSTATUS_MATCHMORE;
07654    if (!skiplock)
07655       ast_mutex_lock(&iaxsl[callno]);
07656    if (iaxs[callno]) {
07657       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07658       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07659       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07660       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07661    }
07662    if (!skiplock)
07663       ast_mutex_unlock(&iaxsl[callno]);
07664 }
07665 
07666 static void *dp_lookup_thread(void *data)
07667 {
07668    /* Look up for dpreq */
07669    struct dpreq_data *dpr = data;
07670    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07671    if (dpr->callerid)
07672       ast_free(dpr->callerid);
07673    ast_free(dpr);
07674    return NULL;
07675 }
07676 
07677 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07678 {
07679    pthread_t newthread;
07680    struct dpreq_data *dpr;
07681    
07682    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07683       return;
07684 
07685    dpr->callno = callno;
07686    ast_copy_string(dpr->context, context, sizeof(dpr->context));
07687    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07688    if (callerid)
07689       dpr->callerid = ast_strdup(callerid);
07690    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
07691       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07692    }
07693 }
07694 
07695 struct iax_dual {
07696    struct ast_channel *chan1;
07697    struct ast_channel *chan2;
07698 };
07699 
07700 static void *iax_park_thread(void *stuff)
07701 {
07702    struct ast_channel *chan1, *chan2;
07703    struct iax_dual *d;
07704    struct ast_frame *f;
07705    int ext;
07706    int res;
07707    d = stuff;
07708    chan1 = d->chan1;
07709    chan2 = d->chan2;
07710    ast_free(d);
07711    f = ast_read(chan1);
07712    if (f)
07713       ast_frfree(f);
07714    res = ast_park_call(chan1, chan2, 0, &ext);
07715    ast_hangup(chan2);
07716    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07717    return NULL;
07718 }
07719 
07720 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07721 {
07722    struct iax_dual *d;
07723    struct ast_channel *chan1m, *chan2m;
07724    pthread_t th;
07725    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07726    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07727    if (chan2m && chan1m) {
07728       /* Make formats okay */
07729       chan1m->readformat = chan1->readformat;
07730       chan1m->writeformat = chan1->writeformat;
07731       ast_channel_masquerade(chan1m, chan1);
07732       /* Setup the extensions and such */
07733       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
07734       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
07735       chan1m->priority = chan1->priority;
07736       
07737       /* We make a clone of the peer channel too, so we can play
07738          back the announcement */
07739       /* Make formats okay */
07740       chan2m->readformat = chan2->readformat;
07741       chan2m->writeformat = chan2->writeformat;
07742       ast_channel_masquerade(chan2m, chan2);
07743       /* Setup the extensions and such */
07744       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
07745       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
07746       chan2m->priority = chan2->priority;
07747       if (ast_do_masquerade(chan2m)) {
07748          ast_log(LOG_WARNING, "Masquerade failed :(\n");
07749          ast_hangup(chan2m);
07750          return -1;
07751       }
07752    } else {
07753       if (chan1m)
07754          ast_hangup(chan1m);
07755       if (chan2m)
07756          ast_hangup(chan2m);
07757       return -1;
07758    }
07759    if ((d = ast_calloc(1, sizeof(*d)))) {
07760       d->chan1 = chan1m;
07761       d->chan2 = chan2m;
07762       if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
07763          return 0;
07764       }
07765       ast_free(d);
07766    }
07767    return -1;
07768 }
07769 
07770 
07771 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
07772 
07773 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
07774 {
07775    unsigned int ourver;
07776    char rsi[80];
07777    snprintf(rsi, sizeof(rsi), "si-%s", si);
07778    if (iax_provision_version(&ourver, rsi, 1))
07779       return 0;
07780    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
07781    if (ourver != ver) 
07782       iax2_provision(sin, sockfd, NULL, rsi, 1);
07783    return 0;
07784 }
07785 
07786 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
07787 {
07788    jb_info stats;
07789    jb_getinfo(pvt->jb, &stats);
07790    
07791    memset(iep, 0, sizeof(*iep));
07792 
07793    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
07794    if(stats.frames_in == 0) stats.frames_in = 1;
07795    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
07796    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
07797    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
07798    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
07799    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07800 }
07801 
07802 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
07803 {
07804    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07805    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07806    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07807    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07808    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07809    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07810    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07811 }
07812 
07813 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies) 
07814 {
07815    int i;
07816    unsigned int length, offset = 0;
07817    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
07818 
07819    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
07820       length = ies->ospblocklength[i];
07821       if (length != 0) {
07822          if (length > IAX_MAX_OSPBLOCK_SIZE) {
07823             /* OSP token block length wrong, clear buffer */
07824             offset = 0;
07825             break;
07826          } else {
07827             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
07828             offset += length;
07829          }
07830       } else {
07831          break;
07832       }
07833    }
07834    *(full_osptoken + offset) = '\0';
07835    if (strlen(full_osptoken) != offset) {
07836       /* OSP token length wrong, clear buffer */
07837       *full_osptoken = '\0';
07838    }
07839 
07840    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
07841 }
07842 
07843 static void log_jitterstats(unsigned short callno)
07844 {
07845    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
07846    jb_info jbinfo;
07847 
07848    ast_mutex_lock(&iaxsl[callno]);
07849    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
07850       if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
07851          jb_getinfo(iaxs[callno]->jb, &jbinfo);
07852          localjitter = jbinfo.jitter;
07853          localdelay = jbinfo.current - jbinfo.min;
07854          locallost = jbinfo.frames_lost;
07855          locallosspct = jbinfo.losspct/1000;
07856          localdropped = jbinfo.frames_dropped;
07857          localooo = jbinfo.frames_ooo;
07858          localpackets = jbinfo.frames_in;
07859       }
07860       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",
07861          iaxs[callno]->owner->name,
07862          iaxs[callno]->pingtime,
07863          localjitter,
07864          localdelay,
07865          locallost,
07866          locallosspct,
07867          localdropped,
07868          localooo,
07869          localpackets,
07870          iaxs[callno]->remote_rr.jitter,
07871          iaxs[callno]->remote_rr.delay,
07872          iaxs[callno]->remote_rr.losscnt,
07873          iaxs[callno]->remote_rr.losspct/1000,
07874          iaxs[callno]->remote_rr.dropped,
07875          iaxs[callno]->remote_rr.ooo,
07876          iaxs[callno]->remote_rr.packets);
07877       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",
07878          iaxs[callno]->owner->name,
07879          iaxs[callno]->pingtime,
07880          localjitter,
07881          localdelay,
07882          locallost,
07883          locallosspct,
07884          localdropped,
07885          localooo,
07886          localpackets,
07887          iaxs[callno]->remote_rr.jitter,
07888          iaxs[callno]->remote_rr.delay,
07889          iaxs[callno]->remote_rr.losscnt,
07890          iaxs[callno]->remote_rr.losspct/1000,
07891          iaxs[callno]->remote_rr.dropped,
07892          iaxs[callno]->remote_rr.ooo,
07893          iaxs[callno]->remote_rr.packets);
07894    }
07895    ast_mutex_unlock(&iaxsl[callno]);
07896 }
07897 
07898 static int socket_process(struct iax2_thread *thread);
07899 
07900 /*!
07901  * \brief Handle any deferred full frames for this thread
07902  */
07903 static void handle_deferred_full_frames(struct iax2_thread *thread)
07904 {
07905    struct iax2_pkt_buf *pkt_buf;
07906 
07907    ast_mutex_lock(&thread->lock);
07908 
07909    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07910       ast_mutex_unlock(&thread->lock);
07911 
07912       thread->buf = pkt_buf->buf;
07913       thread->buf_len = pkt_buf->len;
07914       thread->buf_size = pkt_buf->len + 1;
07915       
07916       socket_process(thread);
07917 
07918       thread->buf = NULL;
07919       ast_free(pkt_buf);
07920 
07921       ast_mutex_lock(&thread->lock);
07922    }
07923 
07924    ast_mutex_unlock(&thread->lock);
07925 }
07926 
07927 /*!
07928  * \brief Queue the last read full frame for processing by a certain thread
07929  *
07930  * If there are already any full frames queued, they are sorted
07931  * by sequence number.
07932  */
07933 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07934 {
07935    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07936    struct ast_iax2_full_hdr *fh, *cur_fh;
07937 
07938    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07939       return;
07940 
07941    pkt_buf->len = from_here->buf_len;
07942    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07943 
07944    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07945    ast_mutex_lock(&to_here->lock);
07946    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07947       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07948       if (fh->oseqno < cur_fh->oseqno) {
07949          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
07950          break;
07951       }
07952    }
07953    AST_LIST_TRAVERSE_SAFE_END
07954 
07955    if (!cur_pkt_buf)
07956       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07957    
07958    ast_mutex_unlock(&to_here->lock);
07959 }
07960 
07961 static int socket_read(int *id, int fd, short events, void *cbdata)
07962 {
07963    struct iax2_thread *thread;
07964    socklen_t len;
07965    time_t t;
07966    static time_t last_errtime = 0;
07967    struct ast_iax2_full_hdr *fh;
07968 
07969    if (!(thread = find_idle_thread())) {
07970       time(&t);
07971       if (t != last_errtime)
07972          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
07973       last_errtime = t;
07974       usleep(1);
07975       return 1;
07976    }
07977 
07978    len = sizeof(thread->iosin);
07979    thread->iofd = fd;
07980    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07981    thread->buf_size = sizeof(thread->readbuf);
07982    thread->buf = thread->readbuf;
07983    if (thread->buf_len < 0) {
07984       if (errno != ECONNREFUSED && errno != EAGAIN)
07985          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07986       handle_error();
07987       thread->iostate = IAX_IOSTATE_IDLE;
07988       signal_condition(&thread->lock, &thread->cond);
07989       return 1;
07990    }
07991    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
07992       thread->iostate = IAX_IOSTATE_IDLE;
07993       signal_condition(&thread->lock, &thread->cond);
07994       return 1;
07995    }
07996    
07997    /* Determine if this frame is a full frame; if so, and any thread is currently
07998       processing a full frame for the same callno from this peer, then drop this
07999       frame (and the peer will retransmit it) */
08000    fh = (struct ast_iax2_full_hdr *) thread->buf;
08001    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08002       struct iax2_thread *cur = NULL;
08003       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08004       
08005       AST_LIST_LOCK(&active_list);
08006       AST_LIST_TRAVERSE(&active_list, cur, list) {
08007          if ((cur->ffinfo.callno == callno) &&
08008              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08009             break;
08010       }
08011       if (cur) {
08012          /* we found another thread processing a full frame for this call,
08013             so queue it up for processing later. */
08014          defer_full_frame(thread, cur);
08015          AST_LIST_UNLOCK(&active_list);
08016          thread->iostate = IAX_IOSTATE_IDLE;
08017          signal_condition(&thread->lock, &thread->cond);
08018          return 1;
08019       } else {
08020          /* this thread is going to process this frame, so mark it */
08021          thread->ffinfo.callno = callno;
08022          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08023          thread->ffinfo.type = fh->type;
08024          thread->ffinfo.csub = fh->csub;
08025       }
08026       AST_LIST_UNLOCK(&active_list);
08027    }
08028    
08029    /* Mark as ready and send on its way */
08030    thread->iostate = IAX_IOSTATE_READY;
08031 #ifdef DEBUG_SCHED_MULTITHREAD
08032    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08033 #endif
08034    signal_condition(&thread->lock, &thread->cond);
08035 
08036    return 1;
08037 }
08038 
08039 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
08040    struct iax_frame *fr)
08041 {
08042    unsigned char metatype;
08043    struct ast_iax2_meta_trunk_mini *mtm;
08044    struct ast_iax2_meta_trunk_hdr *mth;
08045    struct ast_iax2_meta_trunk_entry *mte;
08046    struct iax2_trunk_peer *tpeer;
08047    unsigned int ts;
08048    void *ptr;
08049    struct timeval rxtrunktime;
08050    struct ast_frame f = { 0, };
08051 
08052    if (packet_len < sizeof(*meta)) {
08053       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
08054          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08055       return 1;
08056    }
08057 
08058    if (meta->metacmd != IAX_META_TRUNK)
08059       return 1;
08060 
08061    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
08062       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
08063          (int) (sizeof(*meta) + sizeof(*mth)));
08064       return 1;
08065    }
08066    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08067    ts = ntohl(mth->ts);
08068    metatype = meta->cmddata;
08069    packet_len -= (sizeof(*meta) + sizeof(*mth));
08070    ptr = mth->data;
08071    tpeer = find_tpeer(sin, sockfd);
08072    if (!tpeer) {
08073       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
08074          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08075       return 1;
08076    }
08077    tpeer->trunkact = ast_tvnow();
08078    if (!ts || ast_tvzero(tpeer->rxtrunktime))
08079       tpeer->rxtrunktime = tpeer->trunkact;
08080    rxtrunktime = tpeer->rxtrunktime;
08081    ast_mutex_unlock(&tpeer->lock);
08082    while (packet_len >= sizeof(*mte)) {
08083       /* Process channels */
08084       unsigned short callno, trunked_ts, len;
08085 
08086       if (metatype == IAX_META_TRUNK_MINI) {
08087          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
08088          ptr += sizeof(*mtm);
08089          packet_len -= sizeof(*mtm);
08090          len = ntohs(mtm->len);
08091          callno = ntohs(mtm->mini.callno);
08092          trunked_ts = ntohs(mtm->mini.ts);
08093       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08094          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08095          ptr += sizeof(*mte);
08096          packet_len -= sizeof(*mte);
08097          len = ntohs(mte->len);
08098          callno = ntohs(mte->callno);
08099          trunked_ts = 0;
08100       } else {
08101          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08102          break;
08103       }
08104       /* Stop if we don't have enough data */
08105       if (len > packet_len)
08106          break;
08107       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
08108       if (!fr->callno)
08109          continue;
08110 
08111       /* If it's a valid call, deliver the contents.  If not, we
08112          drop it, since we don't have a scallno to use for an INVAL */
08113       /* Process as a mini frame */
08114       memset(&f, 0, sizeof(f));
08115       f.frametype = AST_FRAME_VOICE;
08116       if (!iaxs[fr->callno]) {
08117          /* drop it */
08118       } else if (iaxs[fr->callno]->voiceformat == 0) {
08119          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08120          iax2_vnak(fr->callno);
08121       } else {
08122          f.subclass = iaxs[fr->callno]->voiceformat;
08123          f.datalen = len;
08124          if (f.datalen >= 0) {
08125             if (f.datalen)
08126                f.data = ptr;
08127             else
08128                f.data = NULL;
08129             if (trunked_ts)
08130                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08131             else
08132                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08133             /* Don't pass any packets until we're started */
08134             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08135                struct iax_frame *duped_fr;
08136 
08137                /* Common things */
08138                f.src = "IAX2";
08139                f.mallocd = 0;
08140                f.offset = 0;
08141                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
08142                   f.samples = ast_codec_get_samples(&f);
08143                else
08144                   f.samples = 0;
08145                fr->outoforder = 0;
08146                iax_frame_wrap(fr, &f);
08147                duped_fr = iaxfrdup2(fr);
08148                if (duped_fr)
08149                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
08150                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
08151                   iaxs[fr->callno]->last = fr->ts;
08152             }
08153          } else {
08154             ast_log(LOG_WARNING, "Datalen < 0?\n");
08155          }
08156       }
08157       ast_mutex_unlock(&iaxsl[fr->callno]);
08158       ptr += len;
08159       packet_len -= len;
08160    }
08161 
08162    return 1;
08163 }
08164 
08165 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
08166 {
08167    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08168    AST_LIST_HEAD(, ast_var_t) *varlist;
08169    struct ast_var_t *var;
08170 
08171    if (!variablestore) {
08172       *buf = '\0';
08173       return 0;
08174    }
08175    varlist = variablestore->data;
08176 
08177    AST_LIST_LOCK(varlist);
08178    AST_LIST_TRAVERSE(varlist, var, entries) {
08179       if (strcmp(var->name, data) == 0) {
08180          ast_copy_string(buf, var->value, len);
08181          break;
08182       }
08183    }
08184    AST_LIST_UNLOCK(varlist);
08185    return 0;
08186 }
08187 
08188 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
08189 {
08190    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08191    AST_LIST_HEAD(, ast_var_t) *varlist;
08192    struct ast_var_t *var;
08193 
08194    if (!variablestore) {
08195       variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
08196       if (!variablestore) {
08197          ast_log(LOG_ERROR, "Memory allocation error\n");
08198          return -1;
08199       }
08200       varlist = ast_calloc(1, sizeof(*varlist));
08201       if (!varlist) {
08202          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08203          return -1;
08204       }
08205 
08206       AST_LIST_HEAD_INIT(varlist);
08207       variablestore->data = varlist;
08208       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08209       ast_channel_datastore_add(chan, variablestore);
08210    } else
08211       varlist = variablestore->data;
08212 
08213    AST_LIST_LOCK(varlist);
08214    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
08215       if (strcmp(var->name, data) == 0) {
08216          AST_LIST_REMOVE_CURRENT(entries);
08217          ast_var_delete(var);
08218          break;
08219       }
08220    }
08221    AST_LIST_TRAVERSE_SAFE_END;
08222    var = ast_var_assign(data, value);
08223    if (var)
08224       AST_LIST_INSERT_TAIL(varlist, var, entries);
08225    else
08226       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08227    AST_LIST_UNLOCK(varlist);
08228    return 0;
08229 }
08230 
08231 static struct ast_custom_function iaxvar_function = {
08232    .name = "IAXVAR",
08233    .synopsis = "Sets or retrieves a remote variable",
08234    .syntax = "IAXVAR(<varname>)",
08235    .read = acf_iaxvar_read,
08236    .write = acf_iaxvar_write,
08237 };
08238 
08239 static int socket_process(struct iax2_thread *thread)
08240 {
08241    struct sockaddr_in sin;
08242    int res;
08243    int updatehistory=1;
08244    int new = NEW_PREVENT;
08245    int dcallno = 0;
08246    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08247    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08248    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08249    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08250    struct iax_frame *fr;
08251    struct iax_frame *cur;
08252    struct ast_frame f = { 0, };
08253    struct ast_channel *c = NULL;
08254    struct iax2_dpcache *dp;
08255    struct iax2_peer *peer;
08256    struct iax_ies ies;
08257    struct iax_ie_data ied0, ied1;
08258    int format;
08259    int fd;
08260    int exists;
08261    int minivid = 0;
08262    char empty[32]="";      /* Safety measure */
08263    struct iax_frame *duped_fr;
08264    char host_pref_buf[128];
08265    char caller_pref_buf[128];
08266    struct ast_codec_pref pref;
08267    char *using_prefs = "mine";
08268 
08269    /* allocate an iax_frame with 4096 bytes of data buffer */
08270    fr = alloca(sizeof(*fr) + 4096);
08271    memset(fr, 0, sizeof(*fr));
08272    fr->afdatalen = 4096; /* From alloca() above */
08273 
08274    /* Copy frequently used parameters to the stack */
08275    res = thread->buf_len;
08276    fd = thread->iofd;
08277    memcpy(&sin, &thread->iosin, sizeof(sin));
08278 
08279    if (res < sizeof(*mh)) {
08280       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
08281       return 1;
08282    }
08283    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08284       if (res < sizeof(*vh)) {
08285          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));
08286          return 1;
08287       }
08288 
08289       /* This is a video frame, get call number */
08290       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08291       minivid = 1;
08292    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
08293       return socket_process_meta(res, meta, &sin, fd, fr);
08294 
08295 #ifdef DEBUG_SUPPORT
08296    if (iaxdebug && (res >= sizeof(*fh)))
08297       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08298 #endif
08299    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08300       if (res < sizeof(*fh)) {
08301          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));
08302          return 1;
08303       }
08304 
08305       /* Get the destination call number */
08306       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08307       /* Retrieve the type and subclass */
08308       f.frametype = fh->type;
08309       if (f.frametype == AST_FRAME_VIDEO) {
08310          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08311       } else {
08312          f.subclass = uncompress_subclass(fh->csub);
08313       }
08314 
08315       /* Deal with POKE/PONG without allocating a callno */
08316       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08317          /* Reply back with a PONG, but don't care about the result. */
08318          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1);
08319          return 1;
08320       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08321          /* Ignore */
08322          return 1;
08323       }
08324 
08325       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
08326                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
08327                          (f.subclass == IAX_COMMAND_REGREL)))
08328          new = NEW_ALLOW;
08329    } else {
08330       /* Don't know anything about it yet */
08331       f.frametype = AST_FRAME_NULL;
08332       f.subclass = 0;
08333    }
08334 
08335    if (!fr->callno) {
08336       int check_dcallno = 0;
08337 
08338       /*
08339        * We enforce accurate destination call numbers for all full frames except
08340        * LAGRQ and PING commands.  This is because older versions of Asterisk
08341        * schedule these commands to get sent very quickly, and they will sometimes
08342        * be sent before they receive the first frame from the other side.  When
08343        * that happens, it doesn't contain the destination call number.  However,
08344        * not checking it for these frames is safe.
08345        * 
08346        * Discussed in the following thread:
08347        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
08348        */
08349 
08350       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08351          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08352       }
08353 
08354       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
08355    }
08356 
08357    if (fr->callno > 0)
08358       ast_mutex_lock(&iaxsl[fr->callno]);
08359 
08360    if (!fr->callno || !iaxs[fr->callno]) {
08361       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
08362          frame, reply with an inval */
08363       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08364          /* We can only raw hangup control frames */
08365          if (((f.subclass != IAX_COMMAND_INVAL) &&
08366              (f.subclass != IAX_COMMAND_TXCNT) &&
08367              (f.subclass != IAX_COMMAND_TXACC) &&
08368              (f.subclass != IAX_COMMAND_FWDOWNL))||
08369              (f.frametype != AST_FRAME_IAX))
08370             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08371             fd);
08372       }
08373       if (fr->callno > 0) 
08374          ast_mutex_unlock(&iaxsl[fr->callno]);
08375       return 1;
08376    }
08377    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08378       if (decrypt_frame(fr->callno, fh, &f, &res)) {
08379          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08380          ast_mutex_unlock(&iaxsl[fr->callno]);
08381          return 1;
08382       }
08383 #ifdef DEBUG_SUPPORT
08384       else if (iaxdebug)
08385          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08386 #endif
08387    }
08388 
08389    /* count this frame */
08390    iaxs[fr->callno]->frames_received++;
08391 
08392    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08393       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
08394       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
08395       unsigned short new_peercallno;
08396       
08397       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08398       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08399          if (iaxs[fr->callno]->peercallno) {
08400             remove_by_peercallno(iaxs[fr->callno]);
08401          }
08402          iaxs[fr->callno]->peercallno = new_peercallno;
08403          store_by_peercallno(iaxs[fr->callno]);
08404       }
08405    }
08406    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08407       if (iaxdebug)
08408          ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08409       /* Check if it's out of order (and not an ACK or INVAL) */
08410       fr->oseqno = fh->oseqno;
08411       fr->iseqno = fh->iseqno;
08412       fr->ts = ntohl(fh->ts);
08413 #ifdef IAXTESTS
08414       if (test_resync) {
08415          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08416          fr->ts += test_resync;
08417       }
08418 #endif /* IAXTESTS */
08419 #if 0
08420       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08421            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08422                         (f.subclass == IAX_COMMAND_NEW ||
08423                          f.subclass == IAX_COMMAND_AUTHREQ ||
08424                          f.subclass == IAX_COMMAND_ACCEPT ||
08425                          f.subclass == IAX_COMMAND_REJECT))      ) )
08426 #endif
08427       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08428          updatehistory = 0;
08429       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08430          (iaxs[fr->callno]->iseqno ||
08431             ((f.subclass != IAX_COMMAND_TXCNT) &&
08432             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
08433             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
08434             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
08435             (f.subclass != IAX_COMMAND_TXACC)) ||
08436             (f.frametype != AST_FRAME_IAX))) {
08437          if (
08438           ((f.subclass != IAX_COMMAND_ACK) &&
08439            (f.subclass != IAX_COMMAND_INVAL) &&
08440            (f.subclass != IAX_COMMAND_TXCNT) &&
08441            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
08442            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
08443            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
08444            (f.subclass != IAX_COMMAND_TXACC) &&
08445            (f.subclass != IAX_COMMAND_VNAK)) ||
08446            (f.frametype != AST_FRAME_IAX)) {
08447             /* If it's not an ACK packet, it's out of order. */
08448             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
08449                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08450             /* Check to see if we need to request retransmission,
08451              * and take sequence number wraparound into account */
08452             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08453                /* If we've already seen it, ack it XXX There's a border condition here XXX */
08454                if ((f.frametype != AST_FRAME_IAX) || 
08455                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08456                   ast_debug(1, "Acking anyway\n");
08457                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
08458                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
08459                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08460                }
08461             } else {
08462                /* Send a VNAK requesting retransmission */
08463                iax2_vnak(fr->callno);
08464             }
08465             ast_mutex_unlock(&iaxsl[fr->callno]);
08466             return 1;
08467          }
08468       } else {
08469          /* Increment unless it's an ACK or VNAK */
08470          if (((f.subclass != IAX_COMMAND_ACK) &&
08471              (f.subclass != IAX_COMMAND_INVAL) &&
08472              (f.subclass != IAX_COMMAND_TXCNT) &&
08473              (f.subclass != IAX_COMMAND_TXACC) &&
08474             (f.subclass != IAX_COMMAND_VNAK)) ||
08475              (f.frametype != AST_FRAME_IAX))
08476             iaxs[fr->callno]->iseqno++;
08477       }
08478       /* A full frame */
08479       if (res < sizeof(*fh)) {
08480          ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*fh));
08481          ast_mutex_unlock(&iaxsl[fr->callno]);
08482          return 1;
08483       }
08484       /* Ensure text frames are NULL-terminated */
08485       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08486          if (res < thread->buf_size)
08487             thread->buf[res++] = '\0';
08488          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
08489             thread->buf[res - 1] = '\0';
08490       }
08491       f.datalen = res - sizeof(*fh);
08492 
08493       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
08494          from the real peer, not the transfer peer */
08495       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08496           ((f.subclass != IAX_COMMAND_INVAL) ||
08497            (f.frametype != AST_FRAME_IAX))) {
08498          unsigned char x;
08499          int call_to_destroy;
08500          /* XXX This code is not very efficient.  Surely there is a better way which still
08501                 properly handles boundary conditions? XXX */
08502          /* First we have to qualify that the ACKed value is within our window */
08503          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
08504             if (fr->iseqno == x)
08505                break;
08506          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08507             /* The acknowledgement is within our window.  Time to acknowledge everything
08508                that it says to */
08509             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08510                /* Ack the packet with the given timestamp */
08511                if (iaxdebug)
08512                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
08513                call_to_destroy = 0;
08514                AST_LIST_LOCK(&frame_queue);
08515                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08516                   /* If it's our call, and our timestamp, mark -1 retries */
08517                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08518                      cur->retries = -1;
08519                      /* Destroy call if this is the end */
08520                      if (cur->final)
08521                         call_to_destroy = fr->callno;
08522                   }
08523                }
08524                AST_LIST_UNLOCK(&frame_queue);
08525                if (call_to_destroy) {
08526                   if (iaxdebug)
08527                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08528                   ast_mutex_lock(&iaxsl[call_to_destroy]);
08529                   iax2_destroy(call_to_destroy);
08530                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
08531                }
08532             }
08533             /* Note how much we've received acknowledgement for */
08534             if (iaxs[fr->callno])
08535                iaxs[fr->callno]->rseqno = fr->iseqno;
08536             else {
08537                /* Stop processing now */
08538                ast_mutex_unlock(&iaxsl[fr->callno]);
08539                return 1;
08540             }
08541          } else {
08542             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08543          }
08544       }
08545       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08546          ((f.frametype != AST_FRAME_IAX) || 
08547           ((f.subclass != IAX_COMMAND_TXACC) &&
08548            (f.subclass != IAX_COMMAND_TXCNT)))) {
08549          /* Only messages we accept from a transfer host are TXACC and TXCNT */
08550          ast_mutex_unlock(&iaxsl[fr->callno]);
08551          return 1;
08552       }
08553 
08554       if (f.datalen) {
08555          if (f.frametype == AST_FRAME_IAX) {
08556             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08557                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08558                ast_mutex_unlock(&iaxsl[fr->callno]);
08559                return 1;
08560             }
08561             f.data = NULL;
08562             f.datalen = 0;
08563          } else {
08564             f.data = thread->buf + sizeof(*fh);
08565             memset(&ies, 0, sizeof(ies));
08566          }
08567       } else {
08568          if (f.frametype == AST_FRAME_IAX)
08569             f.data = NULL;
08570          else
08571             f.data = empty;
08572          memset(&ies, 0, sizeof(ies));
08573       }
08574 
08575       /* when we receive the first full frame for a new incoming channel,
08576          it is safe to start the PBX on the channel because we have now
08577          completed a 3-way handshake with the peer */
08578       if ((f.frametype == AST_FRAME_VOICE) ||
08579           (f.frametype == AST_FRAME_VIDEO) ||
08580           (f.frametype == AST_FRAME_IAX)) {
08581          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08582             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08583             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08584                ast_mutex_unlock(&iaxsl[fr->callno]);
08585                return 1;
08586             }
08587          }
08588 
08589          if (ies.vars) {
08590             struct ast_datastore *variablestore;
08591             struct ast_variable *var, *prev = NULL;
08592             AST_LIST_HEAD(, ast_var_t) *varlist;
08593             if ((c = iaxs[fr->callno]->owner)) {
08594                varlist = ast_calloc(1, sizeof(*varlist));
08595                variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
08596                if (variablestore && varlist) {
08597                   variablestore->data = varlist;
08598                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08599                   AST_LIST_HEAD_INIT(varlist);
08600                   ast_debug(1, "I can haz IAX vars?\n");
08601                   for (var = ies.vars; var; var = var->next) {
08602                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08603                      if (prev) {
08604                         ast_free(prev);
08605                      }
08606                      prev = var;
08607                      if (!newvar) {
08608                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
08609                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08610                      } else {
08611                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08612                      }
08613                   }
08614                   if (prev) {
08615                      ast_free(prev);
08616                   }
08617                   ies.vars = NULL;
08618                   ast_channel_datastore_add(c, variablestore);
08619                } else {
08620                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08621                   if (variablestore) {
08622                      ast_channel_datastore_free(variablestore);
08623                   }
08624                   if (varlist) {
08625                      ast_free(varlist);
08626                   }
08627                }
08628             } else {
08629                /* No channel yet, so transfer the variables directly over to the pvt,
08630                 * for later inheritance. */
08631                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
08632                for (var = ies.vars; var && var->next; var = var->next);
08633                if (var) {
08634                   var->next = iaxs[fr->callno]->iaxvars;
08635                   iaxs[fr->callno]->iaxvars = ies.vars;
08636                   ies.vars = NULL;
08637                }
08638             }
08639          }
08640       }
08641 
08642       if (ies.vars) {
08643          ast_debug(1, "I have IAX variables, but they were not processed\n");
08644       }
08645 
08646       if (f.frametype == AST_FRAME_VOICE) {
08647          if (f.subclass != iaxs[fr->callno]->voiceformat) {
08648                iaxs[fr->callno]->voiceformat = f.subclass;
08649                ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
08650                if (iaxs[fr->callno]->owner) {
08651                   int orignative;
08652 retryowner:
08653                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
08654                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08655                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08656                   }
08657                   if (iaxs[fr->callno]) {
08658                      if (iaxs[fr->callno]->owner) {
08659                         orignative = iaxs[fr->callno]->owner->nativeformats;
08660                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
08661                         if (iaxs[fr->callno]->owner->readformat)
08662                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08663                         iaxs[fr->callno]->owner->nativeformats = orignative;
08664                         ast_channel_unlock(iaxs[fr->callno]->owner);
08665                      }
08666                   } else {
08667                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
08668                      /* Free remote variables (if any) */
08669                      if (ies.vars) {
08670                         ast_variables_destroy(ies.vars);
08671                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
08672                         ies.vars = NULL;
08673                      }
08674                      ast_mutex_unlock(&iaxsl[fr->callno]);
08675                      return 1;
08676                   }
08677                }
08678          }
08679       }
08680       if (f.frametype == AST_FRAME_VIDEO) {
08681          if (f.subclass != iaxs[fr->callno]->videoformat) {
08682             ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08683             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08684          }
08685       }
08686       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08687          if (f.subclass == AST_CONTROL_BUSY) {
08688             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08689          } else if (f.subclass == AST_CONTROL_CONGESTION) {
08690             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08691          }
08692       }
08693       if (f.frametype == AST_FRAME_IAX) {
08694          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08695          /* Handle the IAX pseudo frame itself */
08696          if (iaxdebug)
08697             ast_debug(1, "IAX subclass %d received\n", f.subclass);
08698 
08699                         /* Update last ts unless the frame's timestamp originated with us. */
08700          if (iaxs[fr->callno]->last < fr->ts &&
08701                             f.subclass != IAX_COMMAND_ACK &&
08702                             f.subclass != IAX_COMMAND_PONG &&
08703                             f.subclass != IAX_COMMAND_LAGRP) {
08704             iaxs[fr->callno]->last = fr->ts;
08705             if (iaxdebug)
08706                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08707          }
08708          iaxs[fr->callno]->last_iax_message = f.subclass;
08709          if (!iaxs[fr->callno]->first_iax_message) {
08710             iaxs[fr->callno]->first_iax_message = f.subclass;
08711          }
08712          switch(f.subclass) {
08713          case IAX_COMMAND_ACK:
08714             /* Do nothing */
08715             break;
08716          case IAX_COMMAND_QUELCH:
08717             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08718                     /* Generate Manager Hold event, if necessary*/
08719                if (iaxs[fr->callno]->owner) {
08720                   manager_event(EVENT_FLAG_CALL, "Hold",
08721                      "Status: On\r\n"
08722                      "Channel: %s\r\n"
08723                      "Uniqueid: %s\r\n",
08724                      iaxs[fr->callno]->owner->name, 
08725                      iaxs[fr->callno]->owner->uniqueid);
08726                }
08727 
08728                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08729                if (ies.musiconhold) {
08730                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08731                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
08732                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
08733                         S_OR(mohsuggest, NULL),
08734                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
08735                      if (!iaxs[fr->callno]) {
08736                         ast_mutex_unlock(&iaxsl[fr->callno]);
08737                         return 1;
08738                      }
08739                   }
08740                }
08741             }
08742             break;
08743          case IAX_COMMAND_UNQUELCH:
08744             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08745                     /* Generate Manager Unhold event, if necessary*/
08746                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08747                   manager_event(EVENT_FLAG_CALL, "Hold",
08748                      "Status: Off\r\n"
08749                      "Channel: %s\r\n"
08750                      "Uniqueid: %s\r\n",
08751                      iaxs[fr->callno]->owner->name, 
08752                      iaxs[fr->callno]->owner->uniqueid);
08753                }
08754 
08755                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08756                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08757                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08758                   if (!iaxs[fr->callno]) {
08759                      ast_mutex_unlock(&iaxsl[fr->callno]);
08760                      return 1;
08761                   }
08762                }
08763             }
08764             break;
08765          case IAX_COMMAND_TXACC:
08766             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08767                /* Ack the packet with the given timestamp */
08768                AST_LIST_LOCK(&frame_queue);
08769                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08770                   /* Cancel any outstanding txcnt's */
08771                   if ((fr->callno == cur->callno) && (cur->transfer))
08772                      cur->retries = -1;
08773                }
08774                AST_LIST_UNLOCK(&frame_queue);
08775                memset(&ied1, 0, sizeof(ied1));
08776                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08777                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08778                iaxs[fr->callno]->transferring = TRANSFER_READY;
08779             }
08780             break;
08781          case IAX_COMMAND_NEW:
08782             /* Ignore if it's already up */
08783             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08784                break;
08785             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08786                ast_mutex_unlock(&iaxsl[fr->callno]);
08787                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08788                ast_mutex_lock(&iaxsl[fr->callno]);
08789                if (!iaxs[fr->callno]) {
08790                   ast_mutex_unlock(&iaxsl[fr->callno]);
08791                   return 1;
08792                }
08793             }
08794             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
08795             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08796                int new_callno;
08797                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08798                   fr->callno = new_callno;
08799             }
08800             /* For security, always ack immediately */
08801             if (delayreject)
08802                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08803             if (check_access(fr->callno, &sin, &ies)) {
08804                /* They're not allowed on */
08805                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08806                if (authdebug)
08807                   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);
08808                break;
08809             }
08810             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08811                const char *context, *exten, *cid_num;
08812 
08813                context = ast_strdupa(iaxs[fr->callno]->context);
08814                exten = ast_strdupa(iaxs[fr->callno]->exten);
08815                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08816 
08817                /* This might re-enter the IAX code and need the lock */
08818                ast_mutex_unlock(&iaxsl[fr->callno]);
08819                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08820                ast_mutex_lock(&iaxsl[fr->callno]);
08821 
08822                if (!iaxs[fr->callno]) {
08823                   ast_mutex_unlock(&iaxsl[fr->callno]);
08824                   return 1;
08825                }
08826             } else
08827                exists = 0;
08828             /* Get OSP token if it does exist */
08829             save_osptoken(fr, &ies);
08830             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08831                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08832                   memset(&ied0, 0, sizeof(ied0));
08833                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08834                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08835                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08836                   if (!iaxs[fr->callno]) {
08837                      ast_mutex_unlock(&iaxsl[fr->callno]);
08838                      return 1;
08839                   }
08840                   if (authdebug)
08841                      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);
08842                } else {
08843                   /* Select an appropriate format */
08844 
08845                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08846                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08847                         using_prefs = "reqonly";
08848                      } else {
08849                         using_prefs = "disabled";
08850                      }
08851                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08852                      memset(&pref, 0, sizeof(pref));
08853                      strcpy(caller_pref_buf, "disabled");
08854                      strcpy(host_pref_buf, "disabled");
08855                   } else {
08856                      using_prefs = "mine";
08857                      /* If the information elements are in here... use them */
08858                      if (ies.codec_prefs)
08859                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08860                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08861                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
08862                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08863                            pref = iaxs[fr->callno]->rprefs;
08864                            using_prefs = "caller";
08865                         } else {
08866                            pref = iaxs[fr->callno]->prefs;
08867                         }
08868                      } else
08869                         pref = iaxs[fr->callno]->prefs;
08870                      
08871                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08872                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08873                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08874                   }
08875                   if (!format) {
08876                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08877                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08878                      if (!format) {
08879                         memset(&ied0, 0, sizeof(ied0));
08880                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08881                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08882                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08883                         if (!iaxs[fr->callno]) {
08884                            ast_mutex_unlock(&iaxsl[fr->callno]);
08885                            return 1;
08886                         }
08887                         if (authdebug) {
08888                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08889                               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);
08890                            else 
08891                               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);
08892                         }
08893                      } else {
08894                         /* Pick one... */
08895                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08896                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08897                               format = 0;
08898                         } else {
08899                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08900                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08901                               memset(&pref, 0, sizeof(pref));
08902                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08903                               strcpy(caller_pref_buf,"disabled");
08904                               strcpy(host_pref_buf,"disabled");
08905                            } else {
08906                               using_prefs = "mine";
08907                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08908                                  /* Do the opposite of what we tried above. */
08909                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08910                                     pref = iaxs[fr->callno]->prefs;                       
08911                                  } else {
08912                                     pref = iaxs[fr->callno]->rprefs;
08913                                     using_prefs = "caller";
08914                                  }
08915                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08916                            
08917                               } else /* if no codec_prefs IE do it the old way */
08918                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08919                            }
08920                         }
08921 
08922                         if (!format) {
08923                            memset(&ied0, 0, sizeof(ied0));
08924                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08925                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08926                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08927                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08928                            if (!iaxs[fr->callno]) {
08929                               ast_mutex_unlock(&iaxsl[fr->callno]);
08930                               return 1;
08931                            }
08932                            if (authdebug)
08933                               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);
08934                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
08935                            break;
08936                         }
08937                      }
08938                   }
08939                   if (format) {
08940                      /* No authentication required, let them in */
08941                      memset(&ied1, 0, sizeof(ied1));
08942                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08943                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08944                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08945                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08946                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
08947                                     "%srequested format = %s,\n"
08948                                     "%srequested prefs = %s,\n"
08949                                     "%sactual format = %s,\n"
08950                                     "%shost prefs = %s,\n"
08951                                     "%spriority = %s\n",
08952                                     ast_inet_ntoa(sin.sin_addr), 
08953                                     VERBOSE_PREFIX_4,
08954                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
08955                                     VERBOSE_PREFIX_4,
08956                                     caller_pref_buf,
08957                                     VERBOSE_PREFIX_4,
08958                                     ast_getformatname(format), 
08959                                     VERBOSE_PREFIX_4,
08960                                     host_pref_buf, 
08961                                     VERBOSE_PREFIX_4,
08962                                     using_prefs);
08963                         
08964                         iaxs[fr->callno]->chosenformat = format;
08965                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08966                      } else {
08967                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08968                         /* If this is a TBD call, we're ready but now what...  */
08969                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08970                      }
08971                   }
08972                }
08973                break;
08974             }
08975             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
08976                merge_encryption(iaxs[fr->callno],ies.encmethods);
08977             else
08978                iaxs[fr->callno]->encmethods = 0;
08979             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
08980                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
08981             if (!iaxs[fr->callno]) {
08982                ast_mutex_unlock(&iaxsl[fr->callno]);
08983                return 1;
08984             }
08985             break;
08986          case IAX_COMMAND_DPREQ:
08987             /* Request status in the dialplan */
08988             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
08989                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
08990                if (iaxcompat) {
08991                   /* Spawn a thread for the lookup */
08992                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
08993                } else {
08994                   /* Just look it up */
08995                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
08996                }
08997             }
08998             break;
08999          case IAX_COMMAND_HANGUP:
09000             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09001             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
09002             /* Set hangup cause according to remote */
09003             if (ies.causecode && iaxs[fr->callno]->owner)
09004                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09005             /* Send ack immediately, before we destroy */
09006             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09007             iax2_destroy(fr->callno);
09008             break;
09009          case IAX_COMMAND_REJECT:
09010             /* Set hangup cause according to remote */
09011             if (ies.causecode && iaxs[fr->callno]->owner)
09012                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09013 
09014             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09015                if (iaxs[fr->callno]->owner && authdebug)
09016                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09017                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09018                      ies.cause ? ies.cause : "<Unknown>");
09019                ast_debug(1, "Immediately destroying %d, having received reject\n",
09020                   fr->callno);
09021             }
09022             /* Send ack immediately, before we destroy */
09023             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09024                          fr->ts, NULL, 0, fr->iseqno);
09025             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09026                iaxs[fr->callno]->error = EPERM;
09027             iax2_destroy(fr->callno);
09028             break;
09029          case IAX_COMMAND_TRANSFER:
09030          {
09031             struct ast_channel *bridged_chan;
09032 
09033             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09034                /* Set BLINDTRANSFER channel variables */
09035 
09036                ast_mutex_unlock(&iaxsl[fr->callno]);
09037                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09038                ast_mutex_lock(&iaxsl[fr->callno]);
09039                if (!iaxs[fr->callno]) {
09040                   ast_mutex_unlock(&iaxsl[fr->callno]);
09041                   return 1;
09042                }
09043 
09044                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09045                if (!strcmp(ies.called_number, ast_parking_ext())) {
09046                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09047                   ast_mutex_unlock(&iaxsl[fr->callno]);
09048                   if (iax_park(bridged_chan, saved_channel)) {
09049                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09050                   } else {
09051                      ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
09052                   }
09053                   ast_mutex_lock(&iaxsl[fr->callno]);
09054                } else {
09055                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09056                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
09057                         ies.called_number, iaxs[fr->callno]->context);
09058                   else {
09059                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
09060                         ies.called_number, iaxs[fr->callno]->context);
09061                   }
09062                }
09063             } else {
09064                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
09065             }
09066 
09067             break;
09068          }
09069          case IAX_COMMAND_ACCEPT:
09070             /* Ignore if call is already up or needs authentication or is a TBD */
09071             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09072                break;
09073             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09074                /* Send ack immediately, before we destroy */
09075                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09076                iax2_destroy(fr->callno);
09077                break;
09078             }
09079             if (ies.format) {
09080                iaxs[fr->callno]->peerformat = ies.format;
09081             } else {
09082                if (iaxs[fr->callno]->owner)
09083                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09084                else
09085                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09086             }
09087             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));
09088             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09089                memset(&ied0, 0, sizeof(ied0));
09090                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09091                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09092                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09093                if (!iaxs[fr->callno]) {
09094                   ast_mutex_unlock(&iaxsl[fr->callno]);
09095                   return 1;
09096                }
09097                if (authdebug)
09098                   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);
09099             } else {
09100                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09101                if (iaxs[fr->callno]->owner) {
09102                   /* Switch us to use a compatible format */
09103                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09104                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09105 retryowner2:
09106                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09107                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09108                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09109                   }
09110                   
09111                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09112                      /* Setup read/write formats properly. */
09113                      if (iaxs[fr->callno]->owner->writeformat)
09114                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
09115                      if (iaxs[fr->callno]->owner->readformat)
09116                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
09117                      ast_channel_unlock(iaxs[fr->callno]->owner);
09118                   }
09119                }
09120             }
09121             if (iaxs[fr->callno]) {
09122                AST_LIST_LOCK(&dpcache);
09123                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
09124                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
09125                      iax2_dprequest(dp, fr->callno);
09126                AST_LIST_UNLOCK(&dpcache);
09127             }
09128             break;
09129          case IAX_COMMAND_POKE:
09130             /* Send back a pong packet with the original timestamp */
09131             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09132             if (!iaxs[fr->callno]) {
09133                ast_mutex_unlock(&iaxsl[fr->callno]);
09134                return 1;
09135             }
09136             break;
09137          case IAX_COMMAND_PING:
09138          {
09139             struct iax_ie_data pingied;
09140             construct_rr(iaxs[fr->callno], &pingied);
09141             /* Send back a pong packet with the original timestamp */
09142             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09143          }
09144             break;
09145          case IAX_COMMAND_PONG:
09146             /* Calculate ping time */
09147             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09148             /* save RR info */
09149             save_rr(fr, &ies);
09150 
09151             /* Good time to write jb stats for this call */
09152             log_jitterstats(fr->callno);
09153 
09154             if (iaxs[fr->callno]->peerpoke) {
09155                peer = iaxs[fr->callno]->peerpoke;
09156                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
09157                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09158                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09159                      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); 
09160                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09161                   }
09162                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09163                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
09164                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09165                      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); 
09166                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09167                   }
09168                }
09169                peer->lastms = iaxs[fr->callno]->pingtime;
09170                if (peer->smoothing && (peer->lastms > -1))
09171                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09172                else if (peer->smoothing && peer->lastms < 0)
09173                   peer->historicms = (0 + peer->historicms) / 2;
09174                else              
09175                   peer->historicms = iaxs[fr->callno]->pingtime;
09176 
09177                /* Remove scheduled iax2_poke_noanswer */
09178                if (peer->pokeexpire > -1) {
09179                   if (!ast_sched_del(sched, peer->pokeexpire)) {
09180                      peer_unref(peer);
09181                      peer->pokeexpire = -1;
09182                   }
09183                }
09184                /* Schedule the next cycle */
09185                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
09186                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09187                else
09188                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09189                if (peer->pokeexpire == -1)
09190                   peer_unref(peer);
09191                /* and finally send the ack */
09192                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09193                /* And wrap up the qualify call */
09194                iax2_destroy(fr->callno);
09195                peer->callno = 0;
09196                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09197             }
09198             break;
09199          case IAX_COMMAND_LAGRQ:
09200          case IAX_COMMAND_LAGRP:
09201             f.src = "LAGRQ";
09202             f.mallocd = 0;
09203             f.offset = 0;
09204             f.samples = 0;
09205             iax_frame_wrap(fr, &f);
09206             if(f.subclass == IAX_COMMAND_LAGRQ) {
09207                /* Received a LAGRQ - echo back a LAGRP */
09208                fr->af.subclass = IAX_COMMAND_LAGRP;
09209                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09210             } else {
09211                /* Received LAGRP in response to our LAGRQ */
09212                unsigned int ts;
09213                /* This is a reply we've been given, actually measure the difference */
09214                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09215                iaxs[fr->callno]->lag = ts - fr->ts;
09216                if (iaxdebug)
09217                   ast_debug(1, "Peer %s lag measured as %dms\n",
09218                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09219             }
09220             break;
09221          case IAX_COMMAND_AUTHREQ:
09222             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09223                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>");
09224                break;
09225             }
09226             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09227                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09228                         .subclass = AST_CONTROL_HANGUP,
09229                };
09230                ast_log(LOG_WARNING, 
09231                   "I don't know how to authenticate %s to %s\n", 
09232                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09233                iax2_queue_frame(fr->callno, &hangup_fr);
09234             }
09235             if (!iaxs[fr->callno]) {
09236                ast_mutex_unlock(&iaxsl[fr->callno]);
09237                return 1;
09238             }
09239             break;
09240          case IAX_COMMAND_AUTHREP:
09241             /* For security, always ack immediately */
09242             if (delayreject)
09243                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09244             /* Ignore once we've started */
09245             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09246                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>");
09247                break;
09248             }
09249             if (authenticate_verify(iaxs[fr->callno], &ies)) {
09250                if (authdebug)
09251                   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);
09252                memset(&ied0, 0, sizeof(ied0));
09253                auth_fail(fr->callno, IAX_COMMAND_REJECT);
09254                break;
09255             }
09256             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09257                /* This might re-enter the IAX code and need the lock */
09258                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09259             } else
09260                exists = 0;
09261             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09262                if (authdebug)
09263                   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);
09264                memset(&ied0, 0, sizeof(ied0));
09265                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09266                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09267                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09268                if (!iaxs[fr->callno]) {
09269                   ast_mutex_unlock(&iaxsl[fr->callno]);
09270                   return 1;
09271                }
09272             } else {
09273                /* Select an appropriate format */
09274                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09275                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09276                      using_prefs = "reqonly";
09277                   } else {
09278                      using_prefs = "disabled";
09279                   }
09280                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09281                   memset(&pref, 0, sizeof(pref));
09282                   strcpy(caller_pref_buf, "disabled");
09283                   strcpy(host_pref_buf, "disabled");
09284                } else {
09285                   using_prefs = "mine";
09286                   if (ies.codec_prefs)
09287                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09288                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09289                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09290                         pref = iaxs[fr->callno]->rprefs;
09291                         using_prefs = "caller";
09292                      } else {
09293                         pref = iaxs[fr->callno]->prefs;
09294                      }
09295                   } else /* if no codec_prefs IE do it the old way */
09296                      pref = iaxs[fr->callno]->prefs;
09297                
09298                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09299                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09300                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09301                }
09302                if (!format) {
09303                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09304                      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);
09305                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09306                   }
09307                   if (!format) {
09308                      if (authdebug) {
09309                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
09310                            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);
09311                         else
09312                            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);
09313                      }
09314                      memset(&ied0, 0, sizeof(ied0));
09315                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09316                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09317                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09318                      if (!iaxs[fr->callno]) {
09319                         ast_mutex_unlock(&iaxsl[fr->callno]);
09320                         return 1;
09321                      }
09322                   } else {
09323                      /* Pick one... */
09324                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09325                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09326                            format = 0;
09327                      } else {
09328                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09329                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09330                            memset(&pref, 0, sizeof(pref));
09331                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09332                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09333                            strcpy(caller_pref_buf,"disabled");
09334                            strcpy(host_pref_buf,"disabled");
09335                         } else {
09336                            using_prefs = "mine";
09337                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09338                               /* Do the opposite of what we tried above. */
09339                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09340                                  pref = iaxs[fr->callno]->prefs;                 
09341                               } else {
09342                                  pref = iaxs[fr->callno]->rprefs;
09343                                  using_prefs = "caller";
09344                               }
09345                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09346                            } else /* if no codec_prefs IE do it the old way */
09347                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
09348                         }
09349                      }
09350                      if (!format) {
09351                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09352                         if (authdebug) {
09353                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09354                               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);
09355                            else
09356                               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);
09357                         }
09358                         memset(&ied0, 0, sizeof(ied0));
09359                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09360                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09361                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09362                         if (!iaxs[fr->callno]) {
09363                            ast_mutex_unlock(&iaxsl[fr->callno]);
09364                            return 1;
09365                         }
09366                      }
09367                   }
09368                }
09369                if (format) {
09370                   /* Authentication received */
09371                   memset(&ied1, 0, sizeof(ied1));
09372                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09373                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09374                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09375                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09376                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
09377                                  "%srequested format = %s,\n"
09378                                  "%srequested prefs = %s,\n"
09379                                  "%sactual format = %s,\n"
09380                                  "%shost prefs = %s,\n"
09381                                  "%spriority = %s\n", 
09382                                  ast_inet_ntoa(sin.sin_addr), 
09383                                  VERBOSE_PREFIX_4,
09384                                  ast_getformatname(iaxs[fr->callno]->peerformat),
09385                                  VERBOSE_PREFIX_4,
09386                                  caller_pref_buf,
09387                                  VERBOSE_PREFIX_4,
09388                                  ast_getformatname(format),
09389                                  VERBOSE_PREFIX_4,
09390                                  host_pref_buf,
09391                                  VERBOSE_PREFIX_4,
09392                                  using_prefs);
09393 
09394                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09395                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09396                         iax2_destroy(fr->callno);
09397                      else if (ies.vars) {
09398                         struct ast_datastore *variablestore;
09399                         struct ast_variable *var, *prev = NULL;
09400                         AST_LIST_HEAD(, ast_var_t) *varlist;
09401                         varlist = ast_calloc(1, sizeof(*varlist));
09402                         variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
09403                         if (variablestore && varlist) {
09404                            variablestore->data = varlist;
09405                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09406                            AST_LIST_HEAD_INIT(varlist);
09407                            ast_debug(1, "I can haz IAX vars? w00t\n");
09408                            for (var = ies.vars; var; var = var->next) {
09409                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09410                               if (prev)
09411                                  ast_free(prev);
09412                               prev = var;
09413                               if (!newvar) {
09414                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
09415                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09416                               } else {
09417                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09418                               }
09419                            }
09420                            if (prev)
09421                               ast_free(prev);
09422                            ies.vars = NULL;
09423                            ast_channel_datastore_add(c, variablestore);
09424                         } else {
09425                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09426                            if (variablestore)
09427                               ast_channel_datastore_free(variablestore);
09428                            if (varlist)
09429                               ast_free(varlist);
09430                         }
09431                      }
09432                   } else {
09433                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09434                      /* If this is a TBD call, we're ready but now what...  */
09435                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09436                   }
09437                }
09438             }
09439             break;
09440          case IAX_COMMAND_DIAL:
09441             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09442                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09443                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09444                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09445                   if (authdebug)
09446                      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);
09447                   memset(&ied0, 0, sizeof(ied0));
09448                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09449                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09450                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09451                   if (!iaxs[fr->callno]) {
09452                      ast_mutex_unlock(&iaxsl[fr->callno]);
09453                      return 1;
09454                   }
09455                } else {
09456                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09457                   ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09458                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09459                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09460                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09461                      iax2_destroy(fr->callno);
09462                   else if (ies.vars) {
09463                      struct ast_datastore *variablestore;
09464                      struct ast_variable *var, *prev = NULL;
09465                      AST_LIST_HEAD(, ast_var_t) *varlist;
09466                      varlist = ast_calloc(1, sizeof(*varlist));
09467                      variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
09468                      if (variablestore && varlist) {
09469                         variablestore->data = varlist;
09470                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09471                         AST_LIST_HEAD_INIT(varlist);
09472                         for (var = ies.vars; var; var = var->next) {
09473                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09474                            if (prev)
09475                               ast_free(prev);
09476                            prev = var;
09477                            if (!newvar) {
09478                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
09479                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09480                            } else {
09481                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09482                            }
09483                         }
09484                         if (prev)
09485                            ast_free(prev);
09486                         ies.vars = NULL;
09487                         ast_channel_datastore_add(c, variablestore);
09488                      } else {
09489                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09490                         if (variablestore)
09491                            ast_channel_datastore_free(variablestore);
09492                         if (varlist)
09493                            ast_free(varlist);
09494                      }
09495                   }
09496                }
09497             }
09498             break;
09499          case IAX_COMMAND_INVAL:
09500             iaxs[fr->callno]->error = ENOTCONN;
09501             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
09502             iax2_destroy(fr->callno);
09503             ast_debug(1, "Destroying call %d\n", fr->callno);
09504             break;
09505          case IAX_COMMAND_VNAK:
09506             ast_debug(1, "Received VNAK: resending outstanding frames\n");
09507             /* Force retransmission */
09508             vnak_retransmit(fr->callno, fr->iseqno);
09509             break;
09510          case IAX_COMMAND_REGREQ:
09511          case IAX_COMMAND_REGREL:
09512             /* For security, always ack immediately */
09513             if (delayreject)
09514                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09515             if (register_verify(fr->callno, &sin, &ies)) {
09516                if (!iaxs[fr->callno]) {
09517                   ast_mutex_unlock(&iaxsl[fr->callno]);
09518                   return 1;
09519                }
09520                /* Send delayed failure */
09521                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09522                break;
09523             }
09524             if (!iaxs[fr->callno]) {
09525                ast_mutex_unlock(&iaxsl[fr->callno]);
09526                return 1;
09527             }
09528             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09529                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09530 
09531                if (f.subclass == IAX_COMMAND_REGREL)
09532                   memset(&sin, 0, sizeof(sin));
09533                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09534                   ast_log(LOG_WARNING, "Registry error\n");
09535                if (!iaxs[fr->callno]) {
09536                   ast_mutex_unlock(&iaxsl[fr->callno]);
09537                   return 1;
09538                }
09539                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09540                   ast_mutex_unlock(&iaxsl[fr->callno]);
09541                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09542                   ast_mutex_lock(&iaxsl[fr->callno]);
09543                   if (!iaxs[fr->callno]) {
09544                      ast_mutex_unlock(&iaxsl[fr->callno]);
09545                      return 1;
09546                   }
09547                }
09548                break;
09549             }
09550             registry_authrequest(fr->callno);
09551             if (!iaxs[fr->callno]) {
09552                ast_mutex_unlock(&iaxsl[fr->callno]);
09553                return 1;
09554             }
09555             break;
09556          case IAX_COMMAND_REGACK:
09557             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
09558                ast_log(LOG_WARNING, "Registration failure\n");
09559             /* Send ack immediately, before we destroy */
09560             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09561             iax2_destroy(fr->callno);
09562             break;
09563          case IAX_COMMAND_REGREJ:
09564             if (iaxs[fr->callno]->reg) {
09565                if (authdebug) {
09566                   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));
09567                   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>");
09568                }
09569                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09570             }
09571             /* Send ack immediately, before we destroy */
09572             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09573             iax2_destroy(fr->callno);
09574             break;
09575          case IAX_COMMAND_REGAUTH:
09576             /* Authentication request */
09577             if (registry_rerequest(&ies, fr->callno, &sin)) {
09578                memset(&ied0, 0, sizeof(ied0));
09579                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09580                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09581                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09582                if (!iaxs[fr->callno]) {
09583                   ast_mutex_unlock(&iaxsl[fr->callno]);
09584                   return 1;
09585                }
09586             }
09587             break;
09588          case IAX_COMMAND_TXREJ:
09589             iaxs[fr->callno]->transferring = 0;
09590             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09591             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09592             if (iaxs[fr->callno]->bridgecallno) {
09593                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09594                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09595                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09596                }
09597             }
09598             break;
09599          case IAX_COMMAND_TXREADY:
09600             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09601                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09602                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09603                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09604                else
09605                   iaxs[fr->callno]->transferring = TRANSFER_READY;
09606                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09607                if (iaxs[fr->callno]->bridgecallno) {
09608                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09609                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09610                      /* They're both ready, now release them. */
09611                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09612                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09613                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09614 
09615                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09616                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09617 
09618                         memset(&ied0, 0, sizeof(ied0));
09619                         memset(&ied1, 0, sizeof(ied1));
09620                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09621                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09622                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09623                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09624                      } else {
09625                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09626                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09627 
09628                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09629                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09630                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09631                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09632 
09633                         /* Stop doing lag & ping requests */
09634                         stop_stuff(fr->callno);
09635                         stop_stuff(iaxs[fr->callno]->bridgecallno);
09636 
09637                         memset(&ied0, 0, sizeof(ied0));
09638                         memset(&ied1, 0, sizeof(ied1));
09639                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09640                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09641                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09642                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09643                      }
09644 
09645                   }
09646                }
09647             }
09648             break;
09649          case IAX_COMMAND_TXREQ:
09650             try_transfer(iaxs[fr->callno], &ies);
09651             break;
09652          case IAX_COMMAND_TXCNT:
09653             if (iaxs[fr->callno]->transferring)
09654                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09655             break;
09656          case IAX_COMMAND_TXREL:
09657             /* Send ack immediately, rather than waiting until we've changed addresses */
09658             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09659             complete_transfer(fr->callno, &ies);
09660             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
09661             break;   
09662          case IAX_COMMAND_TXMEDIA:
09663             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09664                AST_LIST_LOCK(&frame_queue);
09665                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09666                   /* Cancel any outstanding frames and start anew */
09667                   if ((fr->callno == cur->callno) && (cur->transfer))
09668                      cur->retries = -1;
09669                }
09670                AST_LIST_UNLOCK(&frame_queue);
09671                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
09672                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09673             }
09674             break;   
09675          case IAX_COMMAND_DPREP:
09676             complete_dpreply(iaxs[fr->callno], &ies);
09677             break;
09678          case IAX_COMMAND_UNSUPPORT:
09679             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09680             break;
09681          case IAX_COMMAND_FWDOWNL:
09682             /* Firmware download */
09683             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09684                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09685                break;
09686             }
09687             memset(&ied0, 0, sizeof(ied0));
09688             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09689             if (res < 0)
09690                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09691             else if (res > 0)
09692                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09693             else
09694                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09695             if (!iaxs[fr->callno]) {
09696                ast_mutex_unlock(&iaxsl[fr->callno]);
09697                return 1;
09698             }
09699             break;
09700          default:
09701             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09702             memset(&ied0, 0, sizeof(ied0));
09703             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09704             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09705          }
09706          /* Free remote variables (if any) */
09707          if (ies.vars) {
09708             ast_variables_destroy(ies.vars);
09709             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
09710             ies.vars = NULL;
09711          }
09712 
09713          /* Don't actually pass these frames along */
09714          if ((f.subclass != IAX_COMMAND_ACK) && 
09715            (f.subclass != IAX_COMMAND_TXCNT) && 
09716            (f.subclass != IAX_COMMAND_TXACC) && 
09717            (f.subclass != IAX_COMMAND_INVAL) &&
09718            (f.subclass != IAX_COMMAND_VNAK)) { 
09719             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09720                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09721          }
09722          ast_mutex_unlock(&iaxsl[fr->callno]);
09723          return 1;
09724       }
09725       /* Unless this is an ACK or INVAL frame, ack it */
09726       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09727          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09728    } else if (minivid) {
09729       f.frametype = AST_FRAME_VIDEO;
09730       if (iaxs[fr->callno]->videoformat > 0) 
09731          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09732       else {
09733          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09734          iax2_vnak(fr->callno);
09735          ast_mutex_unlock(&iaxsl[fr->callno]);
09736          return 1;
09737       }
09738       f.datalen = res - sizeof(*vh);
09739       if (f.datalen)
09740          f.data = thread->buf + sizeof(*vh);
09741       else
09742          f.data = NULL;
09743 #ifdef IAXTESTS
09744       if (test_resync) {
09745          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09746       } else
09747 #endif /* IAXTESTS */
09748          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09749    } else {
09750       /* A mini frame */
09751       f.frametype = AST_FRAME_VOICE;
09752       if (iaxs[fr->callno]->voiceformat > 0)
09753          f.subclass = iaxs[fr->callno]->voiceformat;
09754       else {
09755          ast_debug(1, "Received mini frame before first full voice frame\n");
09756          iax2_vnak(fr->callno);
09757          ast_mutex_unlock(&iaxsl[fr->callno]);
09758          return 1;
09759       }
09760       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09761       if (f.datalen < 0) {
09762          ast_log(LOG_WARNING, "Datalen < 0?\n");
09763          ast_mutex_unlock(&iaxsl[fr->callno]);
09764          return 1;
09765       }
09766       if (f.datalen)
09767          f.data = thread->buf + sizeof(*mh);
09768       else
09769          f.data = NULL;
09770 #ifdef IAXTESTS
09771       if (test_resync) {
09772          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09773       } else
09774 #endif /* IAXTESTS */
09775       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09776       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
09777    }
09778    /* Don't pass any packets until we're started */
09779    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09780       ast_mutex_unlock(&iaxsl[fr->callno]);
09781       return 1;
09782    }
09783    /* Common things */
09784    f.src = "IAX2";
09785    f.mallocd = 0;
09786    f.offset = 0;
09787    f.len = 0;
09788    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09789       f.samples = ast_codec_get_samples(&f);
09790       /* We need to byteswap incoming slinear samples from network byte order */
09791       if (f.subclass == AST_FORMAT_SLINEAR)
09792          ast_frame_byteswap_be(&f);
09793    } else
09794       f.samples = 0;
09795    iax_frame_wrap(fr, &f);
09796 
09797    /* If this is our most recent packet, use it as our basis for timestamping */
09798    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09799       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
09800       fr->outoforder = 0;
09801    } else {
09802       if (iaxdebug && iaxs[fr->callno])
09803          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);
09804       fr->outoforder = -1;
09805    }
09806    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09807    duped_fr = iaxfrdup2(fr);
09808    if (duped_fr) {
09809       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09810    }
09811    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09812       iaxs[fr->callno]->last = fr->ts;
09813 #if 1
09814       if (iaxdebug)
09815          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09816 #endif
09817    }
09818 
09819    /* Always run again */
09820    ast_mutex_unlock(&iaxsl[fr->callno]);
09821    return 1;
09822 }
09823 
09824 /* Function to clean up process thread if it is cancelled */
09825 static void iax2_process_thread_cleanup(void *data)
09826 {
09827    struct iax2_thread *thread = data;
09828    ast_mutex_destroy(&thread->lock);
09829    ast_cond_destroy(&thread->cond);
09830    ast_free(thread);
09831    ast_atomic_dec_and_test(&iaxactivethreadcount);
09832 }
09833 
09834 static void *iax2_process_thread(void *data)
09835 {
09836    struct iax2_thread *thread = data;
09837    struct timeval tv;
09838    struct timespec ts;
09839    int put_into_idle = 0;
09840 
09841    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09842    pthread_cleanup_push(iax2_process_thread_cleanup, data);
09843    for(;;) {
09844       /* Wait for something to signal us to be awake */
09845       ast_mutex_lock(&thread->lock);
09846 
09847       /* Flag that we're ready to accept signals */
09848       thread->ready_for_signal = 1;
09849       
09850       /* Put into idle list if applicable */
09851       if (put_into_idle)
09852          insert_idle_thread(thread);
09853 
09854       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
09855          struct iax2_thread *t = NULL;
09856          /* Wait to be signalled or time out */
09857          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09858          ts.tv_sec = tv.tv_sec;
09859          ts.tv_nsec = tv.tv_usec * 1000;
09860          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09861             /* This thread was never put back into the available dynamic
09862              * thread list, so just go away. */
09863             if (!put_into_idle) {
09864                ast_mutex_unlock(&thread->lock);
09865                break;
09866             }
09867             AST_LIST_LOCK(&dynamic_list);
09868             /* Account for the case where this thread is acquired *right* after a timeout */
09869             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09870                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
09871             AST_LIST_UNLOCK(&dynamic_list);
09872             if (t) {
09873                /* This dynamic thread timed out waiting for a task and was
09874                 * not acquired immediately after the timeout, 
09875                 * so it's time to go away. */
09876                ast_mutex_unlock(&thread->lock);
09877                break;
09878             }
09879             /* Someone grabbed our thread *right* after we timed out.
09880              * Wait for them to set us up with something to do and signal
09881              * us to continue. */
09882             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09883             ts.tv_sec = tv.tv_sec;
09884             ts.tv_nsec = tv.tv_usec * 1000;
09885             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09886             {
09887                ast_mutex_unlock(&thread->lock);
09888                break;
09889             }
09890          }
09891       } else {
09892          ast_cond_wait(&thread->cond, &thread->lock);
09893       }
09894 
09895       /* Go back into our respective list */
09896       put_into_idle = 1;
09897 
09898       ast_mutex_unlock(&thread->lock);
09899 
09900       if (thread->iostate == IAX_IOSTATE_IDLE)
09901          continue;
09902 
09903       /* Add ourselves to the active list now */
09904       AST_LIST_LOCK(&active_list);
09905       AST_LIST_INSERT_HEAD(&active_list, thread, list);
09906       AST_LIST_UNLOCK(&active_list);
09907 
09908       /* See what we need to do */
09909       switch(thread->iostate) {
09910       case IAX_IOSTATE_READY:
09911          thread->actions++;
09912          thread->iostate = IAX_IOSTATE_PROCESSING;
09913          socket_process(thread);
09914          handle_deferred_full_frames(thread);
09915          break;
09916       case IAX_IOSTATE_SCHEDREADY:
09917          thread->actions++;
09918          thread->iostate = IAX_IOSTATE_PROCESSING;
09919 #ifdef SCHED_MULTITHREADED
09920          thread->schedfunc(thread->scheddata);
09921 #endif      
09922       default:
09923          break;
09924       }
09925       time(&thread->checktime);
09926       thread->iostate = IAX_IOSTATE_IDLE;
09927 #ifdef DEBUG_SCHED_MULTITHREAD
09928       thread->curfunc[0]='\0';
09929 #endif      
09930 
09931       /* Now... remove ourselves from the active list, and return to the idle list */
09932       AST_LIST_LOCK(&active_list);
09933       AST_LIST_REMOVE(&active_list, thread, list);
09934       AST_LIST_UNLOCK(&active_list);
09935 
09936       /* Make sure another frame didn't sneak in there after we thought we were done. */
09937       handle_deferred_full_frames(thread);
09938    }
09939 
09940    /*!\note For some reason, idle threads are exiting without being removed
09941     * from an idle list, which is causing memory corruption.  Forcibly remove
09942     * it from the list, if it's there.
09943     */
09944    AST_LIST_LOCK(&idle_list);
09945    AST_LIST_REMOVE(&idle_list, thread, list);
09946    AST_LIST_UNLOCK(&idle_list);
09947 
09948    AST_LIST_LOCK(&dynamic_list);
09949    AST_LIST_REMOVE(&dynamic_list, thread, list);
09950    AST_LIST_UNLOCK(&dynamic_list);
09951 
09952    /* I am exiting here on my own volition, I need to clean up my own data structures
09953    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
09954    */
09955    pthread_cleanup_pop(1);
09956    return NULL;
09957 }
09958 
09959 static int iax2_do_register(struct iax2_registry *reg)
09960 {
09961    struct iax_ie_data ied;
09962    if (iaxdebug)
09963       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
09964 
09965    if (reg->dnsmgr && 
09966        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09967       /* Maybe the IP has changed, force DNS refresh */
09968       ast_dnsmgr_refresh(reg->dnsmgr);
09969    }
09970    
09971    /*
09972     * if IP has Changed, free allocated call to create a new one with new IP
09973     * call has the pointer to IP and must be updated to the new one
09974     */
09975    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
09976       int callno = reg->callno;
09977       ast_mutex_lock(&iaxsl[callno]);
09978       iax2_destroy(callno);
09979       ast_mutex_unlock(&iaxsl[callno]);
09980       reg->callno = 0;
09981    }
09982    if (!reg->addr.sin_addr.s_addr) {
09983       if (iaxdebug)
09984          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
09985       /* Setup the next registration attempt */
09986       reg->expire = iax2_sched_replace(reg->expire, sched, 
09987          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
09988       return -1;
09989    }
09990 
09991    if (!reg->callno) {
09992       ast_debug(3, "Allocate call number\n");
09993       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
09994       if (reg->callno < 1) {
09995          ast_log(LOG_WARNING, "Unable to create call for registration\n");
09996          return -1;
09997       } else
09998          ast_debug(3, "Registration created on call %d\n", reg->callno);
09999       iaxs[reg->callno]->reg = reg;
10000       ast_mutex_unlock(&iaxsl[reg->callno]);
10001    }
10002    /* Setup the next registration a little early */
10003    reg->expire = iax2_sched_replace(reg->expire, sched, 
10004       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10005    /* Send the request */
10006    memset(&ied, 0, sizeof(ied));
10007    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10008    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10009    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10010    reg->regstate = REG_STATE_REGSENT;
10011    return 0;
10012 }
10013 
10014 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
10015 {
10016    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
10017       is found for template */
10018    struct iax_ie_data provdata;
10019    struct iax_ie_data ied;
10020    unsigned int sig;
10021    struct sockaddr_in sin;
10022    int callno;
10023    struct create_addr_info cai;
10024 
10025    memset(&cai, 0, sizeof(cai));
10026 
10027    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
10028 
10029    if (iax_provision_build(&provdata, &sig, template, force)) {
10030       ast_debug(1, "No provisioning found for template '%s'\n", template);
10031       return 0;
10032    }
10033 
10034    if (end) {
10035       memcpy(&sin, end, sizeof(sin));
10036       cai.sockfd = sockfd;
10037    } else if (create_addr(dest, NULL, &sin, &cai))
10038       return -1;
10039 
10040    /* Build the rest of the message */
10041    memset(&ied, 0, sizeof(ied));
10042    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10043 
10044    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10045    if (!callno)
10046       return -1;
10047 
10048    if (iaxs[callno]) {
10049       /* Schedule autodestruct in case they don't ever give us anything back */
10050       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
10051          sched, 15000, auto_hangup, (void *)(long)callno);
10052       ast_set_flag(iaxs[callno], IAX_PROVISION);
10053       /* Got a call number now, so go ahead and send the provisioning information */
10054       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10055    }
10056    ast_mutex_unlock(&iaxsl[callno]);
10057 
10058    return 1;
10059 }
10060 
10061 static char *papp = "IAX2Provision";
10062 static char *psyn = "Provision a calling IAXy with a given template";
10063 static char *pdescrip = 
10064 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
10065 "the calling entity is in fact an IAXy) with the given template or\n"
10066 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
10067 
10068 /*! iax2provision
10069 \ingroup applications
10070 */
10071 static int iax2_prov_app(struct ast_channel *chan, void *data)
10072 {
10073    int res;
10074    char *sdata;
10075    char *opts;
10076    int force =0;
10077    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
10078    if (ast_strlen_zero(data))
10079       data = "default";
10080    sdata = ast_strdupa(data);
10081    opts = strchr(sdata, '|');
10082    if (opts)
10083       *opts='\0';
10084 
10085    if (chan->tech != &iax2_tech) {
10086       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
10087       return -1;
10088    } 
10089    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
10090       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
10091       return -1;
10092    }
10093    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
10094    ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
10095       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
10096       sdata, res);
10097    return res;
10098 }
10099 
10100 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
10101 {
10102    int force = 0;
10103    int res;
10104 
10105    switch (cmd) {
10106    case CLI_INIT:
10107       e->command = "iax2 provision";
10108       e->usage = 
10109          "Usage: iax2 provision <host> <template> [forced]\n"
10110          "       Provisions the given peer or IP address using a template\n"
10111          "       matching either 'template' or '*' if the template is not\n"
10112          "       found.  If 'forced' is specified, even empty provisioning\n"
10113          "       fields will be provisioned as empty fields.\n";
10114       return NULL;
10115    case CLI_GENERATE:
10116       if (a->pos == 3)
10117          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
10118       return NULL;
10119    }
10120 
10121    if (a->argc < 4)
10122       return CLI_SHOWUSAGE;
10123    if (a->argc > 4) {
10124       if (!strcasecmp(a->argv[4], "forced"))
10125          force = 1;
10126       else
10127          return CLI_SHOWUSAGE;
10128    }
10129    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
10130    if (res < 0)
10131       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
10132    else if (res < 1)
10133       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
10134    else
10135       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
10136    return CLI_SUCCESS;
10137 }
10138 
10139 static void __iax2_poke_noanswer(const void *data)
10140 {
10141    struct iax2_peer *peer = (struct iax2_peer *)data;
10142    int callno;
10143 
10144    if (peer->lastms > -1) {
10145       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10146       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10147       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
10148    }
10149    if ((callno = peer->callno) > 0) {
10150       ast_mutex_lock(&iaxsl[callno]);
10151       iax2_destroy(callno);
10152       ast_mutex_unlock(&iaxsl[callno]);
10153    }
10154    peer->callno = 0;
10155    peer->lastms = -1;
10156    /* Try again quickly */
10157    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10158    if (peer->pokeexpire == -1)
10159       peer_unref(peer);
10160 }
10161 
10162 static int iax2_poke_noanswer(const void *data)
10163 {
10164    struct iax2_peer *peer = (struct iax2_peer *)data;
10165    peer->pokeexpire = -1;
10166 #ifdef SCHED_MULTITHREADED
10167    if (schedule_action(__iax2_poke_noanswer, data))
10168 #endif      
10169       __iax2_poke_noanswer(data);
10170    peer_unref(peer);
10171    return 0;
10172 }
10173 
10174 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
10175 {
10176    struct iax2_peer *peer = obj;
10177 
10178    iax2_poke_peer(peer, 0);
10179 
10180    return 0;
10181 }
10182 
10183 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
10184 {
10185    int callno;
10186    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10187       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
10188         immediately after clearing things out */
10189       peer->lastms = 0;
10190       peer->historicms = 0;
10191       peer->pokeexpire = -1;
10192       peer->callno = 0;
10193       return 0;
10194    }
10195 
10196    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
10197    if ((callno = peer->callno) > 0) {
10198       ast_log(LOG_NOTICE, "Still have a callno...\n");
10199       ast_mutex_lock(&iaxsl[callno]);
10200       iax2_destroy(callno);
10201       ast_mutex_unlock(&iaxsl[callno]);
10202    }
10203    if (heldcall)
10204       ast_mutex_unlock(&iaxsl[heldcall]);
10205    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10206    if (heldcall)
10207       ast_mutex_lock(&iaxsl[heldcall]);
10208    if (peer->callno < 1) {
10209       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10210       return -1;
10211    }
10212 
10213    /* Speed up retransmission times for this qualify call */
10214    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10215    iaxs[peer->callno]->peerpoke = peer;
10216 
10217    if (peer->pokeexpire > -1) {
10218       if (!ast_sched_del(sched, peer->pokeexpire)) {
10219          peer->pokeexpire = -1;
10220          peer_unref(peer);
10221       }
10222    }
10223  
10224    /* Queue up a new task to handle no reply */
10225    /* If the host is already unreachable then use the unreachable interval instead */
10226    if (peer->lastms < 0)
10227       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10228    else
10229       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10230 
10231    if (peer->pokeexpire == -1)
10232       peer_unref(peer);
10233 
10234    /* And send the poke */
10235    ast_mutex_lock(&iaxsl[callno]);
10236    if (iaxs[callno]) {
10237       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
10238    }
10239    ast_mutex_unlock(&iaxsl[callno]);
10240 
10241    return 0;
10242 }
10243 
10244 static void free_context(struct iax2_context *con)
10245 {
10246    struct iax2_context *conl;
10247    while(con) {
10248       conl = con;
10249       con = con->next;
10250       ast_free(conl);
10251    }
10252 }
10253 
10254 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
10255 {
10256    int callno;
10257    int res;
10258    int fmt, native;
10259    struct sockaddr_in sin;
10260    struct ast_channel *c;
10261    struct parsed_dial_string pds;
10262    struct create_addr_info cai;
10263    char *tmpstr;
10264 
10265    memset(&pds, 0, sizeof(pds));
10266    tmpstr = ast_strdupa(data);
10267    parse_dial_string(tmpstr, &pds);
10268 
10269    if (ast_strlen_zero(pds.peer)) {
10270       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10271       return NULL;
10272    }
10273           
10274    memset(&cai, 0, sizeof(cai));
10275    cai.capability = iax2_capability;
10276 
10277    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10278    
10279    /* Populate our address from the given */
10280    if (create_addr(pds.peer, NULL, &sin, &cai)) {
10281       *cause = AST_CAUSE_UNREGISTERED;
10282       return NULL;
10283    }
10284 
10285    if (pds.port)
10286       sin.sin_port = htons(atoi(pds.port));
10287 
10288    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10289    if (callno < 1) {
10290       ast_log(LOG_WARNING, "Unable to create call\n");
10291       *cause = AST_CAUSE_CONGESTION;
10292       return NULL;
10293    }
10294 
10295    /* If this is a trunk, update it now */
10296    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
10297    if (ast_test_flag(&cai, IAX_TRUNK)) {
10298       int new_callno;
10299       if ((new_callno = make_trunk(callno, 1)) != -1)
10300          callno = new_callno;
10301    }
10302    iaxs[callno]->maxtime = cai.maxtime;
10303    if (cai.found)
10304       ast_string_field_set(iaxs[callno], host, pds.peer);
10305 
10306    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10307 
10308    ast_mutex_unlock(&iaxsl[callno]);
10309 
10310    if (c) {
10311       /* Choose a format we can live with */
10312       if (c->nativeformats & format) 
10313          c->nativeformats &= format;
10314       else {
10315          native = c->nativeformats;
10316          fmt = format;
10317          res = ast_translator_best_choice(&fmt, &native);
10318          if (res < 0) {
10319             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10320                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10321             ast_hangup(c);
10322             return NULL;
10323          }
10324          c->nativeformats = native;
10325       }
10326       c->readformat = ast_best_codec(c->nativeformats);
10327       c->writeformat = c->readformat;
10328    }
10329 
10330    return c;
10331 }
10332 
10333 static void *sched_thread(void *ignore)
10334 {
10335    int count;
10336    int res;
10337    struct timeval tv;
10338    struct timespec ts;
10339 
10340    for (;;) {
10341       res = ast_sched_wait(sched);
10342       if ((res > 1000) || (res < 0))
10343          res = 1000;
10344       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
10345       ts.tv_sec = tv.tv_sec;
10346       ts.tv_nsec = tv.tv_usec * 1000;
10347 
10348       pthread_testcancel();
10349       ast_mutex_lock(&sched_lock);
10350       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10351       ast_mutex_unlock(&sched_lock);
10352       pthread_testcancel();
10353 
10354       count = ast_sched_runq(sched);
10355       if (count >= 20)
10356          ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10357    }
10358 
10359    return NULL;
10360 }
10361 
10362 static void *network_thread(void *ignore)
10363 {
10364    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
10365       from the network, and queue them for delivery to the channels */
10366    int res, count, wakeup;
10367    struct iax_frame *f;
10368 
10369    if (timingfd > -1)
10370       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10371    
10372    for(;;) {
10373       pthread_testcancel();
10374 
10375       /* Go through the queue, sending messages which have not yet been
10376          sent, and scheduling retransmissions if appropriate */
10377       AST_LIST_LOCK(&frame_queue);
10378       count = 0;
10379       wakeup = -1;
10380       AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
10381          if (f->sentyet)
10382             continue;
10383          
10384          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
10385          if (ast_mutex_trylock(&iaxsl[f->callno])) {
10386             wakeup = 1;
10387             continue;
10388          }
10389 
10390          f->sentyet = 1;
10391 
10392          if (iaxs[f->callno]) {
10393             send_packet(f);
10394             count++;
10395          } 
10396 
10397          ast_mutex_unlock(&iaxsl[f->callno]);
10398 
10399          if (f->retries < 0) {
10400             /* This is not supposed to be retransmitted */
10401             AST_LIST_REMOVE_CURRENT(list);
10402             /* Free the iax frame */
10403             iax_frame_free(f);
10404          } else {
10405             /* We need reliable delivery.  Schedule a retransmission */
10406             f->retries++;
10407             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10408          }
10409       }
10410       AST_LIST_TRAVERSE_SAFE_END;
10411       AST_LIST_UNLOCK(&frame_queue);
10412 
10413       pthread_testcancel();
10414       if (count >= 20)
10415          ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10416 
10417       /* Now do the IO, and run scheduled tasks */
10418       res = ast_io_wait(io, wakeup);
10419       if (res >= 0) {
10420          if (res >= 20)
10421             ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10422       }
10423    }
10424    return NULL;
10425 }
10426 
10427 static int start_network_thread(void)
10428 {
10429    struct iax2_thread *thread;
10430    int threadcount = 0;
10431    int x;
10432    for (x = 0; x < iaxthreadcount; x++) {
10433       thread = ast_calloc(1, sizeof(*thread));
10434       if (thread) {
10435          thread->type = IAX_THREAD_TYPE_POOL;
10436          thread->threadnum = ++threadcount;
10437          ast_mutex_init(&thread->lock);
10438          ast_cond_init(&thread->cond, NULL);
10439          if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
10440             ast_log(LOG_WARNING, "Failed to create new thread!\n");
10441             ast_free(thread);
10442             thread = NULL;
10443          }
10444          AST_LIST_LOCK(&idle_list);
10445          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10446          AST_LIST_UNLOCK(&idle_list);
10447       }
10448    }
10449    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10450    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10451    ast_verb(2, "%d helper threads started\n", threadcount);
10452    return 0;
10453 }
10454 
10455 static struct iax2_context *build_context(const char *context)
10456 {
10457    struct iax2_context *con;
10458 
10459    if ((con = ast_calloc(1, sizeof(*con))))
10460       ast_copy_string(con->context, context, sizeof(con->context));
10461    
10462    return con;
10463 }
10464 
10465 static int get_auth_methods(const char *value)
10466 {
10467    int methods = 0;
10468    if (strstr(value, "rsa"))
10469       methods |= IAX_AUTH_RSA;
10470    if (strstr(value, "md5"))
10471       methods |= IAX_AUTH_MD5;
10472    if (strstr(value, "plaintext"))
10473       methods |= IAX_AUTH_PLAINTEXT;
10474    return methods;
10475 }
10476 
10477 
10478 /*! \brief Check if address can be used as packet source.
10479  \return 0  address available, 1  address unavailable, -1  error
10480 */
10481 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
10482 {
10483    int sd;
10484    int res;
10485    
10486    sd = socket(AF_INET, SOCK_DGRAM, 0);
10487    if (sd < 0) {
10488       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10489       return -1;
10490    }
10491 
10492    res = bind(sd, sa, salen);
10493    if (res < 0) {
10494       ast_debug(1, "Can't bind: %s\n", strerror(errno));
10495       close(sd);
10496       return 1;
10497    }
10498 
10499    close(sd);
10500    return 0;
10501 }
10502 
10503 /*! \brief Parse the "sourceaddress" value,
10504   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
10505   not found. */
10506 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
10507 {
10508    struct sockaddr_in sin;
10509    int nonlocal = 1;
10510    int port = IAX_DEFAULT_PORTNO;
10511    int sockfd = defaultsockfd;
10512    char *tmp;
10513    char *addr;
10514    char *portstr;
10515 
10516    if (!(tmp = ast_strdupa(srcaddr)))
10517       return -1;
10518 
10519    addr = strsep(&tmp, ":");
10520    portstr = tmp;
10521 
10522    if (portstr) {
10523       port = atoi(portstr);
10524       if (port < 1)
10525          port = IAX_DEFAULT_PORTNO;
10526    }
10527    
10528    if (!ast_get_ip(&sin, addr)) {
10529       struct ast_netsock *sock;
10530       int res;
10531 
10532       sin.sin_port = 0;
10533       sin.sin_family = AF_INET;
10534       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10535       if (res == 0) {
10536          /* ip address valid. */
10537          sin.sin_port = htons(port);
10538          if (!(sock = ast_netsock_find(netsock, &sin)))
10539             sock = ast_netsock_find(outsock, &sin);
10540          if (sock) {
10541             sockfd = ast_netsock_sockfd(sock);
10542             nonlocal = 0;
10543          } else {
10544             unsigned int orig_saddr = sin.sin_addr.s_addr;
10545             /* INADDR_ANY matches anyway! */
10546             sin.sin_addr.s_addr = INADDR_ANY;
10547             if (ast_netsock_find(netsock, &sin)) {
10548                sin.sin_addr.s_addr = orig_saddr;
10549                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, cos, socket_read, NULL);
10550                if (sock) {
10551                   sockfd = ast_netsock_sockfd(sock);
10552                   ast_netsock_unref(sock);
10553                   nonlocal = 0;
10554                } else {
10555                   nonlocal = 2;
10556                }
10557             }
10558          }
10559       }
10560    }
10561       
10562    peer->sockfd = sockfd;
10563 
10564    if (nonlocal == 1) {
10565       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10566          srcaddr, peer->name);
10567       return -1;
10568         } else if (nonlocal == 2) {
10569       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10570          srcaddr, peer->name);
10571          return -1;
10572    } else {
10573       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10574       return 0;
10575    }
10576 }
10577 
10578 static void peer_destructor(void *obj)
10579 {
10580    struct iax2_peer *peer = obj;
10581    int callno = peer->callno;
10582 
10583    ast_free_ha(peer->ha);
10584 
10585    if (callno > 0) {
10586       ast_mutex_lock(&iaxsl[callno]);
10587       iax2_destroy(callno);
10588       ast_mutex_unlock(&iaxsl[callno]);
10589    }
10590 
10591    register_peer_exten(peer, 0);
10592 
10593    if (peer->dnsmgr)
10594       ast_dnsmgr_release(peer->dnsmgr);
10595 
10596    if (peer->mwi_event_sub)
10597       ast_event_unsubscribe(peer->mwi_event_sub);
10598 
10599    ast_string_field_free_memory(peer);
10600 }
10601 
10602 /*! \brief Create peer structure based on configuration */
10603 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10604 {
10605    struct iax2_peer *peer = NULL;
10606    struct ast_ha *oldha = NULL;
10607    int maskfound = 0;
10608    int found = 0;
10609    int firstpass = 1;
10610    struct iax2_peer tmp_peer = {
10611       .name = name,
10612    };
10613 
10614    if (!temponly) {
10615       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10616       if (peer && !ast_test_flag(peer, IAX_DELME))
10617          firstpass = 0;
10618    }
10619 
10620    if (peer) {
10621       found++;
10622       if (firstpass) {
10623          oldha = peer->ha;
10624          peer->ha = NULL;
10625       }
10626       unlink_peer(peer);
10627    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10628       peer->expire = -1;
10629       peer->pokeexpire = -1;
10630       peer->sockfd = defaultsockfd;
10631       if (ast_string_field_init(peer, 32))
10632          peer = peer_unref(peer);
10633    }
10634 
10635    if (peer) {
10636       if (firstpass) {
10637          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10638          peer->encmethods = iax2_encryption;
10639          peer->adsi = adsi;
10640          ast_string_field_set(peer,secret,"");
10641          if (!found) {
10642             ast_string_field_set(peer, name, name);
10643             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10644             peer->expiry = min_reg_expire;
10645          }
10646          peer->prefs = prefs;
10647          peer->capability = iax2_capability;
10648          peer->smoothing = 0;
10649          peer->pokefreqok = DEFAULT_FREQ_OK;
10650          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10651          ast_string_field_set(peer,context,"");
10652          ast_string_field_set(peer,peercontext,"");
10653          ast_clear_flag(peer, IAX_HASCALLERID);
10654          ast_string_field_set(peer, cid_name, "");
10655          ast_string_field_set(peer, cid_num, "");
10656          ast_string_field_set(peer, mohinterpret, mohinterpret);
10657          ast_string_field_set(peer, mohsuggest, mohsuggest);
10658       }
10659 
10660       if (!v) {
10661          v = alt;
10662          alt = NULL;
10663       }
10664       while(v) {
10665          if (!strcasecmp(v->name, "secret")) {
10666             ast_string_field_set(peer, secret, v->value);
10667          } else if (!strcasecmp(v->name, "mailbox")) {
10668             ast_string_field_set(peer, mailbox, v->value);
10669          } else if (!strcasecmp(v->name, "hasvoicemail")) {
10670             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10671                ast_string_field_set(peer, mailbox, name);
10672             }
10673          } else if (!strcasecmp(v->name, "mohinterpret")) {
10674             ast_string_field_set(peer, mohinterpret, v->value);
10675          } else if (!strcasecmp(v->name, "mohsuggest")) {
10676             ast_string_field_set(peer, mohsuggest, v->value);
10677          } else if (!strcasecmp(v->name, "dbsecret")) {
10678             ast_string_field_set(peer, dbsecret, v->value);
10679          } else if (!strcasecmp(v->name, "trunk")) {
10680             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
10681             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
10682                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without DAHDI timing\n", peer->name);
10683                ast_clear_flag(peer, IAX_TRUNK);
10684             }
10685          } else if (!strcasecmp(v->name, "auth")) {
10686             peer->authmethods = get_auth_methods(v->value);
10687          } else if (!strcasecmp(v->name, "encryption")) {
10688             peer->encmethods = get_encrypt_methods(v->value);
10689          } else if (!strcasecmp(v->name, "transfer")) {
10690             if (!strcasecmp(v->value, "mediaonly")) {
10691                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10692             } else if (ast_true(v->value)) {
10693                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10694             } else 
10695                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10696          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10697             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
10698          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10699             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
10700          } else if (!strcasecmp(v->name, "host")) {
10701             if (!strcasecmp(v->value, "dynamic")) {
10702                /* They'll register with us */
10703                ast_set_flag(peer, IAX_DYNAMIC); 
10704                if (!found) {
10705                   /* Initialize stuff iff we're not found, otherwise
10706                      we keep going with what we had */
10707                   memset(&peer->addr.sin_addr, 0, 4);
10708                   if (peer->addr.sin_port) {
10709                      /* If we've already got a port, make it the default rather than absolute */
10710                      peer->defaddr.sin_port = peer->addr.sin_port;
10711                      peer->addr.sin_port = 0;
10712                   }
10713                }
10714             } else {
10715                /* Non-dynamic.  Make sure we become that way if we're not */
10716                AST_SCHED_DEL(sched, peer->expire);
10717                ast_clear_flag(peer, IAX_DYNAMIC);
10718                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
10719                   return peer_unref(peer);
10720                if (!peer->addr.sin_port)
10721                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10722             }
10723             if (!maskfound)
10724                inet_aton("255.255.255.255", &peer->mask);
10725          } else if (!strcasecmp(v->name, "defaultip")) {
10726             if (ast_get_ip(&peer->defaddr, v->value))
10727                return peer_unref(peer);
10728          } else if (!strcasecmp(v->name, "sourceaddress")) {
10729             peer_set_srcaddr(peer, v->value);
10730          } else if (!strcasecmp(v->name, "permit") ||
10731                   !strcasecmp(v->name, "deny")) {
10732             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
10733          } else if (!strcasecmp(v->name, "mask")) {
10734             maskfound++;
10735             inet_aton(v->value, &peer->mask);
10736          } else if (!strcasecmp(v->name, "context")) {
10737             ast_string_field_set(peer, context, v->value);
10738          } else if (!strcasecmp(v->name, "regexten")) {
10739             ast_string_field_set(peer, regexten, v->value);
10740          } else if (!strcasecmp(v->name, "peercontext")) {
10741             ast_string_field_set(peer, peercontext, v->value);
10742          } else if (!strcasecmp(v->name, "port")) {
10743             if (ast_test_flag(peer, IAX_DYNAMIC))
10744                peer->defaddr.sin_port = htons(atoi(v->value));
10745             else
10746                peer->addr.sin_port = htons(atoi(v->value));
10747          } else if (!strcasecmp(v->name, "username")) {
10748             ast_string_field_set(peer, username, v->value);
10749          } else if (!strcasecmp(v->name, "allow")) {
10750             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10751          } else if (!strcasecmp(v->name, "disallow")) {
10752             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10753          } else if (!strcasecmp(v->name, "callerid")) {
10754             if (!ast_strlen_zero(v->value)) {
10755                char name2[80];
10756                char num2[80];
10757                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10758                ast_string_field_set(peer, cid_name, name2);
10759                ast_string_field_set(peer, cid_num, num2);
10760             } else {
10761                ast_string_field_set(peer, cid_name, "");
10762                ast_string_field_set(peer, cid_num, "");
10763             }
10764             ast_set_flag(peer, IAX_HASCALLERID);
10765          } else if (!strcasecmp(v->name, "fullname")) {
10766             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10767             ast_set_flag(peer, IAX_HASCALLERID);
10768          } else if (!strcasecmp(v->name, "cid_number")) {
10769             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10770             ast_set_flag(peer, IAX_HASCALLERID);
10771          } else if (!strcasecmp(v->name, "sendani")) {
10772             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
10773          } else if (!strcasecmp(v->name, "inkeys")) {
10774             ast_string_field_set(peer, inkeys, v->value);
10775          } else if (!strcasecmp(v->name, "outkey")) {
10776             ast_string_field_set(peer, outkey, v->value);
10777          } else if (!strcasecmp(v->name, "qualify")) {
10778             if (!strcasecmp(v->value, "no")) {
10779                peer->maxms = 0;
10780             } else if (!strcasecmp(v->value, "yes")) {
10781                peer->maxms = DEFAULT_MAXMS;
10782             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
10783                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);
10784                peer->maxms = 0;
10785             }
10786          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10787             peer->smoothing = ast_true(v->value);
10788          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10789             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
10790                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);
10791             }
10792          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10793             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
10794                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);
10795             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10796          } else if (!strcasecmp(v->name, "timezone")) {
10797             ast_string_field_set(peer, zonetag, v->value);
10798          } else if (!strcasecmp(v->name, "adsi")) {
10799             peer->adsi = ast_true(v->value);
10800          }/* else if (strcasecmp(v->name,"type")) */
10801          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10802          v = v->next;
10803          if (!v) {
10804             v = alt;
10805             alt = NULL;
10806          }
10807       }
10808       if (!peer->authmethods)
10809          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10810       ast_clear_flag(peer, IAX_DELME); 
10811       /* Make sure these are IPv4 addresses */
10812       peer->addr.sin_family = AF_INET;
10813    }
10814 
10815    if (oldha)
10816       ast_free_ha(oldha);
10817 
10818    if (!ast_strlen_zero(peer->mailbox)) {
10819       char *mailbox, *context;
10820       context = mailbox = ast_strdupa(peer->mailbox);
10821       strsep(&context, "@");
10822       if (ast_strlen_zero(context))
10823          context = "default";
10824       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
10825          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
10826          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
10827          AST_EVENT_IE_END);
10828    }
10829 
10830    return peer;
10831 }
10832 
10833 static void user_destructor(void *obj)
10834 {
10835    struct iax2_user *user = obj;
10836 
10837    ast_free_ha(user->ha);
10838    free_context(user->contexts);
10839    if(user->vars) {
10840       ast_variables_destroy(user->vars);
10841       user->vars = NULL;
10842    }
10843    ast_string_field_free_memory(user);
10844 }
10845 
10846 /*! \brief Create in-memory user structure from configuration */
10847 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10848 {
10849    struct iax2_user *user = NULL;
10850    struct iax2_context *con, *conl = NULL;
10851    struct ast_ha *oldha = NULL;
10852    struct iax2_context *oldcon = NULL;
10853    int format;
10854    int firstpass=1;
10855    int oldcurauthreq = 0;
10856    char *varname = NULL, *varval = NULL;
10857    struct ast_variable *tmpvar = NULL;
10858    struct iax2_user tmp_user = {
10859       .name = name,
10860    };
10861 
10862    if (!temponly) {
10863       user = ao2_find(users, &tmp_user, OBJ_POINTER);
10864       if (user && !ast_test_flag(user, IAX_DELME))
10865          firstpass = 0;
10866    }
10867 
10868    if (user) {
10869       if (firstpass) {
10870          oldcurauthreq = user->curauthreq;
10871          oldha = user->ha;
10872          oldcon = user->contexts;
10873          user->ha = NULL;
10874          user->contexts = NULL;
10875       }
10876       /* Already in the list, remove it and it will be added back (or FREE'd) */
10877       ao2_unlink(users, user);
10878    } else {
10879       user = ao2_alloc(sizeof(*user), user_destructor);
10880    }
10881    
10882    if (user) {
10883       if (firstpass) {
10884          ast_string_field_free_memory(user);
10885          memset(user, 0, sizeof(struct iax2_user));
10886          if (ast_string_field_init(user, 32)) {
10887             user = user_unref(user);
10888             goto cleanup;
10889          }
10890          user->maxauthreq = maxauthreq;
10891          user->curauthreq = oldcurauthreq;
10892          user->prefs = prefs;
10893          user->capability = iax2_capability;
10894          user->encmethods = iax2_encryption;
10895          user->adsi = adsi;
10896          ast_string_field_set(user, name, name);
10897          ast_string_field_set(user, language, language);
10898          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
10899          ast_clear_flag(user, IAX_HASCALLERID);
10900          ast_string_field_set(user, cid_name, "");
10901          ast_string_field_set(user, cid_num, "");
10902          ast_string_field_set(user, accountcode, accountcode);
10903          ast_string_field_set(user, mohinterpret, mohinterpret);
10904          ast_string_field_set(user, mohsuggest, mohsuggest);
10905       }
10906       if (!v) {
10907          v = alt;
10908          alt = NULL;
10909       }
10910       while(v) {
10911          if (!strcasecmp(v->name, "context")) {
10912             con = build_context(v->value);
10913             if (con) {
10914                if (conl)
10915                   conl->next = con;
10916                else
10917                   user->contexts = con;
10918                conl = con;
10919             }
10920          } else if (!strcasecmp(v->name, "permit") ||
10921                   !strcasecmp(v->name, "deny")) {
10922             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
10923          } else if (!strcasecmp(v->name, "setvar")) {
10924             varname = ast_strdupa(v->value);
10925             if (varname && (varval = strchr(varname,'='))) {
10926                *varval = '\0';
10927                varval++;
10928                if((tmpvar = ast_variable_new(varname, varval, ""))) {
10929                   tmpvar->next = user->vars; 
10930                   user->vars = tmpvar;
10931                }
10932             }
10933          } else if (!strcasecmp(v->name, "allow")) {
10934             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10935          } else if (!strcasecmp(v->name, "disallow")) {
10936             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10937          } else if (!strcasecmp(v->name, "trunk")) {
10938             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
10939             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
10940                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without DAHDI timing\n", user->name);
10941                ast_clear_flag(user, IAX_TRUNK);
10942             }
10943          } else if (!strcasecmp(v->name, "auth")) {
10944             user->authmethods = get_auth_methods(v->value);
10945          } else if (!strcasecmp(v->name, "encryption")) {
10946             user->encmethods = get_encrypt_methods(v->value);
10947          } else if (!strcasecmp(v->name, "transfer")) {
10948             if (!strcasecmp(v->value, "mediaonly")) {
10949                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10950             } else if (ast_true(v->value)) {
10951                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10952             } else 
10953                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10954          } else if (!strcasecmp(v->name, "codecpriority")) {
10955             if(!strcasecmp(v->value, "caller"))
10956                ast_set_flag(user, IAX_CODEC_USER_FIRST);
10957             else if(!strcasecmp(v->value, "disabled"))
10958                ast_set_flag(user, IAX_CODEC_NOPREFS);
10959             else if(!strcasecmp(v->value, "reqonly")) {
10960                ast_set_flag(user, IAX_CODEC_NOCAP);
10961                ast_set_flag(user, IAX_CODEC_NOPREFS);
10962             }
10963          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10964             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
10965          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10966             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
10967          } else if (!strcasecmp(v->name, "dbsecret")) {
10968             ast_string_field_set(user, dbsecret, v->value);
10969          } else if (!strcasecmp(v->name, "secret")) {
10970             if (!ast_strlen_zero(user->secret)) {
10971                char *old = ast_strdupa(user->secret);
10972 
10973                ast_string_field_build(user, secret, "%s;%s", old, v->value);
10974             } else
10975                ast_string_field_set(user, secret, v->value);
10976          } else if (!strcasecmp(v->name, "callerid")) {
10977             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
10978                char name2[80];
10979                char num2[80];
10980                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10981                ast_string_field_set(user, cid_name, name2);
10982                ast_string_field_set(user, cid_num, num2);
10983                ast_set_flag(user, IAX_HASCALLERID);
10984             } else {
10985                ast_clear_flag(user, IAX_HASCALLERID);
10986                ast_string_field_set(user, cid_name, "");
10987                ast_string_field_set(user, cid_num, "");
10988             }
10989          } else if (!strcasecmp(v->name, "fullname")) {
10990             if (!ast_strlen_zero(v->value)) {
10991                ast_string_field_set(user, cid_name, v->value);
10992                ast_set_flag(user, IAX_HASCALLERID);
10993             } else {
10994                ast_string_field_set(user, cid_name, "");
10995                if (ast_strlen_zero(user->cid_num))
10996                   ast_clear_flag(user, IAX_HASCALLERID);
10997             }
10998          } else if (!strcasecmp(v->name, "cid_number")) {
10999             if (!ast_strlen_zero(v->value)) {
11000                ast_string_field_set(user, cid_num, v->value);
11001                ast_set_flag(user, IAX_HASCALLERID);
11002             } else {
11003                ast_string_field_set(user, cid_num, "");
11004                if (ast_strlen_zero(user->cid_name))
11005                   ast_clear_flag(user, IAX_HASCALLERID);
11006             }
11007          } else if (!strcasecmp(v->name, "accountcode")) {
11008             ast_string_field_set(user, accountcode, v->value);
11009          } else if (!strcasecmp(v->name, "mohinterpret")) {
11010             ast_string_field_set(user, mohinterpret, v->value);
11011          } else if (!strcasecmp(v->name, "mohsuggest")) {
11012             ast_string_field_set(user, mohsuggest, v->value);
11013          } else if (!strcasecmp(v->name, "language")) {
11014             ast_string_field_set(user, language, v->value);
11015          } else if (!strcasecmp(v->name, "amaflags")) {
11016             format = ast_cdr_amaflags2int(v->value);
11017             if (format < 0) {
11018                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11019             } else {
11020                user->amaflags = format;
11021             }
11022          } else if (!strcasecmp(v->name, "inkeys")) {
11023             ast_string_field_set(user, inkeys, v->value);
11024          } else if (!strcasecmp(v->name, "maxauthreq")) {
11025             user->maxauthreq = atoi(v->value);
11026             if (user->maxauthreq < 0)
11027                user->maxauthreq = 0;
11028          } else if (!strcasecmp(v->name, "adsi")) {
11029             user->adsi = ast_true(v->value);
11030          }/* else if (strcasecmp(v->name,"type")) */
11031          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11032          v = v->next;
11033          if (!v) {
11034             v = alt;
11035             alt = NULL;
11036          }
11037       }
11038       if (!user->authmethods) {
11039          if (!ast_strlen_zero(user->secret)) {
11040             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11041             if (!ast_strlen_zero(user->inkeys))
11042                user->authmethods |= IAX_AUTH_RSA;
11043          } else if (!ast_strlen_zero(user->inkeys)) {
11044             user->authmethods = IAX_AUTH_RSA;
11045          } else {
11046             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11047          }
11048       }
11049       ast_clear_flag(user, IAX_DELME);
11050    }
11051 cleanup:
11052    if (oldha)
11053       ast_free_ha(oldha);
11054    if (oldcon)
11055       free_context(oldcon);
11056    return user;
11057 }
11058 
11059 static int peer_delme_cb(void *obj, void *arg, int flags)
11060 {
11061    struct iax2_peer *peer = obj;
11062 
11063    ast_set_flag(peer, IAX_DELME);
11064 
11065    return 0;
11066 }
11067 
11068 static int user_delme_cb(void *obj, void *arg, int flags)
11069 {
11070    struct iax2_user *user = obj;
11071 
11072    ast_set_flag(user, IAX_DELME);
11073 
11074    return 0;
11075 }
11076 
11077 static void delete_users(void)
11078 {
11079    struct iax2_registry *reg;
11080 
11081    ao2_callback(users, 0, user_delme_cb, NULL);
11082 
11083    AST_LIST_LOCK(&registrations);
11084    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
11085       AST_SCHED_DEL(sched, reg->expire);
11086       if (reg->callno) {
11087          int callno = reg->callno;
11088          ast_mutex_lock(&iaxsl[callno]);
11089          if (iaxs[callno]) {
11090             iaxs[callno]->reg = NULL;
11091             iax2_destroy(callno);
11092          }
11093          ast_mutex_unlock(&iaxsl[callno]);
11094       }
11095       if (reg->dnsmgr)
11096          ast_dnsmgr_release(reg->dnsmgr);
11097       ast_free(reg);
11098    }
11099    AST_LIST_UNLOCK(&registrations);
11100 
11101    ao2_callback(peers, 0, peer_delme_cb, NULL);
11102 }
11103 
11104 static void prune_users(void)
11105 {
11106    struct iax2_user *user;
11107    struct ao2_iterator i;
11108 
11109    i = ao2_iterator_init(users, 0);
11110    while ((user = ao2_iterator_next(&i))) {
11111       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11112          ao2_unlink(users, user);
11113       }
11114       user_unref(user);
11115    }
11116 }
11117 
11118 /* Prune peers who still are supposed to be deleted */
11119 static void prune_peers(void)
11120 {
11121    struct iax2_peer *peer;
11122    struct ao2_iterator i;
11123 
11124    i = ao2_iterator_init(peers, 0);
11125    while ((peer = ao2_iterator_next(&i))) {
11126       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11127          unlink_peer(peer);
11128       }
11129       peer_unref(peer);
11130    }
11131 }
11132 
11133 static void set_timing(void)
11134 {
11135 #ifdef HAVE_DAHDI
11136    int bs = trunkfreq * 8;
11137    if (timingfd > -1) {
11138       if (
11139 #ifdef DAHDI_TIMERACK
11140          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
11141 #endif         
11142          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
11143          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
11144    }
11145 #endif
11146 }
11147 
11148 static void set_config_destroy(void)
11149 {
11150    strcpy(accountcode, "");
11151    strcpy(language, "");
11152    strcpy(mohinterpret, "default");
11153    strcpy(mohsuggest, "");
11154    trunkmaxsize = MAX_TRUNKDATA;
11155    amaflags = 0;
11156    delayreject = 0;
11157    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
11158    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11159    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
11160    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
11161    delete_users();
11162 }
11163 
11164 /*! \brief Load configuration */
11165 static int set_config(char *config_file, int reload)
11166 {
11167    struct ast_config *cfg, *ucfg;
11168    int capability=iax2_capability;
11169    struct ast_variable *v;
11170    char *cat;
11171    const char *utype;
11172    const char *tosval;
11173    int format;
11174    int portno = IAX_DEFAULT_PORTNO;
11175    int  x;
11176    int mtuv; 
11177    struct iax2_user *user;
11178    struct iax2_peer *peer;
11179    struct ast_netsock *ns;
11180    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11181 #if 0
11182    static unsigned short int last_port=0;
11183 #endif
11184 
11185    cfg = ast_config_load(config_file, config_flags);
11186 
11187    if (!cfg) {
11188       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11189       return -1;
11190    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
11191       ucfg = ast_config_load("users.conf", config_flags);
11192       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
11193          return 0;
11194       /* Otherwise we need to reread both files */
11195       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11196       cfg = ast_config_load(config_file, config_flags);
11197    } else { /* iax.conf changed, gotta reread users.conf, too */
11198       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11199       ucfg = ast_config_load("users.conf", config_flags);
11200    }
11201 
11202    if (reload) {
11203       set_config_destroy();
11204    }
11205 
11206    /* Reset global codec prefs */   
11207    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11208    
11209    /* Reset Global Flags */
11210    memset(&globalflags, 0, sizeof(globalflags));
11211    ast_set_flag(&globalflags, IAX_RTUPDATE);
11212 
11213 #ifdef SO_NO_CHECK
11214    nochecksums = 0;
11215 #endif
11216 
11217    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11218    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11219    global_max_trunk_mtu = MAX_TRUNK_MTU;
11220 
11221    maxauthreq = 3;
11222 
11223    srvlookup = 0;
11224 
11225    v = ast_variable_browse(cfg, "general");
11226 
11227    /* Seed initial tos value */
11228    tosval = ast_variable_retrieve(cfg, "general", "tos");
11229    if (tosval) {
11230       if (ast_str2tos(tosval, &tos))
11231          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
11232    }
11233    /* Seed initial cos value */
11234    tosval = ast_variable_retrieve(cfg, "general", "cos");
11235    if (tosval) {
11236       if (ast_str2cos(tosval, &cos))
11237          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
11238    }
11239    while(v) {
11240       if (!strcasecmp(v->name, "bindport")){ 
11241          if (reload)
11242             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11243          else
11244             portno = atoi(v->value);
11245       } else if (!strcasecmp(v->name, "pingtime")) 
11246          ping_time = atoi(v->value);
11247       else if (!strcasecmp(v->name, "iaxthreadcount")) {
11248          if (reload) {
11249             if (atoi(v->value) != iaxthreadcount)
11250                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11251          } else {
11252             iaxthreadcount = atoi(v->value);
11253             if (iaxthreadcount < 1) {
11254                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11255                iaxthreadcount = 1;
11256             } else if (iaxthreadcount > 256) {
11257                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11258                iaxthreadcount = 256;
11259             }
11260          }
11261       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11262          if (reload) {
11263             AST_LIST_LOCK(&dynamic_list);
11264             iaxmaxthreadcount = atoi(v->value);
11265             AST_LIST_UNLOCK(&dynamic_list);
11266          } else {
11267             iaxmaxthreadcount = atoi(v->value);
11268             if (iaxmaxthreadcount < 0) {
11269                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11270                iaxmaxthreadcount = 0;
11271             } else if (iaxmaxthreadcount > 256) {
11272                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11273                iaxmaxthreadcount = 256;
11274             }
11275          }
11276       } else if (!strcasecmp(v->name, "nochecksums")) {
11277 #ifdef SO_NO_CHECK
11278          if (ast_true(v->value))
11279             nochecksums = 1;
11280          else
11281             nochecksums = 0;
11282 #else
11283          if (ast_true(v->value))
11284             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11285 #endif
11286       }
11287       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
11288          maxjitterbuffer = atoi(v->value);
11289       else if (!strcasecmp(v->name, "resyncthreshold")) 
11290          resyncthreshold = atoi(v->value);
11291       else if (!strcasecmp(v->name, "maxjitterinterps")) 
11292          maxjitterinterps = atoi(v->value);
11293       else if (!strcasecmp(v->name, "jittertargetextra"))
11294          jittertargetextra = atoi(v->value);
11295       else if (!strcasecmp(v->name, "lagrqtime")) 
11296          lagrq_time = atoi(v->value);
11297       else if (!strcasecmp(v->name, "maxregexpire")) 
11298          max_reg_expire = atoi(v->value);
11299       else if (!strcasecmp(v->name, "minregexpire")) 
11300          min_reg_expire = atoi(v->value);
11301       else if (!strcasecmp(v->name, "bindaddr")) {
11302          if (reload) {
11303             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11304          } else {
11305             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, cos, socket_read, NULL))) {
11306                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11307             } else {
11308                   if (strchr(v->value, ':'))
11309                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
11310                   else
11311                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
11312                if (defaultsockfd < 0) 
11313                   defaultsockfd = ast_netsock_sockfd(ns);
11314                ast_netsock_unref(ns);
11315             }
11316          }
11317       } else if (!strcasecmp(v->name, "authdebug"))
11318          authdebug = ast_true(v->value);
11319       else if (!strcasecmp(v->name, "encryption"))
11320          iax2_encryption = get_encrypt_methods(v->value);
11321       else if (!strcasecmp(v->name, "transfer")) {
11322          if (!strcasecmp(v->value, "mediaonly")) {
11323             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
11324          } else if (ast_true(v->value)) {
11325             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11326          } else 
11327             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11328       } else if (!strcasecmp(v->name, "codecpriority")) {
11329          if(!strcasecmp(v->value, "caller"))
11330             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11331          else if(!strcasecmp(v->value, "disabled"))
11332             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11333          else if(!strcasecmp(v->value, "reqonly")) {
11334             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11335             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11336          }
11337       } else if (!strcasecmp(v->name, "jitterbuffer"))
11338          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
11339       else if (!strcasecmp(v->name, "forcejitterbuffer"))
11340          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
11341       else if (!strcasecmp(v->name, "delayreject"))
11342          delayreject = ast_true(v->value);
11343       else if (!strcasecmp(v->name, "allowfwdownload"))
11344          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11345       else if (!strcasecmp(v->name, "rtcachefriends"))
11346          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
11347       else if (!strcasecmp(v->name, "rtignoreregexpire"))
11348          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
11349       else if (!strcasecmp(v->name, "rtupdate"))
11350          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11351       else if (!strcasecmp(v->name, "trunktimestamps"))
11352          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11353       else if (!strcasecmp(v->name, "rtautoclear")) {
11354          int i = atoi(v->value);
11355          if(i > 0)
11356             global_rtautoclear = i;
11357          else
11358             i = 0;
11359          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
11360       } else if (!strcasecmp(v->name, "trunkfreq")) {
11361          trunkfreq = atoi(v->value);
11362          if (trunkfreq < 10)
11363             trunkfreq = 10;
11364       } else if (!strcasecmp(v->name, "trunkmtu")) {
11365          mtuv = atoi(v->value);
11366          if (mtuv  == 0 )  
11367             global_max_trunk_mtu = 0; 
11368          else if (mtuv >= 172 && mtuv < 4000) 
11369             global_max_trunk_mtu = mtuv; 
11370          else 
11371             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
11372                mtuv, v->lineno);
11373       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
11374          trunkmaxsize = atoi(v->value);
11375          if (trunkmaxsize == 0)
11376             trunkmaxsize = MAX_TRUNKDATA;
11377       } else if (!strcasecmp(v->name, "autokill")) {
11378          if (sscanf(v->value, "%d", &x) == 1) {
11379             if (x >= 0)
11380                autokill = x;
11381             else
11382                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11383          } else if (ast_true(v->value)) {
11384             autokill = DEFAULT_MAXMS;
11385          } else {
11386             autokill = 0;
11387          }
11388       } else if (!strcasecmp(v->name, "bandwidth")) {
11389          if (!strcasecmp(v->value, "low")) {
11390             capability = IAX_CAPABILITY_LOWBANDWIDTH;
11391          } else if (!strcasecmp(v->value, "medium")) {
11392             capability = IAX_CAPABILITY_MEDBANDWIDTH;
11393          } else if (!strcasecmp(v->value, "high")) {
11394             capability = IAX_CAPABILITY_FULLBANDWIDTH;
11395          } else
11396             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11397       } else if (!strcasecmp(v->name, "allow")) {
11398          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11399       } else if (!strcasecmp(v->name, "disallow")) {
11400          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11401       } else if (!strcasecmp(v->name, "register")) {
11402          iax2_register(v->value, v->lineno);
11403       } else if (!strcasecmp(v->name, "iaxcompat")) {
11404          iaxcompat = ast_true(v->value);
11405       } else if (!strcasecmp(v->name, "regcontext")) {
11406          ast_copy_string(regcontext, v->value, sizeof(regcontext));
11407          /* Create context if it doesn't exist already */
11408          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
11409       } else if (!strcasecmp(v->name, "tos")) {
11410          if (ast_str2tos(v->value, &tos))
11411             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
11412       } else if (!strcasecmp(v->name, "cos")) {
11413          if (ast_str2cos(v->value, &cos))
11414             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
11415       } else if (!strcasecmp(v->name, "accountcode")) {
11416          ast_copy_string(accountcode, v->value, sizeof(accountcode));
11417       } else if (!strcasecmp(v->name, "mohinterpret")) {
11418          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11419       } else if (!strcasecmp(v->name, "mohsuggest")) {
11420          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11421       } else if (!strcasecmp(v->name, "amaflags")) {
11422          format = ast_cdr_amaflags2int(v->value);
11423          if (format < 0) {
11424             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11425          } else {
11426             amaflags = format;
11427          }
11428       } else if (!strcasecmp(v->name, "language")) {
11429          ast_copy_string(language, v->value, sizeof(language));
11430       } else if (!strcasecmp(v->name, "maxauthreq")) {
11431          maxauthreq = atoi(v->value);
11432          if (maxauthreq < 0)
11433             maxauthreq = 0;
11434       } else if (!strcasecmp(v->name, "adsi")) {
11435          adsi = ast_true(v->value);
11436       } else if (!strcasecmp(v->name, "srvlookup")) {
11437          srvlookup = ast_true(v->value);
11438       } /*else if (strcasecmp(v->name,"type")) */
11439       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11440       v = v->next;
11441    }
11442    
11443    if (defaultsockfd < 0) {
11444       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, cos, socket_read, NULL))) {
11445          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11446       } else {
11447          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11448          defaultsockfd = ast_netsock_sockfd(ns);
11449          ast_netsock_unref(ns);
11450       }
11451    }
11452    if (reload) {
11453       ast_netsock_release(outsock);
11454       outsock = ast_netsock_list_alloc();
11455       if (!outsock) {
11456          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11457          return -1;
11458       }
11459       ast_netsock_init(outsock);
11460    }
11461 
11462    if (min_reg_expire > max_reg_expire) {
11463       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11464          min_reg_expire, max_reg_expire, max_reg_expire);
11465       min_reg_expire = max_reg_expire;
11466    }
11467    iax2_capability = capability;
11468    
11469    if (ucfg) {
11470       struct ast_variable *gen;
11471       int genhasiax;
11472       int genregisteriax;
11473       const char *hasiax, *registeriax;
11474       
11475       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11476       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11477       gen = ast_variable_browse(ucfg, "general");
11478       cat = ast_category_browse(ucfg, NULL);
11479       while (cat) {
11480          if (strcasecmp(cat, "general")) {
11481             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11482             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11483             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11484                /* Start with general parameters, then specific parameters, user and peer */
11485                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11486                if (user) {
11487                   ao2_link(users, user);
11488                   user = user_unref(user);
11489                }
11490                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11491                if (peer) {
11492                   if (ast_test_flag(peer, IAX_DYNAMIC))
11493                      reg_source_db(peer);
11494                   ao2_link(peers, peer);
11495                   peer = peer_unref(peer);
11496                }
11497             }
11498             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11499                char tmp[256];
11500                const char *host = ast_variable_retrieve(ucfg, cat, "host");
11501                const char *username = ast_variable_retrieve(ucfg, cat, "username");
11502                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11503                if (!host)
11504                   host = ast_variable_retrieve(ucfg, "general", "host");
11505                if (!username)
11506                   username = ast_variable_retrieve(ucfg, "general", "username");
11507                if (!secret)
11508                   secret = ast_variable_retrieve(ucfg, "general", "secret");
11509                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11510                   if (!ast_strlen_zero(secret))
11511                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11512                   else
11513                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11514                   iax2_register(tmp, 0);
11515                }
11516             }
11517          }
11518          cat = ast_category_browse(ucfg, cat);
11519       }
11520       ast_config_destroy(ucfg);
11521    }
11522    
11523    cat = ast_category_browse(cfg, NULL);
11524    while(cat) {
11525       if (strcasecmp(cat, "general")) {
11526          utype = ast_variable_retrieve(cfg, cat, "type");
11527          if (utype) {
11528             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11529                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11530                if (user) {
11531                   ao2_link(users, user);
11532                   user = user_unref(user);
11533                }
11534             }
11535             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11536                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11537                if (peer) {
11538                   if (ast_test_flag(peer, IAX_DYNAMIC))
11539                      reg_source_db(peer);
11540                   ao2_link(peers, peer);
11541                   peer = peer_unref(peer);
11542                }
11543             } else if (strcasecmp(utype, "user")) {
11544                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11545             }
11546          } else
11547             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11548       }
11549       cat = ast_category_browse(cfg, cat);
11550    }
11551    ast_config_destroy(cfg);
11552    set_timing();
11553    return 1;
11554 }
11555 
11556 static void poke_all_peers(void)
11557 {
11558    struct ao2_iterator i;
11559    struct iax2_peer *peer;
11560 
11561    i = ao2_iterator_init(peers, 0);
11562    while ((peer = ao2_iterator_next(&i))) {
11563       iax2_poke_peer(peer, 0);
11564       peer_unref(peer);
11565    }
11566 }
11567 static int reload_config(void)
11568 {
11569    char *config = "iax.conf";
11570    struct iax2_registry *reg;
11571 
11572    if (set_config(config, 1) > 0) {
11573       prune_peers();
11574       prune_users();
11575       trunk_timed = trunk_untimed = 0; 
11576       trunk_nmaxmtu = trunk_maxmtu = 0; 
11577 
11578       AST_LIST_LOCK(&registrations);
11579       AST_LIST_TRAVERSE(&registrations, reg, entry)
11580          iax2_do_register(reg);
11581       AST_LIST_UNLOCK(&registrations);
11582 
11583       /* Qualify hosts, too */
11584       poke_all_peers();
11585    }
11586    
11587    reload_firmware(0);
11588    iax_provision_reload(1);
11589 
11590    return 0;
11591 }
11592 
11593 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11594 {
11595    switch (cmd) {
11596    case CLI_INIT:
11597       e->command = "iax2 reload";
11598       e->usage =
11599          "Usage: iax2 reload\n"
11600          "       Reloads IAX configuration from iax.conf\n";
11601       return NULL;
11602    case CLI_GENERATE:
11603       return NULL;
11604    }
11605 
11606    reload_config();
11607 
11608    return CLI_SUCCESS;
11609 }
11610 
11611 static int reload(void)
11612 {
11613    return reload_config();
11614 }
11615 
11616 static int cache_get_callno_locked(const char *data)
11617 {
11618    struct sockaddr_in sin;
11619    int x;
11620    int callno;
11621    struct iax_ie_data ied;
11622    struct create_addr_info cai;
11623    struct parsed_dial_string pds;
11624    char *tmpstr;
11625 
11626    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11627       /* Look for an *exact match* call.  Once a call is negotiated, it can only
11628          look up entries for a single context */
11629       if (!ast_mutex_trylock(&iaxsl[x])) {
11630          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11631             return x;
11632          ast_mutex_unlock(&iaxsl[x]);
11633       }
11634    }
11635 
11636    /* No match found, we need to create a new one */
11637 
11638    memset(&cai, 0, sizeof(cai));
11639    memset(&ied, 0, sizeof(ied));
11640    memset(&pds, 0, sizeof(pds));
11641 
11642    tmpstr = ast_strdupa(data);
11643    parse_dial_string(tmpstr, &pds);
11644 
11645    if (ast_strlen_zero(pds.peer)) {
11646       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11647       return -1;
11648    }
11649 
11650    /* Populate our address from the given */
11651    if (create_addr(pds.peer, NULL, &sin, &cai))
11652       return -1;
11653 
11654    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
11655       pds.peer, pds.username, pds.password, pds.context);
11656 
11657    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11658    if (callno < 1) {
11659       ast_log(LOG_WARNING, "Unable to create call\n");
11660       return -1;
11661    }
11662 
11663    ast_string_field_set(iaxs[callno], dproot, data);
11664    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11665 
11666    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11667    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11668    /* the string format is slightly different from a standard dial string,
11669       because the context appears in the 'exten' position
11670    */
11671    if (pds.exten)
11672       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11673    if (pds.username)
11674       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11675    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11676    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11677    /* Keep password handy */
11678    if (pds.password)
11679       ast_string_field_set(iaxs[callno], secret, pds.password);
11680    if (pds.key)
11681       ast_string_field_set(iaxs[callno], outkey, pds.key);
11682    /* Start the call going */
11683    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11684 
11685    return callno;
11686 }
11687 
11688 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
11689 {
11690    struct iax2_dpcache *dp = NULL;
11691    struct timeval tv = ast_tvnow();
11692    int x, com[2], timeout, old = 0, outfd, abort, callno;
11693    struct ast_channel *c = NULL;
11694    struct ast_frame *f = NULL;
11695 
11696    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
11697       if (ast_tvcmp(tv, dp->expiry) > 0) {
11698          AST_LIST_REMOVE_CURRENT(cache_list);
11699          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
11700             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
11701          else
11702             ast_free(dp);
11703          continue;
11704       }
11705       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
11706          break;
11707    }
11708    AST_LIST_TRAVERSE_SAFE_END;
11709 
11710    if (!dp) {
11711       /* No matching entry.  Create a new one. */
11712       /* First, can we make a callno? */
11713       if ((callno = cache_get_callno_locked(data)) < 0) {
11714          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11715          return NULL;
11716       }
11717       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11718          ast_mutex_unlock(&iaxsl[callno]);
11719          return NULL;
11720       }
11721       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11722       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11723       dp->expiry = ast_tvnow();
11724       dp->orig = dp->expiry;
11725       /* Expires in 30 mins by default */
11726       dp->expiry.tv_sec += iaxdefaultdpcache;
11727       dp->flags = CACHE_FLAG_PENDING;
11728       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
11729          dp->waiters[x] = -1;
11730       /* Insert into the lists */
11731       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
11732       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
11733       /* Send the request if we're already up */
11734       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11735          iax2_dprequest(dp, callno);
11736       ast_mutex_unlock(&iaxsl[callno]);
11737    }
11738 
11739    /* By here we must have a dp */
11740    if (dp->flags & CACHE_FLAG_PENDING) {
11741       /* Okay, here it starts to get nasty.  We need a pipe now to wait
11742          for a reply to come back so long as it's pending */
11743       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11744          /* Find an empty slot */
11745          if (dp->waiters[x] < 0)
11746             break;
11747       }
11748       if (x >= ARRAY_LEN(dp->waiters)) {
11749          ast_log(LOG_WARNING, "No more waiter positions available\n");
11750          return NULL;
11751       }
11752       if (pipe(com)) {
11753          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11754          return NULL;
11755       }
11756       dp->waiters[x] = com[1];
11757       /* Okay, now we wait */
11758       timeout = iaxdefaulttimeout * 1000;
11759       /* Temporarily unlock */
11760       AST_LIST_UNLOCK(&dpcache);
11761       /* Defer any dtmf */
11762       if (chan)
11763          old = ast_channel_defer_dtmf(chan);
11764       abort = 0;
11765       while(timeout) {
11766          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11767          if (outfd > -1)
11768             break;
11769          if (!c)
11770             continue;
11771          if (!(f = ast_read(c))) {
11772             abort = 1;
11773             break;
11774          }
11775          ast_frfree(f);
11776       }
11777       if (!timeout) {
11778          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11779       }
11780       AST_LIST_LOCK(&dpcache);
11781       dp->waiters[x] = -1;
11782       close(com[1]);
11783       close(com[0]);
11784       if (abort) {
11785          /* Don't interpret anything, just abort.  Not sure what th epoint
11786            of undeferring dtmf on a hung up channel is but hey whatever */
11787          if (!old && chan)
11788             ast_channel_undefer_dtmf(chan);
11789          return NULL;
11790       }
11791       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11792          /* Now to do non-independent analysis the results of our wait */
11793          if (dp->flags & CACHE_FLAG_PENDING) {
11794             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
11795                pending.  Don't let it take as long to timeout. */
11796             dp->flags &= ~CACHE_FLAG_PENDING;
11797             dp->flags |= CACHE_FLAG_TIMEOUT;
11798             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
11799                systems without leaving it unavailable once the server comes back online */
11800             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11801             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11802                if (dp->waiters[x] > -1) {
11803                   if (write(dp->waiters[x], "asdf", 4) < 0) {
11804                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11805                   }
11806                }
11807             }
11808          }
11809       }
11810       /* Our caller will obtain the rest */
11811       if (!old && chan)
11812          ast_channel_undefer_dtmf(chan);
11813    }
11814    return dp;  
11815 }
11816 
11817 /*! \brief Part of the IAX2 switch interface */
11818 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11819 {
11820    int res = 0;
11821    struct iax2_dpcache *dp = NULL;
11822 #if 0
11823    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11824 #endif
11825    if ((priority != 1) && (priority != 2))
11826       return 0;
11827 
11828    AST_LIST_LOCK(&dpcache);
11829    if ((dp = find_cache(chan, data, context, exten, priority))) {
11830       if (dp->flags & CACHE_FLAG_EXISTS)
11831          res = 1;
11832    } else {
11833       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11834    }
11835    AST_LIST_UNLOCK(&dpcache);
11836 
11837    return res;
11838 }
11839 
11840 /*! \brief part of the IAX2 dial plan switch interface */
11841 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11842 {
11843    int res = 0;
11844    struct iax2_dpcache *dp = NULL;
11845 #if 0
11846    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11847 #endif
11848    if ((priority != 1) && (priority != 2))
11849       return 0;
11850 
11851    AST_LIST_LOCK(&dpcache);
11852    if ((dp = find_cache(chan, data, context, exten, priority))) {
11853       if (dp->flags & CACHE_FLAG_CANEXIST)
11854          res = 1;
11855    } else {
11856       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11857    }
11858    AST_LIST_UNLOCK(&dpcache);
11859 
11860    return res;
11861 }
11862 
11863 /*! \brief Part of the IAX2 Switch interface */
11864 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11865 {
11866    int res = 0;
11867    struct iax2_dpcache *dp = NULL;
11868 #if 0
11869    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11870 #endif
11871    if ((priority != 1) && (priority != 2))
11872       return 0;
11873 
11874    AST_LIST_LOCK(&dpcache);
11875    if ((dp = find_cache(chan, data, context, exten, priority))) {
11876       if (dp->flags & CACHE_FLAG_MATCHMORE)
11877          res = 1;
11878    } else {
11879       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11880    }
11881    AST_LIST_UNLOCK(&dpcache);
11882 
11883    return res;
11884 }
11885 
11886 /*! \brief Execute IAX2 dialplan switch */
11887 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11888 {
11889    char odata[256];
11890    char req[256];
11891    char *ncontext;
11892    struct iax2_dpcache *dp = NULL;
11893    struct ast_app *dial = NULL;
11894 #if 0
11895    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);
11896 #endif
11897    if (priority == 2) {
11898       /* Indicate status, can be overridden in dialplan */
11899       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11900       if (dialstatus) {
11901          dial = pbx_findapp(dialstatus);
11902          if (dial) 
11903             pbx_exec(chan, dial, "");
11904       }
11905       return -1;
11906    } else if (priority != 1)
11907       return -1;
11908 
11909    AST_LIST_LOCK(&dpcache);
11910    if ((dp = find_cache(chan, data, context, exten, priority))) {
11911       if (dp->flags & CACHE_FLAG_EXISTS) {
11912          ast_copy_string(odata, data, sizeof(odata));
11913          ncontext = strchr(odata, '/');
11914          if (ncontext) {
11915             *ncontext = '\0';
11916             ncontext++;
11917             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11918          } else {
11919             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11920          }
11921          ast_verb(3, "Executing Dial('%s')\n", req);
11922       } else {
11923          AST_LIST_UNLOCK(&dpcache);
11924          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11925          return -1;
11926       }
11927    }
11928    AST_LIST_UNLOCK(&dpcache);
11929 
11930    if ((dial = pbx_findapp("Dial")))
11931       return pbx_exec(chan, dial, req);
11932    else
11933       ast_log(LOG_WARNING, "No dial application registered\n");
11934 
11935    return -1;
11936 }
11937 
11938 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
11939 {
11940    struct iax2_peer *peer;
11941    char *peername, *colname;
11942 
11943    peername = ast_strdupa(data);
11944 
11945    /* if our channel, return the IP address of the endpoint of current channel */
11946    if (!strcmp(peername,"CURRENTCHANNEL")) {
11947            unsigned short callno;
11948       if (chan->tech != &iax2_tech)
11949          return -1;
11950       callno = PTR_TO_CALLNO(chan->tech_pvt);   
11951       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
11952       return 0;
11953    }
11954 
11955    if ((colname = strchr(peername, ',')))
11956       *colname++ = '\0';
11957    else
11958       colname = "ip";
11959 
11960    if (!(peer = find_peer(peername, 1)))
11961       return -1;
11962 
11963    if (!strcasecmp(colname, "ip")) {
11964       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11965    } else  if (!strcasecmp(colname, "status")) {
11966       peer_status(peer, buf, len); 
11967    } else  if (!strcasecmp(colname, "mailbox")) {
11968       ast_copy_string(buf, peer->mailbox, len);
11969    } else  if (!strcasecmp(colname, "context")) {
11970       ast_copy_string(buf, peer->context, len);
11971    } else  if (!strcasecmp(colname, "expire")) {
11972       snprintf(buf, len, "%d", peer->expire);
11973    } else  if (!strcasecmp(colname, "dynamic")) {
11974       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
11975    } else  if (!strcasecmp(colname, "callerid_name")) {
11976       ast_copy_string(buf, peer->cid_name, len);
11977    } else  if (!strcasecmp(colname, "callerid_num")) {
11978       ast_copy_string(buf, peer->cid_num, len);
11979    } else  if (!strcasecmp(colname, "codecs")) {
11980       ast_getformatname_multiple(buf, len -1, peer->capability);
11981    } else  if (!strncasecmp(colname, "codec[", 6)) {
11982       char *codecnum, *ptr;
11983       int index = 0, codec = 0;
11984       
11985       codecnum = strchr(colname, '[');
11986       *codecnum = '\0';
11987       codecnum++;
11988       if ((ptr = strchr(codecnum, ']'))) {
11989          *ptr = '\0';
11990       }
11991       index = atoi(codecnum);
11992       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11993          ast_copy_string(buf, ast_getformatname(codec), len);
11994       }
11995    }
11996 
11997    peer_unref(peer);
11998 
11999    return 0;
12000 }
12001 
12002 struct ast_custom_function iaxpeer_function = {
12003    .name = "IAXPEER",
12004    .synopsis = "Gets IAX peer information",
12005    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
12006    .read = function_iaxpeer,
12007    .desc = "If peername specified, valid items are:\n"
12008    "- ip (default)          The IP address.\n"
12009    "- status                The peer's status (if qualify=yes)\n"
12010    "- mailbox               The configured mailbox.\n"
12011    "- context               The configured context.\n"
12012    "- expire                The epoch time of the next expire.\n"
12013    "- dynamic               Is it dynamic? (yes/no).\n"
12014    "- callerid_name         The configured Caller ID name.\n"
12015    "- callerid_num          The configured Caller ID number.\n"
12016    "- codecs                The configured codecs.\n"
12017    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
12018    "\n"
12019    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
12020    "\n"
12021 };
12022 
12023 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
12024 {
12025    struct chan_iax2_pvt *pvt;
12026    unsigned int callno;
12027    int res = 0;
12028 
12029    if (!chan || chan->tech != &iax2_tech) {
12030       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12031       return -1;
12032    }
12033 
12034    callno = PTR_TO_CALLNO(chan->tech_pvt);
12035    ast_mutex_lock(&iaxsl[callno]);
12036    if (!(pvt = iaxs[callno])) {
12037       ast_mutex_unlock(&iaxsl[callno]);
12038       return -1;
12039    }
12040 
12041    if (!strcasecmp(args, "osptoken"))
12042       ast_string_field_set(pvt, osptoken, value);
12043    else
12044       res = -1;
12045 
12046    ast_mutex_unlock(&iaxsl[callno]);
12047 
12048    return res;
12049 }
12050 
12051 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
12052 {
12053    struct chan_iax2_pvt *pvt;
12054    unsigned int callno;
12055    int res = 0;
12056 
12057    if (!chan || chan->tech != &iax2_tech) {
12058       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12059       return -1;
12060    }
12061 
12062    callno = PTR_TO_CALLNO(chan->tech_pvt);
12063    ast_mutex_lock(&iaxsl[callno]);
12064    if (!(pvt = iaxs[callno])) {
12065       ast_mutex_unlock(&iaxsl[callno]);
12066       return -1;
12067    }
12068 
12069    if (!strcasecmp(args, "osptoken"))
12070       ast_copy_string(buf, pvt->osptoken, buflen);
12071    else
12072       res = -1;
12073 
12074    ast_mutex_unlock(&iaxsl[callno]);
12075 
12076    return res;
12077 }
12078 
12079 /*! \brief Part of the device state notification system ---*/
12080 static int iax2_devicestate(void *data) 
12081 {
12082    struct parsed_dial_string pds;
12083    char *tmp = ast_strdupa(data);
12084    struct iax2_peer *p;
12085    int res = AST_DEVICE_INVALID;
12086 
12087    memset(&pds, 0, sizeof(pds));
12088    parse_dial_string(tmp, &pds);
12089 
12090    if (ast_strlen_zero(pds.peer)) {
12091       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12092       return res;
12093    }
12094    
12095    ast_debug(3, "Checking device state for device %s\n", pds.peer);
12096 
12097    /* SLD: FIXME: second call to find_peer during registration */
12098    if (!(p = find_peer(pds.peer, 1)))
12099       return res;
12100 
12101    res = AST_DEVICE_UNAVAILABLE;
12102    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12103       pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12104    
12105    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12106        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12107       /* Peer is registered, or have default IP address
12108          and a valid registration */
12109       if (p->historicms == 0 || p->historicms <= p->maxms)
12110          /* let the core figure out whether it is in use or not */
12111          res = AST_DEVICE_UNKNOWN;  
12112    }
12113 
12114    peer_unref(p);
12115 
12116    return res;
12117 }
12118 
12119 static struct ast_switch iax2_switch = 
12120 {
12121    name:        "IAX2",
12122    description: "IAX Remote Dialplan Switch",
12123    exists:      iax2_exists,
12124    canmatch:    iax2_canmatch,
12125    exec:        iax2_exec,
12126    matchmore:   iax2_matchmore,
12127 };
12128 
12129 /*
12130    { { "iax2", "show", "cache", NULL },
12131    iax2_show_cache, "Display IAX cached dialplan",
12132    show_cache_usage },
12133 
12134    { { "iax2", "show", "channels", NULL },
12135    iax2_show_channels, "List active IAX channels",
12136    show_channels_usage },
12137 
12138    { { "iax2", "show", "firmware", NULL },
12139    iax2_show_firmware, "List available IAX firmwares",
12140    show_firmware_usage },
12141 
12142    { { "iax2", "show", "netstats", NULL },
12143    iax2_show_netstats, "List active IAX channel netstats",
12144    show_netstats_usage },
12145 
12146    { { "iax2", "show", "peers", NULL },
12147    iax2_show_peers, "List defined IAX peers",
12148    show_peers_usage },
12149 
12150    { { "iax2", "show", "registry", NULL },
12151    iax2_show_registry, "Display IAX registration status",
12152    show_reg_usage },
12153 
12154    { { "iax2", "show", "stats", NULL },
12155    iax2_show_stats, "Display IAX statistics",
12156    show_stats_usage },
12157 
12158    { { "iax2", "show", "threads", NULL },
12159    iax2_show_threads, "Display IAX helper thread info",
12160    show_threads_usage },
12161 
12162    { { "iax2", "unregister", NULL },
12163    iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry",
12164    unregister_usage, complete_iax2_unregister },
12165 
12166    { { "iax2", "set", "mtu", NULL },
12167    iax2_set_mtu, "Set the IAX systemwide trunking MTU",
12168    set_mtu_usage, NULL, NULL },
12169 
12170    { { "iax2", "show", "users", NULL },
12171    iax2_show_users, "List defined IAX users",
12172    show_users_usage },
12173 
12174    { { "iax2", "prune", "realtime", NULL },
12175    iax2_prune_realtime, "Prune a cached realtime lookup",
12176    prune_realtime_usage, complete_iax2_show_peer },
12177 
12178    { { "iax2", "reload", NULL },
12179    iax2_reload, "Reload IAX configuration",
12180    iax2_reload_usage },
12181 
12182    { { "iax2", "show", "peer", NULL },
12183    iax2_show_peer, "Show details on specific IAX peer",
12184    show_peer_usage, complete_iax2_show_peer },
12185 
12186    { { "iax2", "set", "debug", NULL },
12187    iax2_do_debug, "Enable IAX debugging",
12188    debug_usage },
12189 
12190    { { "iax2", "set", "debug", "trunk", NULL },
12191    iax2_do_trunk_debug, "Enable IAX trunk debugging",
12192    debug_trunk_usage },
12193 
12194    { { "iax2", "set", "debug", "jb", NULL },
12195    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
12196    debug_jb_usage },
12197 
12198    { { "iax2", "set", "debug", "off", NULL },
12199    iax2_no_debug, "Disable IAX debugging",
12200    no_debug_usage },
12201 
12202    { { "iax2", "set", "debug", "trunk", "off", NULL },
12203    iax2_no_trunk_debug, "Disable IAX trunk debugging",
12204    no_debug_trunk_usage },
12205 
12206    { { "iax2", "set", "debug", "jb", "off", NULL },
12207    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
12208    no_debug_jb_usage },
12209 
12210    { { "iax2", "test", "losspct", NULL },
12211    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
12212    iax2_test_losspct_usage },
12213 
12214    { { "iax2", "provision", NULL },
12215    iax2_prov_cmd, "Provision an IAX device",
12216    show_prov_usage, iax2_prov_complete_template_3rd },
12217 
12218 #ifdef IAXTESTS
12219    { { "iax2", "test", "late", NULL },
12220    iax2_test_late, "Test the receipt of a late frame",
12221    iax2_test_late_usage },
12222 
12223    { { "iax2", "test", "resync", NULL },
12224    iax2_test_resync, "Test a resync in received timestamps",
12225    iax2_test_resync_usage },
12226 
12227    { { "iax2", "test", "jitter", NULL },
12228    iax2_test_jitter, "Simulates jitter for testing",
12229    iax2_test_jitter_usage },
12230 #endif
12231 */
12232 
12233 static struct ast_cli_entry cli_iax2_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_deprecated, "Enable/Disable IAX debugging");
12234 static struct ast_cli_entry cli_iax2_set_debug_trunk_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk_deprecated, "Enable/Disable IAX debugging");
12235 static struct ast_cli_entry cli_iax2_set_debug_jb_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb_deprecated, "Enable/Disable IAX debugging");
12236 
12237 static struct ast_cli_entry cli_iax2[] = {
12238    AST_CLI_DEFINE(handle_cli_iax2_provision,           "Provision an IAX device"),
12239    AST_CLI_DEFINE(handle_cli_iax2_prune_realtime,      "Prune a cached realtime lookup"),
12240    AST_CLI_DEFINE(handle_cli_iax2_reload,              "Reload IAX configuration"),
12241    AST_CLI_DEFINE(handle_cli_iax2_set_mtu,             "Set the IAX systemwide trunking MTU"),
12242    AST_CLI_DEFINE(handle_cli_iax2_set_debug,           "Enable/Disable IAX debugging", .deprecate_cmd = &cli_iax2_set_debug_deprecated),
12243    AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk,     "Enable/Disable IAX trunk debugging", .deprecate_cmd = &cli_iax2_set_debug_trunk_deprecated),
12244    AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb,        "Enable/Disable IAX jitterbuffer debugging", .deprecate_cmd = &cli_iax2_set_debug_jb_deprecated),
12245    AST_CLI_DEFINE(handle_cli_iax2_show_cache,          "Display IAX cached dialplan"),
12246    AST_CLI_DEFINE(handle_cli_iax2_show_channels,       "List active IAX channels"),
12247    AST_CLI_DEFINE(handle_cli_iax2_show_firmware,       "List available IAX firmware"),
12248    AST_CLI_DEFINE(handle_cli_iax2_show_netstats,       "List active IAX channel netstats"),
12249    AST_CLI_DEFINE(handle_cli_iax2_show_peer,           "Show details on specific IAX peer"),
12250    AST_CLI_DEFINE(handle_cli_iax2_show_peers,          "List defined IAX peers"),
12251    AST_CLI_DEFINE(handle_cli_iax2_show_registry,       "Display IAX registration status"),
12252    AST_CLI_DEFINE(handle_cli_iax2_show_stats,          "Display IAX statistics"),
12253    AST_CLI_DEFINE(handle_cli_iax2_show_threads,        "Display IAX helper thread info"),
12254    AST_CLI_DEFINE(handle_cli_iax2_show_users,          "List defined IAX users"),
12255    AST_CLI_DEFINE(handle_cli_iax2_test_losspct,        "Set IAX2 incoming frame loss percentage"),
12256    AST_CLI_DEFINE(handle_cli_iax2_unregister,          "Unregister (force expiration) an IAX2 peer from the registry"),
12257 #ifdef IAXTESTS
12258    AST_CLI_DEFINE(handle_cli_iax2_test_jitter,         "Simulates jitter for testing"),
12259    AST_CLI_DEFINE(handle_cli_iax2_test_late,           "Test the receipt of a late frame"),
12260    AST_CLI_DEFINE(handle_cli_iax2_test_resync,         "Test a resync in received timestamps"),
12261 #endif /* IAXTESTS */
12262 };
12263 
12264 static int __unload_module(void)
12265 {
12266    struct iax2_thread *thread = NULL;
12267    struct ast_context *con;
12268    int x;
12269 
12270    /* Make sure threads do not hold shared resources when they are canceled */
12271    
12272    /* Grab the sched lock resource to keep it away from threads about to die */
12273    /* Cancel the network thread, close the net socket */
12274    if (netthreadid != AST_PTHREADT_NULL) {
12275       AST_LIST_LOCK(&frame_queue);
12276       ast_mutex_lock(&sched_lock);
12277       pthread_cancel(netthreadid);
12278       ast_cond_signal(&sched_cond);
12279       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
12280       AST_LIST_UNLOCK(&frame_queue);
12281       pthread_join(netthreadid, NULL);
12282    }
12283    if (schedthreadid != AST_PTHREADT_NULL) {
12284       ast_mutex_lock(&sched_lock);
12285       pthread_cancel(schedthreadid);
12286       ast_cond_signal(&sched_cond);
12287       ast_mutex_unlock(&sched_lock);
12288       pthread_join(schedthreadid, NULL);
12289    }
12290 
12291    /* Call for all threads to halt */
12292    AST_LIST_LOCK(&idle_list);
12293    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
12294       pthread_cancel(thread->threadid);
12295    AST_LIST_UNLOCK(&idle_list);
12296 
12297    AST_LIST_LOCK(&active_list);
12298    while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
12299       pthread_cancel(thread->threadid);
12300    AST_LIST_UNLOCK(&active_list);
12301 
12302    AST_LIST_LOCK(&dynamic_list);
12303    while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
12304       pthread_cancel(thread->threadid);
12305    AST_LIST_UNLOCK(&dynamic_list);
12306    
12307    /* Wait for threads to exit */
12308    while(0 < iaxactivethreadcount)
12309       usleep(10000);
12310    
12311    ast_netsock_release(netsock);
12312    ast_netsock_release(outsock);
12313    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12314       if (iaxs[x]) {
12315          iax2_destroy(x);
12316       }
12317    }
12318    ast_manager_unregister( "IAXpeers" );
12319    ast_manager_unregister( "IAXpeerlist" );
12320    ast_manager_unregister( "IAXnetstats" );
12321    ast_unregister_application(papp);
12322    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12323    ast_unregister_switch(&iax2_switch);
12324    ast_channel_unregister(&iax2_tech);
12325    delete_users();
12326    iax_provision_unload();
12327    sched_context_destroy(sched);
12328    reload_firmware(1);
12329 
12330    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12331       ast_mutex_destroy(&iaxsl[x]);
12332    }
12333 
12334    ao2_ref(peers, -1);
12335    ao2_ref(users, -1);
12336    ao2_ref(iax_peercallno_pvts, -1);
12337    ao2_ref(iax_transfercallno_pvts, -1);  
12338    con = ast_context_find(regcontext);
12339    if (con)
12340       ast_context_destroy(con, "IAX2");
12341    
12342    return 0;
12343 }
12344 
12345 static int unload_module(void)
12346 {
12347    ast_custom_function_unregister(&iaxpeer_function);
12348    ast_custom_function_unregister(&iaxvar_function);
12349    return __unload_module();
12350 }
12351 
12352 static int peer_set_sock_cb(void *obj, void *arg, int flags)
12353 {
12354    struct iax2_peer *peer = obj;
12355 
12356    if (peer->sockfd < 0)
12357       peer->sockfd = defaultsockfd;
12358 
12359    return 0;
12360 }
12361 
12362 static int pvt_hash_cb(const void *obj, const int flags)
12363 {
12364    const struct chan_iax2_pvt *pvt = obj;
12365 
12366    return pvt->peercallno;
12367 }
12368 
12369 static int pvt_cmp_cb(void *obj, void *arg, int flags)
12370 {
12371    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12372 
12373    /* The frames_received field is used to hold whether we're matching
12374     * against a full frame or not ... */
12375 
12376    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
12377       pvt2->frames_received) ? CMP_MATCH : 0;
12378 }
12379 
12380 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
12381 {
12382    const struct chan_iax2_pvt *pvt = obj;
12383 
12384    return pvt->transfercallno;
12385 }
12386 
12387 static int transfercallno_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->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12395       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12396 }
12397 /*! \brief Load IAX2 module, load configuraiton ---*/
12398 static int load_module(void)
12399 {
12400    char *config = "iax.conf";
12401    int x = 0;
12402    struct iax2_registry *reg = NULL;
12403 
12404    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
12405    if (!peers)
12406       return AST_MODULE_LOAD_FAILURE;
12407    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
12408    if (!users) {
12409       ao2_ref(peers, -1);
12410       return AST_MODULE_LOAD_FAILURE;
12411    }
12412    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
12413    if (!iax_peercallno_pvts) {
12414       ao2_ref(peers, -1);
12415       ao2_ref(users, -1);
12416       return AST_MODULE_LOAD_FAILURE;
12417    }
12418    iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
12419    if (!iax_transfercallno_pvts) {
12420       ao2_ref(peers, -1);
12421       ao2_ref(users, -1);
12422       ao2_ref(iax_peercallno_pvts, -1);
12423       return AST_MODULE_LOAD_FAILURE;
12424    }
12425    ast_custom_function_register(&iaxpeer_function);
12426    ast_custom_function_register(&iaxvar_function);
12427 
12428    iax_set_output(iax_debug_output);
12429    iax_set_error(iax_error_output);
12430    jb_setoutput(jb_error_output, jb_warning_output, NULL);
12431    
12432 #ifdef HAVE_DAHDI
12433 #ifdef DAHDI_TIMERACK
12434    timingfd = open("/dev/dahdi/timer", O_RDWR);
12435    if (timingfd < 0)
12436 #endif
12437       timingfd = open("/dev/dahdi/pseudo", O_RDWR);
12438    if (timingfd < 0) 
12439       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
12440 #endif      
12441 
12442    memset(iaxs, 0, sizeof(iaxs));
12443 
12444    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12445       ast_mutex_init(&iaxsl[x]);
12446    }
12447 
12448    ast_cond_init(&sched_cond, NULL);
12449 
12450    if (!(sched = sched_context_create())) {
12451       ast_log(LOG_ERROR, "Failed to create scheduler context\n");
12452       return AST_MODULE_LOAD_FAILURE;
12453    }
12454 
12455    if (!(io = io_context_create())) {
12456       ast_log(LOG_ERROR, "Failed to create I/O context\n");
12457       sched_context_destroy(sched);
12458       return AST_MODULE_LOAD_FAILURE;
12459    }
12460 
12461    if (!(netsock = ast_netsock_list_alloc())) {
12462       ast_log(LOG_ERROR, "Failed to create netsock list\n");
12463       io_context_destroy(io);
12464       sched_context_destroy(sched);
12465       return AST_MODULE_LOAD_FAILURE;
12466    }
12467    ast_netsock_init(netsock);
12468    
12469    outsock = ast_netsock_list_alloc();
12470    if (!outsock) {
12471       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12472       io_context_destroy(io);
12473       sched_context_destroy(sched);
12474       return AST_MODULE_LOAD_FAILURE;
12475    }
12476    ast_netsock_init(outsock);
12477 
12478    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12479 
12480    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12481    
12482    ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
12483    ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
12484    ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
12485 
12486    if(set_config(config, 0) == -1)
12487       return AST_MODULE_LOAD_DECLINE;
12488 
12489    if (ast_channel_register(&iax2_tech)) {
12490       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12491       __unload_module();
12492       return AST_MODULE_LOAD_FAILURE;
12493    }
12494 
12495    if (ast_register_switch(&iax2_switch)) 
12496       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12497 
12498    if (start_network_thread()) {
12499       ast_log(LOG_ERROR, "Unable to start network thread\n");
12500       __unload_module();
12501       return AST_MODULE_LOAD_FAILURE;
12502    } else
12503       ast_verb(2, "IAX Ready and Listening\n");
12504 
12505    AST_LIST_LOCK(&registrations);
12506    AST_LIST_TRAVERSE(&registrations, reg, entry)
12507       iax2_do_register(reg);
12508    AST_LIST_UNLOCK(&registrations); 
12509    
12510    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12511    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12512 
12513 
12514    reload_firmware(0);
12515    iax_provision_reload(0);
12516 
12517    return AST_MODULE_LOAD_SUCCESS;
12518 }
12519 
12520 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
12521       .load = load_module,
12522       .unload = unload_module,
12523       .reload = reload,
12524       );

Generated on Thu Jul 9 13:40:27 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7