Fri Apr 24 16:25:52 2009

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>dahdi</use>
00033         <depend>res_features</depend>
00034  ***/
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 178838 $")
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061 
00062 #if defined(HAVE_ZAPTEL) || defined (HAVE_DAHDI)
00063 #include <sys/ioctl.h>
00064 #include "asterisk/dahdi_compat.h"
00065 #endif
00066 
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h" 
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099 
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104 
00105 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00106    multithreaded mode. */
00107 #define SCHED_MULTITHREADED
00108 
00109 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00110    thread is actually doing. */
00111 #define DEBUG_SCHED_MULTITHREAD
00112 
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116 
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120 
00121 
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124 
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130 
00131 #define DEBUG_SUPPORT
00132 
00133 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00134 
00135 /* Sample over last 100 units to determine historic jitter */
00136 #define GAMMA (0.01)
00137 
00138 static struct ast_codec_pref prefs;
00139 
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00141 
00142 static char context[80] = "default";
00143 
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146 
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158 static int last_authmethod = 0;
00159 
00160 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00161 
00162 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00163 
00164 static unsigned int tos = 0;
00165 
00166 static int min_reg_expire;
00167 static int max_reg_expire;
00168 
00169 static int timingfd = -1;           /* Timing file descriptor */
00170 
00171 static struct ast_netsock_list *netsock;
00172 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00173 static int defaultsockfd = -1;
00174 
00175 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00176 
00177 /* Ethernet, etc */
00178 #define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00179 /* T1, maybe ISDN */
00180 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00181                 ~AST_FORMAT_SLINEAR &        \
00182                 ~AST_FORMAT_ULAW &        \
00183                 ~AST_FORMAT_ALAW &        \
00184                 ~AST_FORMAT_G722) 
00185 /* A modem */
00186 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00187                 ~AST_FORMAT_G726 &        \
00188                 ~AST_FORMAT_G726_AAL2 &      \
00189                 ~AST_FORMAT_ADPCM)
00190 
00191 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00192                 ~AST_FORMAT_G723_1)
00193 
00194 
00195 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00196 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00197 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00198 
00199 static   struct io_context *io;
00200 static   struct sched_context *sched;
00201 
00202 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00203 
00204 static int iaxdebug = 0;
00205 
00206 static int iaxtrunkdebug = 0;
00207 
00208 static int test_losspct = 0;
00209 #ifdef IAXTESTS
00210 static int test_late = 0;
00211 static int test_resync = 0;
00212 static int test_jit = 0;
00213 static int test_jitpct = 0;
00214 #endif /* IAXTESTS */
00215 
00216 static char accountcode[AST_MAX_ACCOUNT_CODE];
00217 static char mohinterpret[MAX_MUSICCLASS];
00218 static char mohsuggest[MAX_MUSICCLASS];
00219 static int amaflags = 0;
00220 static int adsi = 0;
00221 static int delayreject = 0;
00222 static int iax2_encryption = 0;
00223 
00224 static struct ast_flags globalflags = { 0 };
00225 
00226 static pthread_t netthreadid = AST_PTHREADT_NULL;
00227 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00228 AST_MUTEX_DEFINE_STATIC(sched_lock);
00229 static ast_cond_t sched_cond;
00230 
00231 enum {
00232    IAX_STATE_STARTED =     (1 << 0),
00233    IAX_STATE_AUTHENTICATED =  (1 << 1),
00234    IAX_STATE_TBD =      (1 << 2),
00235    IAX_STATE_UNCHANGED =      (1 << 3),
00236 } iax2_state;
00237 
00238 struct iax2_context {
00239    char context[AST_MAX_CONTEXT];
00240    struct iax2_context *next;
00241 };
00242 
00243 enum {
00244    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00245    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00246    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00247    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00248    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00249    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00250    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00251    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00252         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00253    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00254    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00255    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00256    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00257    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00258    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00259    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00260    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00261    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00262    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00263    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00264    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00265    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00266    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00267    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00268    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00269    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00270                        response, so that we've achieved a three-way handshake with
00271                        them before sending voice or anything else*/
00272    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00273 } iax2_flags;
00274 
00275 static int global_rtautoclear = 120;
00276 
00277 static int reload_config(void);
00278 static int iax2_reload(int fd, int argc, char *argv[]);
00279 
00280 
00281 struct iax2_user {
00282    AST_DECLARE_STRING_FIELDS(
00283       AST_STRING_FIELD(name);
00284       AST_STRING_FIELD(secret);
00285       AST_STRING_FIELD(dbsecret);
00286       AST_STRING_FIELD(accountcode);
00287       AST_STRING_FIELD(mohinterpret);
00288       AST_STRING_FIELD(mohsuggest);
00289       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00290       AST_STRING_FIELD(language);
00291       AST_STRING_FIELD(cid_num);
00292       AST_STRING_FIELD(cid_name);
00293    );
00294    
00295    int authmethods;
00296    int encmethods;
00297    int amaflags;
00298    int adsi;
00299    unsigned int flags;
00300    int capability;
00301    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00302    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00303    struct ast_codec_pref prefs;
00304    struct ast_ha *ha;
00305    struct iax2_context *contexts;
00306    struct ast_variable *vars;
00307 };
00308 
00309 struct iax2_peer {
00310    AST_DECLARE_STRING_FIELDS(
00311       AST_STRING_FIELD(name);
00312       AST_STRING_FIELD(username);
00313       AST_STRING_FIELD(secret);
00314       AST_STRING_FIELD(dbsecret);
00315       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00316 
00317       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00318       AST_STRING_FIELD(context);      /*!< For transfers only */
00319       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00320       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00321       AST_STRING_FIELD(mohinterpret);
00322       AST_STRING_FIELD(mohsuggest);
00323       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00324       /* Suggested caller id if registering */
00325       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00326       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00327       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00328    );
00329    struct ast_codec_pref prefs;
00330    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00331    struct sockaddr_in addr;
00332    int formats;
00333    int sockfd;             /*!< Socket to use for transmission */
00334    struct in_addr mask;
00335    int adsi;
00336    unsigned int flags;
00337 
00338    /* Dynamic Registration fields */
00339    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00340    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00341    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00342 
00343    int expire;             /*!< Schedule entry for expiry */
00344    int expiry;             /*!< How soon to expire */
00345    int capability;               /*!< Capability */
00346 
00347    /* Qualification */
00348    int callno;             /*!< Call number of POKE request */
00349    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00350    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00351    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00352 
00353    int pokefreqok;               /*!< How often to check if the host is up */
00354    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00355    int historicms;               /*!< How long recent average responses took */
00356    int smoothing;             /*!< Sample over how many units to determine historic ms */
00357    
00358    struct ast_ha *ha;
00359 };
00360 
00361 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00362 
00363 static struct iax2_trunk_peer {
00364    ast_mutex_t lock;
00365    int sockfd;
00366    struct sockaddr_in addr;
00367    struct timeval txtrunktime;      /*!< Transmit trunktime */
00368    struct timeval rxtrunktime;      /*!< Receive trunktime */
00369    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00370    struct timeval trunkact;      /*!< Last trunk activity */
00371    unsigned int lastsent;        /*!< Last sent time */
00372    /* Trunk data and length */
00373    unsigned char *trunkdata;
00374    unsigned int trunkdatalen;
00375    unsigned int trunkdataalloc;
00376    struct iax2_trunk_peer *next;
00377    int trunkerror;
00378    int calls;
00379 } *tpeers = NULL;
00380 
00381 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00382 
00383 struct iax_firmware {
00384    struct iax_firmware *next;
00385    int fd;
00386    int mmaplen;
00387    int dead;
00388    struct ast_iax2_firmware_header *fwh;
00389    unsigned char *buf;
00390 };
00391 
00392 enum iax_reg_state {
00393    REG_STATE_UNREGISTERED = 0,
00394    REG_STATE_REGSENT,
00395    REG_STATE_AUTHSENT,
00396    REG_STATE_REGISTERED,
00397    REG_STATE_REJECTED,
00398    REG_STATE_TIMEOUT,
00399    REG_STATE_NOAUTH
00400 };
00401 
00402 enum iax_transfer_state {
00403    TRANSFER_NONE = 0,
00404    TRANSFER_BEGIN,
00405    TRANSFER_READY,
00406    TRANSFER_RELEASED,
00407    TRANSFER_PASSTHROUGH,
00408    TRANSFER_MBEGIN,
00409    TRANSFER_MREADY,
00410    TRANSFER_MRELEASED,
00411    TRANSFER_MPASSTHROUGH,
00412    TRANSFER_MEDIA,
00413    TRANSFER_MEDIAPASS
00414 };
00415 
00416 struct iax2_registry {
00417    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00418    char username[80];
00419    char secret[80];        /*!< Password or key name in []'s */
00420    char random[80];
00421    int expire;          /*!< Sched ID of expiration */
00422    int refresh;            /*!< How often to refresh */
00423    enum iax_reg_state regstate;
00424    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00425    int callno;          /*!< Associated call number if applicable */
00426    struct sockaddr_in us;        /*!< Who the server thinks we are */
00427    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00428    AST_LIST_ENTRY(iax2_registry) entry;
00429 };
00430 
00431 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00432 
00433 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00434 #define MIN_RETRY_TIME     100
00435 #define MAX_RETRY_TIME     10000
00436 
00437 #define MAX_JITTER_BUFFER  50
00438 #define MIN_JITTER_BUFFER  10
00439 
00440 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00441 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00442 
00443 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00444 
00445 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00446 #define TS_GAP_FOR_JB_RESYNC  5000
00447 
00448 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00449 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00450 static int iaxdynamicthreadcount = 0;
00451 static int iaxdynamicthreadnum = 0;
00452 static int iaxactivethreadcount = 0;
00453 
00454 struct iax_rr {
00455    int jitter;
00456    int losspct;
00457    int losscnt;
00458    int packets;
00459    int delay;
00460    int dropped;
00461    int ooo;
00462 };
00463 
00464 struct chan_iax2_pvt {
00465    /*! Socket to send/receive on for this call */
00466    int sockfd;
00467    /*! Last received voice format */
00468    int voiceformat;
00469    /*! Last received video format */
00470    int videoformat;
00471    /*! Last sent voice format */
00472    int svoiceformat;
00473    /*! Last sent video format */
00474    int svideoformat;
00475    /*! What we are capable of sending */
00476    int capability;
00477    /*! Last received timestamp */
00478    unsigned int last;
00479    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00480    unsigned int lastsent;
00481    /*! Timestamp of the last video frame sent */
00482    unsigned int lastvsent;
00483    /*! Next outgoing timestamp if everything is good */
00484    unsigned int nextpred;
00485    /*! True if the last voice we transmitted was not silence/CNG */
00486    int notsilenttx;
00487    /*! Ping time */
00488    unsigned int pingtime;
00489    /*! Max time for initial response */
00490    int maxtime;
00491    /*! Peer Address */
00492    struct sockaddr_in addr;
00493    /*! Actual used codec preferences */
00494    struct ast_codec_pref prefs;
00495    /*! Requested codec preferences */
00496    struct ast_codec_pref rprefs;
00497    /*! Our call number */
00498    unsigned short callno;
00499    /*! Peer callno */
00500    unsigned short peercallno;
00501    /*! Negotiated format, this is only used to remember what format was
00502        chosen for an unauthenticated call so that the channel can get
00503        created later using the right format */
00504    int chosenformat;
00505    /*! Peer selected format */
00506    int peerformat;
00507    /*! Peer capability */
00508    int peercapability;
00509    /*! timeval that we base our transmission on */
00510    struct timeval offset;
00511    /*! timeval that we base our delivery on */
00512    struct timeval rxcore;
00513    /*! The jitterbuffer */
00514         jitterbuf *jb;
00515    /*! active jb read scheduler id */
00516         int jbid;                       
00517    /*! LAG */
00518    int lag;
00519    /*! Error, as discovered by the manager */
00520    int error;
00521    /*! Owner if we have one */
00522    struct ast_channel *owner;
00523    /*! What's our state? */
00524    struct ast_flags state;
00525    /*! Expiry (optional) */
00526    int expiry;
00527    /*! Next outgoing sequence number */
00528    unsigned char oseqno;
00529    /*! Next sequence number they have not yet acknowledged */
00530    unsigned char rseqno;
00531    /*! Next incoming sequence number */
00532    unsigned char iseqno;
00533    /*! Last incoming sequence number we have acknowledged */
00534    unsigned char aseqno;
00535 
00536    AST_DECLARE_STRING_FIELDS(
00537       /*! Peer name */
00538       AST_STRING_FIELD(peer);
00539       /*! Default Context */
00540       AST_STRING_FIELD(context);
00541       /*! Caller ID if available */
00542       AST_STRING_FIELD(cid_num);
00543       AST_STRING_FIELD(cid_name);
00544       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00545       AST_STRING_FIELD(ani);
00546       /*! DNID */
00547       AST_STRING_FIELD(dnid);
00548       /*! RDNIS */
00549       AST_STRING_FIELD(rdnis);
00550       /*! Requested Extension */
00551       AST_STRING_FIELD(exten);
00552       /*! Expected Username */
00553       AST_STRING_FIELD(username);
00554       /*! Expected Secret */
00555       AST_STRING_FIELD(secret);
00556       /*! MD5 challenge */
00557       AST_STRING_FIELD(challenge);
00558       /*! Public keys permitted keys for incoming authentication */
00559       AST_STRING_FIELD(inkeys);
00560       /*! Private key for outgoing authentication */
00561       AST_STRING_FIELD(outkey);
00562       /*! Preferred language */
00563       AST_STRING_FIELD(language);
00564       /*! Hostname/peername for naming purposes */
00565       AST_STRING_FIELD(host);
00566 
00567       AST_STRING_FIELD(dproot);
00568       AST_STRING_FIELD(accountcode);
00569       AST_STRING_FIELD(mohinterpret);
00570       AST_STRING_FIELD(mohsuggest);
00571    );
00572    
00573    /*! permitted authentication methods */
00574    int authmethods;
00575    /*! permitted encryption methods */
00576    int encmethods;
00577    /*! Encryption AES-128 Key */
00578    aes_encrypt_ctx ecx;
00579    /*! Decryption AES-128 Key */
00580    aes_decrypt_ctx dcx;
00581    /*! 32 bytes of semi-random data */
00582    unsigned char semirand[32];
00583    /*! Associated registry */
00584    struct iax2_registry *reg;
00585    /*! Associated peer for poking */
00586    struct iax2_peer *peerpoke;
00587    /*! IAX_ flags */
00588    unsigned int flags;
00589    int adsi;
00590 
00591    /*! Transferring status */
00592    enum iax_transfer_state transferring;
00593    /*! Transfer identifier */
00594    int transferid;
00595    /*! Who we are IAX transfering to */
00596    struct sockaddr_in transfer;
00597    /*! What's the new call number for the transfer */
00598    unsigned short transfercallno;
00599    /*! Transfer decrypt AES-128 Key */
00600    aes_encrypt_ctx tdcx;
00601 
00602    /*! Status of knowledge of peer ADSI capability */
00603    int peeradsicpe;
00604 
00605    /*! Who we are bridged to */
00606    unsigned short bridgecallno;
00607    
00608    int pingid;       /*!< Transmit PING request */
00609    int lagid;        /*!< Retransmit lag request */
00610    int autoid;       /*!< Auto hangup for Dialplan requestor */
00611    int authid;       /*!< Authentication rejection ID */
00612    int authfail;        /*!< Reason to report failure */
00613    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00614    int calling_ton;
00615    int calling_tns;
00616    int calling_pres;
00617    int amaflags;
00618    struct iax2_dpcache *dpentries;
00619    struct ast_variable *vars;
00620    /*! last received remote rr */
00621    struct iax_rr remote_rr;
00622    /*! Current base time: (just for stats) */
00623    int min;
00624    /*! Dropped frame count: (just for stats) */
00625    int frames_dropped;
00626    /*! received frame count: (just for stats) */
00627    int frames_received;
00628 };
00629 
00630 static struct ast_iax2_queue {
00631    AST_LIST_HEAD(, iax_frame) queue;
00632    int count;
00633 } iaxq;
00634 
00635 /*!
00636  * This module will get much higher performance when doing a lot of
00637  * user and peer lookups if the number of buckets is increased from 1.
00638  * However, to maintain old behavior for Asterisk 1.4, these are set to
00639  * 1 by default.  When using multiple buckets, search order through these
00640  * containers is considered random, so you will not be able to depend on
00641  * the order the entires are specified in iax.conf for matching order. */
00642 #ifdef LOW_MEMORY
00643 #define MAX_PEER_BUCKETS 1
00644 /* #define MAX_PEER_BUCKETS 17 */
00645 #else
00646 #define MAX_PEER_BUCKETS 1
00647 /* #define MAX_PEER_BUCKETS 563 */
00648 #endif
00649 static struct ao2_container *peers;
00650 
00651 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00652 static struct ao2_container *users;
00653 
00654 static struct ast_firmware_list {
00655    struct iax_firmware *wares;
00656    ast_mutex_t lock;
00657 } waresl;
00658 
00659 /*! Extension exists */
00660 #define CACHE_FLAG_EXISTS     (1 << 0)
00661 /*! Extension is nonexistent */
00662 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00663 /*! Extension can exist */
00664 #define CACHE_FLAG_CANEXIST      (1 << 2)
00665 /*! Waiting to hear back response */
00666 #define CACHE_FLAG_PENDING    (1 << 3)
00667 /*! Timed out */
00668 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00669 /*! Request transmitted */
00670 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00671 /*! Timeout */
00672 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00673 /*! Matchmore */
00674 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00675 
00676 static struct iax2_dpcache {
00677    char peercontext[AST_MAX_CONTEXT];
00678    char exten[AST_MAX_EXTENSION];
00679    struct timeval orig;
00680    struct timeval expiry;
00681    int flags;
00682    unsigned short callno;
00683    int waiters[256];
00684    struct iax2_dpcache *next;
00685    struct iax2_dpcache *peer; /*!< For linking in peers */
00686 } *dpcache;
00687 
00688 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00689 
00690 static void reg_source_db(struct iax2_peer *p);
00691 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00692 
00693 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00694 
00695 #define IAX_IOSTATE_IDLE      0
00696 #define IAX_IOSTATE_READY     1
00697 #define IAX_IOSTATE_PROCESSING   2
00698 #define IAX_IOSTATE_SCHEDREADY   3
00699 
00700 #define IAX_TYPE_POOL    1
00701 #define IAX_TYPE_DYNAMIC 2
00702 
00703 struct iax2_pkt_buf {
00704    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00705    size_t len;
00706    unsigned char buf[1];
00707 };
00708 
00709 struct iax2_thread {
00710    AST_LIST_ENTRY(iax2_thread) list;
00711    int type;
00712    int iostate;
00713 #ifdef SCHED_MULTITHREADED
00714    void (*schedfunc)(const void *);
00715    const void *scheddata;
00716 #endif
00717 #ifdef DEBUG_SCHED_MULTITHREAD
00718    char curfunc[80];
00719 #endif   
00720    int actions;
00721    pthread_t threadid;
00722    int threadnum;
00723    struct sockaddr_in iosin;
00724    unsigned char readbuf[4096]; 
00725    unsigned char *buf;
00726    ssize_t buf_len;
00727    size_t buf_size;
00728    int iofd;
00729    time_t checktime;
00730    ast_mutex_t lock;
00731    ast_cond_t cond;
00732    unsigned int ready_for_signal:1;
00733    /*! if this thread is processing a full frame,
00734      some information about that frame will be stored
00735      here, so we can avoid dispatching any more full
00736      frames for that callno to other threads */
00737    struct {
00738       unsigned short callno;
00739       struct sockaddr_in sin;
00740       unsigned char type;
00741       unsigned char csub;
00742    } ffinfo;
00743    /*! Queued up full frames for processing.  If more full frames arrive for
00744     *  a call which this thread is already processing a full frame for, they
00745     *  are queued up here. */
00746    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00747 };
00748 
00749 /* Thread lists */
00750 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00751 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00752 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00753 
00754 static void *iax2_process_thread(void *data);
00755 
00756 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00757 {
00758    ast_mutex_lock(lock);
00759    ast_cond_signal(cond);
00760    ast_mutex_unlock(lock);
00761 }
00762 
00763 static void iax_debug_output(const char *data)
00764 {
00765    if (iaxdebug)
00766       ast_verbose("%s", data);
00767 }
00768 
00769 static void iax_error_output(const char *data)
00770 {
00771    ast_log(LOG_WARNING, "%s", data);
00772 }
00773 
00774 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00775 {
00776    va_list args;
00777    char buf[1024];
00778 
00779    va_start(args, fmt);
00780    vsnprintf(buf, 1024, fmt, args);
00781    va_end(args);
00782 
00783    ast_log(LOG_ERROR, "%s", buf);
00784 }
00785 
00786 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00787 {
00788    va_list args;
00789    char buf[1024];
00790 
00791    va_start(args, fmt);
00792    vsnprintf(buf, 1024, fmt, args);
00793    va_end(args);
00794 
00795    ast_log(LOG_WARNING, "%s", buf);
00796 }
00797 
00798 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00799 {
00800    va_list args;
00801    char buf[1024];
00802 
00803    va_start(args, fmt);
00804    vsnprintf(buf, 1024, fmt, args);
00805    va_end(args);
00806 
00807    ast_verbose("%s", buf);
00808 }
00809 
00810 /* XXX We probably should use a mutex when working with this XXX */
00811 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00812 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00813 static struct timeval lastused[ARRAY_LEN(iaxs)];
00814 
00815 /*!
00816  * \brief Another container of iax2_pvt structures
00817  *
00818  * Active IAX2 pvt structs are also stored in this container, if they are a part
00819  * of an active call where we know the remote side's call number.  The reason
00820  * for this is that incoming media frames do not contain our call number.  So,
00821  * instead of having to iterate the entire iaxs array, we use this container to
00822  * look up calls where the remote side is using a given call number.
00823  */
00824 static struct ao2_container *iax_peercallno_pvts;
00825 
00826 /*!
00827  *  * \brief Another container of iax2_pvt structures
00828  *  
00829  *  Active IAX2 pvt stucts used during transfering a call are stored here.  
00830  */
00831 static struct ao2_container *iax_transfercallno_pvts;
00832 
00833 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00834    but keeps the division between trunked and non-trunked better. */
00835 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00836 
00837 static int maxtrunkcall = TRUNK_CALL_START;
00838 static int maxnontrunkcall = 1;
00839 
00840 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);
00841 static int expire_registry(const void *data);
00842 static int iax2_answer(struct ast_channel *c);
00843 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00844 static int iax2_devicestate(void *data);
00845 static int iax2_digit_begin(struct ast_channel *c, char digit);
00846 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00847 static int iax2_do_register(struct iax2_registry *reg);
00848 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00849 static int iax2_hangup(struct ast_channel *c);
00850 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00851 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00852 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00853 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00854 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00855 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00856 static int iax2_sendtext(struct ast_channel *c, const char *text);
00857 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00858 static int iax2_transfer(struct ast_channel *c, const char *dest);
00859 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00860 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00861 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00862 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00863 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00864 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00865 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00866 static struct ast_frame *iax2_read(struct ast_channel *c);
00867 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00868 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00869 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00870 static void prune_peers(void);
00871 static void prune_users(void);
00872 
00873 static const struct ast_channel_tech iax2_tech = {
00874    .type = "IAX2",
00875    .description = tdesc,
00876    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00877    .properties = AST_CHAN_TP_WANTSJITTER,
00878    .requester = iax2_request,
00879    .devicestate = iax2_devicestate,
00880    .send_digit_begin = iax2_digit_begin,
00881    .send_digit_end = iax2_digit_end,
00882    .send_text = iax2_sendtext,
00883    .send_image = iax2_sendimage,
00884    .send_html = iax2_sendhtml,
00885    .call = iax2_call,
00886    .hangup = iax2_hangup,
00887    .answer = iax2_answer,
00888    .read = iax2_read,
00889    .write = iax2_write,
00890    .write_video = iax2_write,
00891    .indicate = iax2_indicate,
00892    .setoption = iax2_setoption,
00893    .bridge = iax2_bridge,
00894    .transfer = iax2_transfer,
00895    .fixup = iax2_fixup,
00896 };
00897 
00898 /* WARNING: insert_idle_thread should only ever be called within the
00899  * context of an iax2_process_thread() thread.
00900  */
00901 static void insert_idle_thread(struct iax2_thread *thread)
00902 {
00903    if (thread->type == IAX_TYPE_DYNAMIC) {
00904       AST_LIST_LOCK(&dynamic_list);
00905       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00906       AST_LIST_UNLOCK(&dynamic_list);
00907    } else {
00908       AST_LIST_LOCK(&idle_list);
00909       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00910       AST_LIST_UNLOCK(&idle_list);
00911    }
00912 
00913    return;
00914 }
00915 
00916 static struct iax2_thread *find_idle_thread(void)
00917 {
00918    pthread_attr_t attr;
00919    struct iax2_thread *thread = NULL;
00920 
00921    /* Pop the head of the list off */
00922    AST_LIST_LOCK(&idle_list);
00923    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00924    AST_LIST_UNLOCK(&idle_list);
00925 
00926    /* If no idle thread is available from the regular list, try dynamic */
00927    if (thread == NULL) {
00928       AST_LIST_LOCK(&dynamic_list);
00929       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00930       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00931       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00932          /* We need to MAKE a thread! */
00933          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00934             thread->threadnum = iaxdynamicthreadnum++;
00935             thread->type = IAX_TYPE_DYNAMIC;
00936             ast_mutex_init(&thread->lock);
00937             ast_cond_init(&thread->cond, NULL);
00938             pthread_attr_init(&attr);
00939             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00940             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00941                free(thread);
00942                thread = NULL;
00943             } else {
00944                /* All went well and the thread is up, so increment our count */
00945                iaxdynamicthreadcount++;
00946                
00947                /* Wait for the thread to be ready before returning it to the caller */
00948                while (!thread->ready_for_signal)
00949                   usleep(1);
00950             }
00951          }
00952       }
00953       AST_LIST_UNLOCK(&dynamic_list);
00954    }
00955 
00956    /* this thread is not processing a full frame (since it is idle),
00957       so ensure that the field for the full frame call number is empty */
00958    if (thread)
00959       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00960 
00961    return thread;
00962 }
00963 
00964 #ifdef SCHED_MULTITHREADED
00965 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00966 {
00967    struct iax2_thread *thread = NULL;
00968    static time_t lasterror;
00969    static time_t t;
00970 
00971    thread = find_idle_thread();
00972 
00973    if (thread != NULL) {
00974       thread->schedfunc = func;
00975       thread->scheddata = data;
00976       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00977 #ifdef DEBUG_SCHED_MULTITHREAD
00978       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00979 #endif
00980       signal_condition(&thread->lock, &thread->cond);
00981       return 0;
00982    }
00983    time(&t);
00984    if (t != lasterror && option_debug) 
00985       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00986    lasterror = t;
00987 
00988    return -1;
00989 }
00990 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00991 #endif
00992 
00993 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00994 {
00995    int res;
00996 
00997    ast_mutex_lock(&sched_lock);
00998    res = ast_sched_add(con, when, callback, data);
00999    ast_cond_signal(&sched_cond);
01000    ast_mutex_unlock(&sched_lock);
01001 
01002    return res;
01003 }
01004 
01005 static int send_ping(const void *data);
01006 
01007 static void __send_ping(const void *data)
01008 {
01009    int callno = (long) data;
01010 
01011    ast_mutex_lock(&iaxsl[callno]);
01012 
01013    if (iaxs[callno]) {
01014       if (iaxs[callno]->peercallno) {
01015          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01016          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01017       } else {
01018          /* I am the schedule, so I'm allowed to do this */
01019          iaxs[callno]->pingid = -1;
01020       }
01021    } else if (option_debug > 0) {
01022       ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01023    }
01024 
01025    ast_mutex_unlock(&iaxsl[callno]);
01026 }
01027 
01028 static int send_ping(const void *data)
01029 {
01030 #ifdef SCHED_MULTITHREADED
01031    if (schedule_action(__send_ping, data))
01032 #endif      
01033       __send_ping(data);
01034 
01035    return 0;
01036 }
01037 
01038 static int get_encrypt_methods(const char *s)
01039 {
01040    int e;
01041    if (!strcasecmp(s, "aes128"))
01042       e = IAX_ENCRYPT_AES128;
01043    else if (ast_true(s))
01044       e = IAX_ENCRYPT_AES128;
01045    else
01046       e = 0;
01047    return e;
01048 }
01049 
01050 static int send_lagrq(const void *data);
01051 
01052 static void __send_lagrq(const void *data)
01053 {
01054    int callno = (long) data;
01055 
01056    ast_mutex_lock(&iaxsl[callno]);
01057 
01058    if (iaxs[callno]) {
01059       if (iaxs[callno]->peercallno) {
01060          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01061          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01062       } else {
01063          /* I am the schedule, so I'm allowed to do this */
01064          iaxs[callno]->lagid = -1;
01065       }
01066    } else {
01067       ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01068    }
01069 
01070    ast_mutex_unlock(&iaxsl[callno]);
01071 }
01072 
01073 static int send_lagrq(const void *data)
01074 {
01075 #ifdef SCHED_MULTITHREADED
01076    if (schedule_action(__send_lagrq, data))
01077 #endif      
01078       __send_lagrq(data);
01079    
01080    return 0;
01081 }
01082 
01083 static unsigned char compress_subclass(int subclass)
01084 {
01085    int x;
01086    int power=-1;
01087    /* If it's 128 or smaller, just return it */
01088    if (subclass < IAX_FLAG_SC_LOG)
01089       return subclass;
01090    /* Otherwise find its power */
01091    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01092       if (subclass & (1 << x)) {
01093          if (power > -1) {
01094             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01095             return 0;
01096          } else
01097             power = x;
01098       }
01099    }
01100    return power | IAX_FLAG_SC_LOG;
01101 }
01102 
01103 static int uncompress_subclass(unsigned char csub)
01104 {
01105    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01106    if (csub & IAX_FLAG_SC_LOG) {
01107       /* special case for 'compressed' -1 */
01108       if (csub == 0xff)
01109          return -1;
01110       else
01111          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01112    }
01113    else
01114       return csub;
01115 }
01116 
01117 /*!
01118  * \note The only member of the peer passed here guaranteed to be set is the name field
01119  */
01120 static int peer_hash_cb(const void *obj, const int flags)
01121 {
01122    const struct iax2_peer *peer = obj;
01123 
01124    return ast_str_hash(peer->name);
01125 }
01126 
01127 /*!
01128  * \note The only member of the peer passed here guaranteed to be set is the name field
01129  */
01130 static int peer_cmp_cb(void *obj, void *arg, int flags)
01131 {
01132    struct iax2_peer *peer = obj, *peer2 = arg;
01133 
01134    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01135 }
01136 
01137 /*!
01138  * \note The only member of the user passed here guaranteed to be set is the name field
01139  */
01140 static int user_hash_cb(const void *obj, const int flags)
01141 {
01142    const struct iax2_user *user = obj;
01143 
01144    return ast_str_hash(user->name);
01145 }
01146 
01147 /*!
01148  * \note The only member of the user passed here guaranteed to be set is the name field
01149  */
01150 static int user_cmp_cb(void *obj, void *arg, int flags)
01151 {
01152    struct iax2_user *user = obj, *user2 = arg;
01153 
01154    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01155 }
01156 
01157 /*!
01158  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01159  *       so do not call it with a pvt lock held.
01160  */
01161 static struct iax2_peer *find_peer(const char *name, int realtime) 
01162 {
01163    struct iax2_peer *peer = NULL;
01164    struct iax2_peer tmp_peer = {
01165       .name = name,
01166    };
01167 
01168    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01169 
01170    /* Now go for realtime if applicable */
01171    if(!peer && realtime)
01172       peer = realtime_peer(name, NULL);
01173 
01174    return peer;
01175 }
01176 
01177 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01178 {
01179    ao2_ref(peer, +1);
01180    return peer;
01181 }
01182 
01183 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01184 {
01185    ao2_ref(peer, -1);
01186    return NULL;
01187 }
01188 
01189 static struct iax2_user *find_user(const char *name)
01190 {
01191    struct iax2_user tmp_user = {
01192       .name = name,
01193    };
01194 
01195    return ao2_find(users, &tmp_user, OBJ_POINTER);
01196 }
01197 
01198 static inline struct iax2_user *user_ref(struct iax2_user *user)
01199 {
01200    ao2_ref(user, +1);
01201    return user;
01202 }
01203 
01204 static inline struct iax2_user *user_unref(struct iax2_user *user)
01205 {
01206    ao2_ref(user, -1);
01207    return NULL;
01208 }
01209 
01210 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01211 {
01212    struct iax2_peer *peer = NULL;
01213    int res = 0;
01214    struct ao2_iterator i;
01215 
01216    i = ao2_iterator_init(peers, 0);
01217    while ((peer = ao2_iterator_next(&i))) {
01218       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01219           (peer->addr.sin_port == sin.sin_port)) {
01220          ast_copy_string(host, peer->name, len);
01221          peer_unref(peer);
01222          res = 1;
01223          break;
01224       }
01225       peer_unref(peer);
01226    }
01227 
01228    if (!peer) {
01229       peer = realtime_peer(NULL, &sin);
01230       if (peer) {
01231          ast_copy_string(host, peer->name, len);
01232          peer_unref(peer);
01233          res = 1;
01234       }
01235    }
01236 
01237    return res;
01238 }
01239 
01240 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01241 {
01242    /* Decrement AUTHREQ count if needed */
01243    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01244       struct iax2_user *user;
01245       struct iax2_user tmp_user = {
01246          .name = pvt->username,
01247       };
01248 
01249       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01250       if (user) {
01251          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01252          user = user_unref(user);       
01253       }
01254 
01255       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01256    }
01257 
01258    /* No more pings or lagrq's */
01259    AST_SCHED_DEL(sched, pvt->pingid);
01260    AST_SCHED_DEL(sched, pvt->lagid);
01261    AST_SCHED_DEL(sched, pvt->autoid);
01262    AST_SCHED_DEL(sched, pvt->authid);
01263    AST_SCHED_DEL(sched, pvt->initid);
01264    AST_SCHED_DEL(sched, pvt->jbid);
01265 }
01266 
01267 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01268 {
01269    if (!pvt->transfercallno) {
01270       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01271       return;
01272    }
01273 
01274    ao2_link(iax_transfercallno_pvts, pvt);
01275 }
01276 
01277 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01278 {
01279    if (!pvt->transfercallno) {
01280       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01281       return;
01282    }
01283 
01284    ao2_unlink(iax_transfercallno_pvts, pvt);
01285 }
01286 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01287 {
01288    if (!pvt->peercallno) {
01289       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01290       return;
01291    }
01292 
01293    ao2_link(iax_peercallno_pvts, pvt);
01294 }
01295 
01296 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01297 {
01298    if (!pvt->peercallno) {
01299       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01300       return;
01301    }
01302 
01303    ao2_unlink(iax_peercallno_pvts, pvt);
01304 }
01305 
01306 static void update_max_trunk(void)
01307 {
01308    int max = TRUNK_CALL_START;
01309    int x;
01310 
01311    /* XXX Prolly don't need locks here XXX */
01312    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01313       if (iaxs[x]) {
01314          max = x + 1;
01315       }
01316    }
01317 
01318    maxtrunkcall = max;
01319    if (option_debug && iaxdebug)
01320       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01321 }
01322 
01323 static void iax2_frame_free(struct iax_frame *fr)
01324 {
01325    AST_SCHED_DEL(sched, fr->retrans);
01326    iax_frame_free(fr);
01327 }
01328 
01329 static void iax2_destroy(int callno)
01330 {
01331    struct chan_iax2_pvt *pvt;
01332    struct ast_channel *owner;
01333 
01334 retry:
01335    pvt = iaxs[callno];
01336    gettimeofday(&lastused[callno], NULL);
01337    
01338    owner = pvt ? pvt->owner : NULL;
01339 
01340    if (owner) {
01341       if (ast_mutex_trylock(&owner->lock)) {
01342          if (option_debug > 2)
01343             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01344          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01345          goto retry;
01346       }
01347    }
01348    if (!owner && iaxs[callno]) {
01349       AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]);
01350       AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]);
01351       iaxs[callno] = NULL;
01352    }
01353 
01354    if (pvt) {
01355       if (!owner) {
01356          pvt->owner = NULL;
01357       } else {
01358          /* If there's an owner, prod it to give up */
01359          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01360           * because we already hold the owner channel lock. */
01361          ast_queue_hangup(owner);
01362       }
01363 
01364       if (pvt->peercallno) {
01365          remove_by_peercallno(pvt);
01366       }
01367 
01368       if (pvt->transfercallno) {
01369          remove_by_transfercallno(pvt);
01370       }
01371 
01372       if (!owner) {
01373          ao2_ref(pvt, -1);
01374          pvt = NULL;
01375       }
01376    }
01377 
01378    if (owner) {
01379       ast_mutex_unlock(&owner->lock);
01380    }
01381 
01382    if (callno & 0x4000) {
01383       update_max_trunk();
01384    }
01385 }
01386 
01387 static int scheduled_destroy(const void *vid)
01388 {
01389    short callno = PTR_TO_CALLNO(vid);
01390    ast_mutex_lock(&iaxsl[callno]);
01391    if (iaxs[callno]) {
01392       if (option_debug) {
01393          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01394       }
01395       iax2_destroy(callno);
01396    }
01397    ast_mutex_unlock(&iaxsl[callno]);
01398    return 0;
01399 }
01400 
01401 static void pvt_destructor(void *obj)
01402 {
01403    struct chan_iax2_pvt *pvt = obj;
01404    struct iax_frame *cur = NULL;
01405 
01406    iax2_destroy_helper(pvt);
01407 
01408    /* Already gone */
01409    ast_set_flag(pvt, IAX_ALREADYGONE); 
01410 
01411    AST_LIST_LOCK(&iaxq.queue);
01412    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01413       /* Cancel any pending transmissions */
01414       if (cur->callno == pvt->callno) { 
01415          cur->retries = -1;
01416       }
01417    }
01418    AST_LIST_UNLOCK(&iaxq.queue);
01419 
01420    if (pvt->reg) {
01421       pvt->reg->callno = 0;
01422    }
01423 
01424    if (!pvt->owner) {
01425       jb_frame frame;
01426       if (pvt->vars) {
01427           ast_variables_destroy(pvt->vars);
01428           pvt->vars = NULL;
01429       }
01430 
01431       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01432          iax2_frame_free(frame.data);
01433       }
01434 
01435       jb_destroy(pvt->jb);
01436       ast_string_field_free_memory(pvt);
01437    }
01438 }
01439 
01440 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01441 {
01442    struct chan_iax2_pvt *tmp;
01443    jb_conf jbconf;
01444 
01445    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01446       return NULL;
01447    }
01448 
01449    if (ast_string_field_init(tmp, 32)) {
01450       ao2_ref(tmp, -1);
01451       tmp = NULL;
01452       return NULL;
01453    }
01454       
01455    tmp->prefs = prefs;
01456    tmp->callno = 0;
01457    tmp->peercallno = 0;
01458    tmp->transfercallno = 0;
01459    tmp->bridgecallno = 0;
01460    tmp->pingid = -1;
01461    tmp->lagid = -1;
01462    tmp->autoid = -1;
01463    tmp->authid = -1;
01464    tmp->initid = -1;
01465 
01466    ast_string_field_set(tmp,exten, "s");
01467    ast_string_field_set(tmp,host, host);
01468 
01469    tmp->jb = jb_new();
01470    tmp->jbid = -1;
01471    jbconf.max_jitterbuf = maxjitterbuffer;
01472    jbconf.resync_threshold = resyncthreshold;
01473    jbconf.max_contig_interp = maxjitterinterps;
01474    jb_setconf(tmp->jb,&jbconf);
01475 
01476    return tmp;
01477 }
01478 
01479 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01480 {
01481    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01482    if (new) {
01483       size_t afdatalen = new->afdatalen;
01484       memcpy(new, fr, sizeof(*new));
01485       iax_frame_wrap(new, &fr->af);
01486       new->afdatalen = afdatalen;
01487       new->data = NULL;
01488       new->datalen = 0;
01489       new->direction = DIRECTION_INGRESS;
01490       new->retrans = -1;
01491    }
01492    return new;
01493 }
01494 
01495 #define NEW_PREVENT  0
01496 #define NEW_ALLOW    1
01497 #define NEW_FORCE    2
01498 
01499 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01500 {
01501    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01502       (cur->addr.sin_port == sin->sin_port)) {
01503       /* This is the main host */
01504       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01505           (check_dcallno ? dcallno == cur->callno : 1) ) {
01506          /* That's us.  Be sure we keep track of the peer call number */
01507          return 1;
01508       }
01509    }
01510    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01511        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01512       /* We're transferring */
01513       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01514          return 1;
01515    }
01516    return 0;
01517 }
01518 
01519 static void update_max_nontrunk(void)
01520 {
01521    int max = 1;
01522    int x;
01523    /* XXX Prolly don't need locks here XXX */
01524    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01525       if (iaxs[x])
01526          max = x + 1;
01527    }
01528    maxnontrunkcall = max;
01529    if (option_debug && iaxdebug)
01530       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01531 }
01532 
01533 static int make_trunk(unsigned short callno, int locked)
01534 {
01535    int x;
01536    int res= 0;
01537    struct timeval now;
01538    if (iaxs[callno]->oseqno) {
01539       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01540       return -1;
01541    }
01542    if (callno & TRUNK_CALL_START) {
01543       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01544       return -1;
01545    }
01546    gettimeofday(&now, NULL);
01547    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01548       ast_mutex_lock(&iaxsl[x]);
01549       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01550          /* Update the two timers that should have been started */
01551          /*!
01552           * \note We delete these before switching the slot, because if
01553           * they fire in the meantime, they will generate a warning.
01554           */
01555          AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01556          AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01557          iaxs[x] = iaxs[callno];
01558          iaxs[x]->callno = x;
01559          iaxs[callno] = NULL;
01560          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01561          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01562          if (locked)
01563             ast_mutex_unlock(&iaxsl[callno]);
01564          res = x;
01565          if (!locked)
01566             ast_mutex_unlock(&iaxsl[x]);
01567          break;
01568       }
01569       ast_mutex_unlock(&iaxsl[x]);
01570    }
01571    if (x >= ARRAY_LEN(iaxs) - 1) {
01572       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01573       return -1;
01574    }
01575    if (option_debug)
01576       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01577    /* We move this call from a non-trunked to a trunked call */
01578    update_max_trunk();
01579    update_max_nontrunk();
01580    return res;
01581 }
01582 
01583 /*!
01584  * \note Calling this function while holding another pvt lock can cause a deadlock.
01585  */
01586 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01587 {
01588    int res = 0;
01589    int x;
01590    struct timeval now;
01591    char host[80];
01592 
01593    if (new <= NEW_ALLOW) {
01594       if (callno) {
01595          struct chan_iax2_pvt *pvt;
01596          struct chan_iax2_pvt tmp_pvt = {
01597             .callno = dcallno,
01598             .peercallno = callno,
01599             .transfercallno = callno,
01600             /* hack!! */
01601             .frames_received = check_dcallno,
01602          };
01603 
01604          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01605          /* this works for finding normal call numbers not involving transfering */ 
01606          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01607             if (return_locked) {
01608                ast_mutex_lock(&iaxsl[pvt->callno]);
01609             }
01610             res = pvt->callno;
01611             ao2_ref(pvt, -1);
01612             pvt = NULL;
01613             return res;
01614          }
01615          /* this searches for transfer call numbers that might not get caught otherwise */
01616          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01617          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01618          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01619             if (return_locked) {
01620                ast_mutex_lock(&iaxsl[pvt->callno]);
01621             }
01622             res = pvt->callno;
01623             ao2_ref(pvt, -1);
01624             pvt = NULL;
01625             return res;
01626          }
01627       }
01628       /* This will occur on the first response to a message that we initiated,
01629        * such as a PING. */
01630       if (dcallno) {
01631          ast_mutex_lock(&iaxsl[dcallno]);
01632       }
01633       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01634          iaxs[dcallno]->peercallno = callno;
01635          res = dcallno;
01636          store_by_peercallno(iaxs[dcallno]);
01637          if (!res || !return_locked) {
01638             ast_mutex_unlock(&iaxsl[dcallno]);
01639          }
01640          return res;
01641       }
01642       if (dcallno) {
01643          ast_mutex_unlock(&iaxsl[dcallno]);
01644       }
01645 #ifdef IAX_OLD_FIND
01646       /* If we get here, we SHOULD NOT find a call structure for this
01647          callno; if we do, it means that there is a call structure that
01648          has a peer callno but did NOT get entered into the hash table,
01649          which is bad.
01650 
01651          If we find a call structure using this old, slow method, output a log
01652          message so we'll know about it. After a few months of leaving this in
01653          place, if we don't hear about people seeing these messages, we can
01654          remove this code for good.
01655       */
01656 
01657       for (x = 1; !res && x < maxnontrunkcall; x++) {
01658          ast_mutex_lock(&iaxsl[x]);
01659          if (iaxs[x]) {
01660             /* Look for an exact match */
01661             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01662                res = x;
01663             }
01664          }
01665          if (!res || !return_locked)
01666             ast_mutex_unlock(&iaxsl[x]);
01667       }
01668 
01669       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01670          ast_mutex_lock(&iaxsl[x]);
01671          if (iaxs[x]) {
01672             /* Look for an exact match */
01673             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01674                res = x;
01675             }
01676          }
01677          if (!res || !return_locked)
01678             ast_mutex_unlock(&iaxsl[x]);
01679       }
01680 
01681       if (res) {
01682          ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
01683       }
01684 #endif
01685    }
01686    if (!res && (new >= NEW_ALLOW)) {
01687       int start, found = 0;
01688 
01689       /* It may seem odd that we look through the peer list for a name for
01690        * this *incoming* call.  Well, it is weird.  However, users don't
01691        * have an IP address/port number that we can match against.  So,
01692        * this is just checking for a peer that has that IP/port and
01693        * assuming that we have a user of the same name.  This isn't always
01694        * correct, but it will be changed if needed after authentication. */
01695       if (!iax2_getpeername(*sin, host, sizeof(host)))
01696          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01697 
01698       now = ast_tvnow();
01699       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01700       for (x = start; 1; x++) {
01701          if (x == TRUNK_CALL_START) {
01702             x = 1;
01703             continue;
01704          }
01705 
01706          /* Find first unused call number that hasn't been used in a while */
01707          ast_mutex_lock(&iaxsl[x]);
01708          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01709             found = 1;
01710             break;
01711          }
01712          ast_mutex_unlock(&iaxsl[x]);
01713          
01714          if (x == start - 1) {
01715             break;
01716          }
01717       }
01718       /* We've still got lock held if we found a spot */
01719       if (x == start - 1 && !found) {
01720          ast_log(LOG_WARNING, "No more space\n");
01721          return 0;
01722       }
01723       iaxs[x] = new_iax(sin, host);
01724       update_max_nontrunk();
01725       if (iaxs[x]) {
01726          if (option_debug && iaxdebug)
01727             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01728          iaxs[x]->sockfd = sockfd;
01729          iaxs[x]->addr.sin_port = sin->sin_port;
01730          iaxs[x]->addr.sin_family = sin->sin_family;
01731          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01732          iaxs[x]->peercallno = callno;
01733          iaxs[x]->callno = x;
01734          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01735          iaxs[x]->expiry = min_reg_expire;
01736          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01737          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01738          iaxs[x]->amaflags = amaflags;
01739          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01740          
01741          ast_string_field_set(iaxs[x], accountcode, accountcode);
01742          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01743          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01744 
01745          if (iaxs[x]->peercallno) {
01746             store_by_peercallno(iaxs[x]);
01747          }
01748       } else {
01749          ast_log(LOG_WARNING, "Out of resources\n");
01750          ast_mutex_unlock(&iaxsl[x]);
01751          return 0;
01752       }
01753       if (!return_locked)
01754          ast_mutex_unlock(&iaxsl[x]);
01755       res = x;
01756    }
01757    return res;
01758 }
01759 
01760 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01761 
01762    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01763 }
01764 
01765 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01766 
01767    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01768 }
01769 
01770 /*!
01771  * \brief Queue a frame to a call's owning asterisk channel
01772  *
01773  * \pre This function assumes that iaxsl[callno] is locked when called.
01774  *
01775  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01776  * was valid before calling it, it may no longer be valid after calling it.
01777  * This function may unlock and lock the mutex associated with this callno,
01778  * meaning that another thread may grab it and destroy the call.
01779  */
01780 static int iax2_queue_frame(int callno, struct ast_frame *f)
01781 {
01782    for (;;) {
01783       if (iaxs[callno] && iaxs[callno]->owner) {
01784          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01785             /* Avoid deadlock by pausing and trying again */
01786             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01787          } else {
01788             ast_queue_frame(iaxs[callno]->owner, f);
01789             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01790             break;
01791          }
01792       } else
01793          break;
01794    }
01795    return 0;
01796 }
01797 
01798 /*!
01799  * \brief Queue a hangup frame on the ast_channel owner
01800  *
01801  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01802  * is active for the given call number.
01803  *
01804  * \pre Assumes lock for callno is already held.
01805  *
01806  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01807  * was valid before calling it, it may no longer be valid after calling it.
01808  * This function may unlock and lock the mutex associated with this callno,
01809  * meaning that another thread may grab it and destroy the call.
01810  */
01811 static int iax2_queue_hangup(int callno)
01812 {
01813    for (;;) {
01814       if (iaxs[callno] && iaxs[callno]->owner) {
01815          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01816             /* Avoid deadlock by pausing and trying again */
01817             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01818          } else {
01819             ast_queue_hangup(iaxs[callno]->owner);
01820             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01821             break;
01822          }
01823       } else
01824          break;
01825    }
01826    return 0;
01827 }
01828 
01829 /*!
01830  * \brief Queue a control frame on the ast_channel owner
01831  *
01832  * This function queues a control frame on the owner of the IAX2 pvt struct that
01833  * is active for the given call number.
01834  *
01835  * \pre Assumes lock for callno is already held.
01836  *
01837  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01838  * was valid before calling it, it may no longer be valid after calling it.
01839  * This function may unlock and lock the mutex associated with this callno,
01840  * meaning that another thread may grab it and destroy the call.
01841  */
01842 static int iax2_queue_control_data(int callno, 
01843    enum ast_control_frame_type control, const void *data, size_t datalen)
01844 {
01845    for (;;) {
01846       if (iaxs[callno] && iaxs[callno]->owner) {
01847          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01848             /* Avoid deadlock by pausing and trying again */
01849             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01850          } else {
01851             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01852             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01853             break;
01854          }
01855       } else
01856          break;
01857    }
01858    return 0;
01859 }
01860 static void destroy_firmware(struct iax_firmware *cur)
01861 {
01862    /* Close firmware */
01863    if (cur->fwh) {
01864       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01865    }
01866    close(cur->fd);
01867    free(cur);
01868 }
01869 
01870 static int try_firmware(char *s)
01871 {
01872    struct stat stbuf;
01873    struct iax_firmware *cur;
01874    int ifd;
01875    int fd;
01876    int res;
01877    
01878    struct ast_iax2_firmware_header *fwh, fwh2;
01879    struct MD5Context md5;
01880    unsigned char sum[16];
01881    unsigned char buf[1024];
01882    int len, chunk;
01883    char *s2;
01884    char *last;
01885    s2 = alloca(strlen(s) + 100);
01886    if (!s2) {
01887       ast_log(LOG_WARNING, "Alloca failed!\n");
01888       return -1;
01889    }
01890    last = strrchr(s, '/');
01891    if (last)
01892       last++;
01893    else
01894       last = s;
01895    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01896    res = stat(s, &stbuf);
01897    if (res < 0) {
01898       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01899       return -1;
01900    }
01901    /* Make sure it's not a directory */
01902    if (S_ISDIR(stbuf.st_mode))
01903       return -1;
01904    ifd = open(s, O_RDONLY);
01905    if (ifd < 0) {
01906       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01907       return -1;
01908    }
01909    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01910    if (fd < 0) {
01911       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01912       close(ifd);
01913       return -1;
01914    }
01915    /* Unlink our newly created file */
01916    unlink(s2);
01917    
01918    /* Now copy the firmware into it */
01919    len = stbuf.st_size;
01920    while(len) {
01921       chunk = len;
01922       if (chunk > sizeof(buf))
01923          chunk = sizeof(buf);
01924       res = read(ifd, buf, chunk);
01925       if (res != chunk) {
01926          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01927          close(ifd);
01928          close(fd);
01929          return -1;
01930       }
01931       res = write(fd, buf, chunk);
01932       if (res != chunk) {
01933          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01934          close(ifd);
01935          close(fd);
01936          return -1;
01937       }
01938       len -= chunk;
01939    }
01940    close(ifd);
01941    /* Return to the beginning */
01942    lseek(fd, 0, SEEK_SET);
01943    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01944       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01945       close(fd);
01946       return -1;
01947    }
01948    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01949       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01950       close(fd);
01951       return -1;
01952    }
01953    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01954       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01955       close(fd);
01956       return -1;
01957    }
01958    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01959       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01960       close(fd);
01961       return -1;
01962    }
01963    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01964    if (fwh == (void *) -1) {
01965       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01966       close(fd);
01967       return -1;
01968    }
01969    MD5Init(&md5);
01970    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01971    MD5Final(sum, &md5);
01972    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01973       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01974       munmap((void*)fwh, stbuf.st_size);
01975       close(fd);
01976       return -1;
01977    }
01978    cur = waresl.wares;
01979    while(cur) {
01980       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01981          /* Found a candidate */
01982          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01983             /* The version we have on loaded is older, load this one instead */
01984             break;
01985          /* This version is no newer than what we have.  Don't worry about it.
01986             We'll consider it a proper load anyhow though */
01987          munmap((void*)fwh, stbuf.st_size);
01988          close(fd);
01989          return 0;
01990       }
01991       cur = cur->next;
01992    }
01993    if (!cur) {
01994       /* Allocate a new one and link it */
01995       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01996          cur->fd = -1;
01997          cur->next = waresl.wares;
01998          waresl.wares = cur;
01999       }
02000    }
02001    if (cur) {
02002       if (cur->fwh) {
02003          munmap((void*)cur->fwh, cur->mmaplen);
02004       }
02005       if (cur->fd > -1)
02006          close(cur->fd);
02007       cur->fwh = fwh;
02008       cur->fd = fd;
02009       cur->mmaplen = stbuf.st_size;
02010       cur->dead = 0;
02011    }
02012    return 0;
02013 }
02014 
02015 static int iax_check_version(char *dev)
02016 {
02017    int res = 0;
02018    struct iax_firmware *cur;
02019    if (!ast_strlen_zero(dev)) {
02020       ast_mutex_lock(&waresl.lock);
02021       cur = waresl.wares;
02022       while(cur) {
02023          if (!strcmp(dev, (char *)cur->fwh->devname)) {
02024             res = ntohs(cur->fwh->version);
02025             break;
02026          }
02027          cur = cur->next;
02028       }
02029       ast_mutex_unlock(&waresl.lock);
02030    }
02031    return res;
02032 }
02033 
02034 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02035 {
02036    int res = -1;
02037    unsigned int bs = desc & 0xff;
02038    unsigned int start = (desc >> 8) & 0xffffff;
02039    unsigned int bytes;
02040    struct iax_firmware *cur;
02041    if (!ast_strlen_zero((char *)dev) && bs) {
02042       start *= bs;
02043       ast_mutex_lock(&waresl.lock);
02044       cur = waresl.wares;
02045       while(cur) {
02046          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
02047             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02048             if (start < ntohl(cur->fwh->datalen)) {
02049                bytes = ntohl(cur->fwh->datalen) - start;
02050                if (bytes > bs)
02051                   bytes = bs;
02052                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02053             } else {
02054                bytes = 0;
02055                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02056             }
02057             if (bytes == bs)
02058                res = 0;
02059             else
02060                res = 1;
02061             break;
02062          }
02063          cur = cur->next;
02064       }
02065       ast_mutex_unlock(&waresl.lock);
02066    }
02067    return res;
02068 }
02069 
02070 
02071 static void reload_firmware(int unload)
02072 {
02073    struct iax_firmware *cur, *curl, *curp;
02074    DIR *fwd;
02075    struct dirent *de;
02076    char dir[256];
02077    char fn[256];
02078    /* Mark all as dead */
02079    ast_mutex_lock(&waresl.lock);
02080    cur = waresl.wares;
02081    while(cur) {
02082       cur->dead = 1;
02083       cur = cur->next;
02084    }
02085 
02086    /* Now that we've freed them, load the new ones */
02087    if (!unload) {
02088       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02089       fwd = opendir(dir);
02090       if (fwd) {
02091          while((de = readdir(fwd))) {
02092             if (de->d_name[0] != '.') {
02093                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02094                if (!try_firmware(fn)) {
02095                   if (option_verbose > 1)
02096                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02097                }
02098             }
02099          }
02100          closedir(fwd);
02101       } else 
02102          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02103    }
02104 
02105    /* Clean up leftovers */
02106    cur = waresl.wares;
02107    curp = NULL;
02108    while(cur) {
02109       curl = cur;
02110       cur = cur->next;
02111       if (curl->dead) {
02112          if (curp) {
02113             curp->next = cur;
02114          } else {
02115             waresl.wares = cur;
02116          }
02117          destroy_firmware(curl);
02118       } else {
02119          curp = cur;
02120       }
02121    }
02122    ast_mutex_unlock(&waresl.lock);
02123 }
02124 
02125 /*!
02126  * \note This function assumes that iaxsl[callno] is locked when called.
02127  *
02128  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02129  * was valid before calling it, it may no longer be valid after calling it.
02130  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02131  * associated with this callno, meaning that another thread may grab it and destroy the call.
02132  */
02133 static int __do_deliver(void *data)
02134 {
02135    /* Just deliver the packet by using queueing.  This is called by
02136      the IAX thread with the iaxsl lock held. */
02137    struct iax_frame *fr = data;
02138    fr->retrans = -1;
02139    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02140    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02141       iax2_queue_frame(fr->callno, &fr->af);
02142    /* Free our iax frame */
02143    iax2_frame_free(fr);
02144    /* And don't run again */
02145    return 0;
02146 }
02147 
02148 static int handle_error(void)
02149 {
02150    /* XXX Ideally we should figure out why an error occured and then abort those
02151       rather than continuing to try.  Unfortunately, the published interface does
02152       not seem to work XXX */
02153 #if 0
02154    struct sockaddr_in *sin;
02155    int res;
02156    struct msghdr m;
02157    struct sock_extended_err e;
02158    m.msg_name = NULL;
02159    m.msg_namelen = 0;
02160    m.msg_iov = NULL;
02161    m.msg_control = &e;
02162    m.msg_controllen = sizeof(e);
02163    m.msg_flags = 0;
02164    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02165    if (res < 0)
02166       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02167    else {
02168       if (m.msg_controllen) {
02169          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02170          if (sin) 
02171             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02172          else
02173             ast_log(LOG_WARNING, "No address detected??\n");
02174       } else {
02175          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02176       }
02177    }
02178 #endif
02179    return 0;
02180 }
02181 
02182 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02183 {
02184    int res;
02185    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02186                sizeof(*sin));
02187    if (res < 0) {
02188       if (option_debug)
02189          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02190       handle_error();
02191    } else
02192       res = 0;
02193    return res;
02194 }
02195 
02196 static int send_packet(struct iax_frame *f)
02197 {
02198    int res;
02199    int callno = f->callno;
02200 
02201    /* Don't send if there was an error, but return error instead */
02202    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02203        return -1;
02204    
02205    /* Called with iaxsl held */
02206    if (option_debug > 2 && iaxdebug)
02207       ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
02208    if (f->transfer) {
02209       if (iaxdebug)
02210          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02211       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02212                sizeof(iaxs[callno]->transfer));
02213    } else {
02214       if (iaxdebug)
02215          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02216       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02217                sizeof(iaxs[callno]->addr));
02218    }
02219    if (res < 0) {
02220       if (option_debug && iaxdebug)
02221          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02222       handle_error();
02223    } else
02224       res = 0;
02225    return res;
02226 }
02227 
02228 /*!
02229  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02230  *       for the given call number may disappear during its execution.
02231  */
02232 static int iax2_predestroy(int callno)
02233 {
02234    struct ast_channel *c;
02235    struct chan_iax2_pvt *pvt = iaxs[callno];
02236 
02237    if (!pvt)
02238       return -1;
02239    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02240       iax2_destroy_helper(pvt);
02241       ast_set_flag(pvt, IAX_ALREADYGONE); 
02242    }
02243    c = pvt->owner;
02244    if (c) {
02245       c->tech_pvt = NULL;
02246       iax2_queue_hangup(callno);
02247       pvt->owner = NULL;
02248       ast_module_unref(ast_module_info->self);
02249    }
02250    return 0;
02251 }
02252 
02253 static int update_packet(struct iax_frame *f)
02254 {
02255    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02256    struct ast_iax2_full_hdr *fh = f->data;
02257    /* Mark this as a retransmission */
02258    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02259    /* Update iseqno */
02260    f->iseqno = iaxs[f->callno]->iseqno;
02261    fh->iseqno = f->iseqno;
02262    return 0;
02263 }
02264 
02265 static int attempt_transmit(const void *data);
02266 static void __attempt_transmit(const void *data)
02267 {
02268    /* Attempt to transmit the frame to the remote peer...
02269       Called without iaxsl held. */
02270    struct iax_frame *f = (struct iax_frame *)data;
02271    int freeme=0;
02272    int callno = f->callno;
02273    /* Make sure this call is still active */
02274    if (callno) 
02275       ast_mutex_lock(&iaxsl[callno]);
02276    if (callno && iaxs[callno]) {
02277       if ((f->retries < 0) /* Already ACK'd */ ||
02278           (f->retries >= max_retries) /* Too many attempts */) {
02279             /* Record an error if we've transmitted too many times */
02280             if (f->retries >= max_retries) {
02281                if (f->transfer) {
02282                   /* Transfer timeout */
02283                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02284                } else if (f->final) {
02285                   if (f->final) 
02286                      iax2_destroy(callno);
02287                } else {
02288                   if (iaxs[callno]->owner)
02289                      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);
02290                   iaxs[callno]->error = ETIMEDOUT;
02291                   if (iaxs[callno]->owner) {
02292                      struct ast_frame fr = { 0, };
02293                      /* Hangup the fd */
02294                      fr.frametype = AST_FRAME_CONTROL;
02295                      fr.subclass = AST_CONTROL_HANGUP;
02296                      iax2_queue_frame(callno, &fr); // XXX
02297                      /* Remember, owner could disappear */
02298                      if (iaxs[callno] && iaxs[callno]->owner)
02299                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02300                   } else {
02301                      if (iaxs[callno]->reg) {
02302                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02303                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02304                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02305                      }
02306                      iax2_destroy(callno);
02307                   }
02308                }
02309 
02310             }
02311             freeme++;
02312       } else {
02313          /* Update it if it needs it */
02314          update_packet(f);
02315          /* Attempt transmission */
02316          send_packet(f);
02317          f->retries++;
02318          /* Try again later after 10 times as long */
02319          f->retrytime *= 10;
02320          if (f->retrytime > MAX_RETRY_TIME)
02321             f->retrytime = MAX_RETRY_TIME;
02322          /* Transfer messages max out at one second */
02323          if (f->transfer && (f->retrytime > 1000))
02324             f->retrytime = 1000;
02325          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02326       }
02327    } else {
02328       /* Make sure it gets freed */
02329       f->retries = -1;
02330       freeme++;
02331    }
02332    if (callno)
02333       ast_mutex_unlock(&iaxsl[callno]);
02334    /* Do not try again */
02335    if (freeme) {
02336       /* Don't attempt delivery, just remove it from the queue */
02337       AST_LIST_LOCK(&iaxq.queue);
02338       AST_LIST_REMOVE(&iaxq.queue, f, list);
02339       iaxq.count--;
02340       AST_LIST_UNLOCK(&iaxq.queue);
02341       f->retrans = -1;
02342       /* Free the IAX frame */
02343       iax2_frame_free(f);
02344    }
02345 }
02346 
02347 static int attempt_transmit(const void *data)
02348 {
02349 #ifdef SCHED_MULTITHREADED
02350    if (schedule_action(__attempt_transmit, data))
02351 #endif      
02352       __attempt_transmit(data);
02353    return 0;
02354 }
02355 
02356 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02357 {
02358    struct iax2_peer *peer = NULL;
02359    struct iax2_user *user = NULL;
02360 
02361    if (argc != 4)
02362         return RESULT_SHOWUSAGE;
02363    if (!strcmp(argv[3],"all")) {
02364       prune_users();
02365       prune_peers();
02366       ast_cli(fd, "OK cache is flushed.\n");
02367       return RESULT_SUCCESS;
02368    }
02369    peer = find_peer(argv[3], 0);
02370    user = find_user(argv[3]);
02371    if (peer || user) {
02372       if (peer) {
02373          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02374             ast_set_flag(peer, IAX_RTAUTOCLEAR);
02375             expire_registry(peer_ref(peer));
02376             ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
02377          } else {
02378             ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
02379          }
02380          peer_unref(peer);
02381       }
02382       if (user) {
02383          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02384             ast_set_flag(user, IAX_RTAUTOCLEAR);
02385             ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
02386          } else {
02387             ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
02388          }
02389          ao2_unlink(users,user);
02390          user_unref(user);
02391       }
02392    } else {
02393       ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
02394    }
02395 
02396    return RESULT_SUCCESS;
02397 }
02398 
02399 static int iax2_test_losspct(int fd, int argc, char *argv[])
02400 {
02401        if (argc != 4)
02402                return RESULT_SHOWUSAGE;
02403 
02404        test_losspct = atoi(argv[3]);
02405 
02406        return RESULT_SUCCESS;
02407 }
02408 
02409 #ifdef IAXTESTS
02410 static int iax2_test_late(int fd, int argc, char *argv[])
02411 {
02412    if (argc != 4)
02413       return RESULT_SHOWUSAGE;
02414 
02415    test_late = atoi(argv[3]);
02416 
02417    return RESULT_SUCCESS;
02418 }
02419 
02420 static int iax2_test_resync(int fd, int argc, char *argv[])
02421 {
02422    if (argc != 4)
02423       return RESULT_SHOWUSAGE;
02424 
02425    test_resync = atoi(argv[3]);
02426 
02427    return RESULT_SUCCESS;
02428 }
02429 
02430 static int iax2_test_jitter(int fd, int argc, char *argv[])
02431 {
02432    if (argc < 4 || argc > 5)
02433       return RESULT_SHOWUSAGE;
02434 
02435    test_jit = atoi(argv[3]);
02436    if (argc == 5) 
02437       test_jitpct = atoi(argv[4]);
02438 
02439    return RESULT_SUCCESS;
02440 }
02441 #endif /* IAXTESTS */
02442 
02443 /*! \brief  peer_status: Report Peer status in character string */
02444 /*    returns 1 if peer is online, -1 if unmonitored */
02445 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02446 {
02447    int res = 0;
02448    if (peer->maxms) {
02449       if (peer->lastms < 0) {
02450          ast_copy_string(status, "UNREACHABLE", statuslen);
02451       } else if (peer->lastms > peer->maxms) {
02452          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02453          res = 1;
02454       } else if (peer->lastms) {
02455          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02456          res = 1;
02457       } else {
02458          ast_copy_string(status, "UNKNOWN", statuslen);
02459       }
02460    } else { 
02461       ast_copy_string(status, "Unmonitored", statuslen);
02462       res = -1;
02463    }
02464    return res;
02465 }
02466 
02467 /*! \brief Show one peer in detail */
02468 static int iax2_show_peer(int fd, int argc, char *argv[])
02469 {
02470    char status[30];
02471    char cbuf[256];
02472    struct iax2_peer *peer;
02473    char codec_buf[512];
02474    int x = 0, codec = 0, load_realtime = 0;
02475 
02476    if (argc < 4)
02477       return RESULT_SHOWUSAGE;
02478 
02479    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02480 
02481    peer = find_peer(argv[3], load_realtime);
02482    if (peer) {
02483       ast_cli(fd,"\n\n");
02484       ast_cli(fd, "  * Name       : %s\n", peer->name);
02485       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02486       ast_cli(fd, "  Context      : %s\n", peer->context);
02487       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02488       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02489       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02490       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02491       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02492       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
02493       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02494       ast_cli(fd, "  Username     : %s\n", peer->username);
02495       ast_cli(fd, "  Codecs       : ");
02496       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02497       ast_cli(fd, "%s\n", codec_buf);
02498 
02499       ast_cli(fd, "  Codec Order  : (");
02500       for(x = 0; x < 32 ; x++) {
02501          codec = ast_codec_pref_index(&peer->prefs,x);
02502          if(!codec)
02503             break;
02504          ast_cli(fd, "%s", ast_getformatname(codec));
02505          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02506             ast_cli(fd, "|");
02507       }
02508 
02509       if (!x)
02510          ast_cli(fd, "none");
02511       ast_cli(fd, ")\n");
02512 
02513       ast_cli(fd, "  Status       : ");
02514       peer_status(peer, status, sizeof(status));   
02515       ast_cli(fd, "%s\n",status);
02516       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02517       ast_cli(fd,"\n");
02518       peer_unref(peer);
02519    } else {
02520       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02521       ast_cli(fd,"\n");
02522    }
02523 
02524    return RESULT_SUCCESS;
02525 }
02526 
02527 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02528 {
02529    int which = 0;
02530    struct iax2_peer *peer;
02531    char *res = NULL;
02532    int wordlen = strlen(word);
02533    struct ao2_iterator i;
02534 
02535    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02536    if (pos != 3)
02537       return NULL;
02538 
02539    i = ao2_iterator_init(peers, 0);
02540    while ((peer = ao2_iterator_next(&i))) {
02541       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02542          res = ast_strdup(peer->name);
02543          peer_unref(peer);
02544          break;
02545       }
02546       peer_unref(peer);
02547    }
02548 
02549    return res;
02550 }
02551 
02552 static int iax2_show_stats(int fd, int argc, char *argv[])
02553 {
02554    struct iax_frame *cur;
02555    int cnt = 0, dead=0, final=0;
02556 
02557    if (argc != 3)
02558       return RESULT_SHOWUSAGE;
02559 
02560    AST_LIST_LOCK(&iaxq.queue);
02561    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02562       if (cur->retries < 0)
02563          dead++;
02564       if (cur->final)
02565          final++;
02566       cnt++;
02567    }
02568    AST_LIST_UNLOCK(&iaxq.queue);
02569 
02570    ast_cli(fd, "    IAX Statistics\n");
02571    ast_cli(fd, "---------------------\n");
02572    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02573    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02574    
02575    return RESULT_SUCCESS;
02576 }
02577 
02578 static int iax2_show_cache(int fd, int argc, char *argv[])
02579 {
02580    struct iax2_dpcache *dp;
02581    char tmp[1024], *pc;
02582    int s;
02583    int x,y;
02584    struct timeval tv;
02585    gettimeofday(&tv, NULL);
02586    ast_mutex_lock(&dpcache_lock);
02587    dp = dpcache;
02588    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02589    while(dp) {
02590       s = dp->expiry.tv_sec - tv.tv_sec;
02591       tmp[0] = '\0';
02592       if (dp->flags & CACHE_FLAG_EXISTS)
02593          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02594       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02595          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02596       if (dp->flags & CACHE_FLAG_CANEXIST)
02597          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02598       if (dp->flags & CACHE_FLAG_PENDING)
02599          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02600       if (dp->flags & CACHE_FLAG_TIMEOUT)
02601          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02602       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02603          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02604       if (dp->flags & CACHE_FLAG_MATCHMORE)
02605          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02606       if (dp->flags & CACHE_FLAG_UNKNOWN)
02607          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02608       /* Trim trailing pipe */
02609       if (!ast_strlen_zero(tmp))
02610          tmp[strlen(tmp) - 1] = '\0';
02611       else
02612          ast_copy_string(tmp, "(none)", sizeof(tmp));
02613       y=0;
02614       pc = strchr(dp->peercontext, '@');
02615       if (!pc)
02616          pc = dp->peercontext;
02617       else
02618          pc++;
02619       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02620          if (dp->waiters[x] > -1)
02621             y++;
02622       if (s > 0)
02623          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02624       else
02625          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02626       dp = dp->next;
02627    }
02628    ast_mutex_unlock(&dpcache_lock);
02629    return RESULT_SUCCESS;
02630 }
02631 
02632 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02633 
02634 static void unwrap_timestamp(struct iax_frame *fr)
02635 {
02636    /* Video mini frames only encode the lower 15 bits of the session
02637     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
02638    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02639    const int lower_mask = (1 << ts_shift) - 1;
02640    const int upper_mask = ~lower_mask;
02641    const int last_upper = iaxs[fr->callno]->last & upper_mask;
02642 
02643    if ( (fr->ts & upper_mask) == last_upper ) {
02644       const int x = fr->ts - iaxs[fr->callno]->last;
02645       const int threshold = (ts_shift == 15) ? 25000 : 50000;
02646 
02647       if (x < -threshold) {
02648          /* Sudden big jump backwards in timestamp:
02649             What likely happened here is that miniframe timestamp has circled but we haven't
02650             gotten the update from the main packet.  We'll just pretend that we did, and
02651             update the timestamp appropriately. */
02652          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02653          if (option_debug && iaxdebug)
02654             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02655       } else if (x > threshold) {
02656          /* Sudden apparent big jump forwards in timestamp:
02657             What's likely happened is this is an old miniframe belonging to the previous
02658             top 15 or 16-bit timestamp that has turned up out of order.
02659             Adjust the timestamp appropriately. */
02660          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02661          if (option_debug && iaxdebug)
02662             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02663       }
02664    }
02665 }
02666 
02667 static int get_from_jb(const void *p);
02668 
02669 static void update_jbsched(struct chan_iax2_pvt *pvt)
02670 {
02671    int when;
02672    
02673    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02674    
02675    when = jb_next(pvt->jb) - when;
02676 
02677    AST_SCHED_DEL(sched, pvt->jbid);
02678 
02679    if(when <= 0) {
02680       /* XXX should really just empty until when > 0.. */
02681       when = 1;
02682    }
02683    
02684    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02685 }
02686 
02687 static void __get_from_jb(const void *p) 
02688 {
02689    int callno = PTR_TO_CALLNO(p);
02690    struct chan_iax2_pvt *pvt = NULL;
02691    struct iax_frame *fr;
02692    jb_frame frame;
02693    int ret;
02694    long now;
02695    long next;
02696    struct timeval tv;
02697    
02698    /* Make sure we have a valid private structure before going on */
02699    ast_mutex_lock(&iaxsl[callno]);
02700    pvt = iaxs[callno];
02701    if (!pvt) {
02702       /* No go! */
02703       ast_mutex_unlock(&iaxsl[callno]);
02704       return;
02705    }
02706 
02707    pvt->jbid = -1;
02708    
02709    gettimeofday(&tv,NULL);
02710    /* round up a millisecond since ast_sched_runq does; */
02711    /* prevents us from spinning while waiting for our now */
02712    /* to catch up with runq's now */
02713    tv.tv_usec += 1000;
02714    
02715    now = ast_tvdiff_ms(tv, pvt->rxcore);
02716    
02717    if(now >= (next = jb_next(pvt->jb))) {
02718       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02719       switch(ret) {
02720       case JB_OK:
02721          fr = frame.data;
02722          __do_deliver(fr);
02723          /* __do_deliver() can cause the call to disappear */
02724          pvt = iaxs[callno];
02725          break;
02726       case JB_INTERP:
02727       {
02728          struct ast_frame af = { 0, };
02729          
02730          /* create an interpolation frame */
02731          af.frametype = AST_FRAME_VOICE;
02732          af.subclass = pvt->voiceformat;
02733          af.samples  = frame.ms * 8;
02734          af.src  = "IAX2 JB interpolation";
02735          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02736          af.offset = AST_FRIENDLY_OFFSET;
02737          
02738          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02739           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02740          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02741             iax2_queue_frame(callno, &af);
02742             /* iax2_queue_frame() could cause the call to disappear */
02743             pvt = iaxs[callno];
02744          }
02745       }
02746          break;
02747       case JB_DROP:
02748          iax2_frame_free(frame.data);
02749          break;
02750       case JB_NOFRAME:
02751       case JB_EMPTY:
02752          /* do nothing */
02753          break;
02754       default:
02755          /* shouldn't happen */
02756          break;
02757       }
02758    }
02759    if (pvt)
02760       update_jbsched(pvt);
02761    ast_mutex_unlock(&iaxsl[callno]);
02762 }
02763 
02764 static int get_from_jb(const void *data)
02765 {
02766 #ifdef SCHED_MULTITHREADED
02767    if (schedule_action(__get_from_jb, data))
02768 #endif      
02769       __get_from_jb(data);
02770    return 0;
02771 }
02772 
02773 /*!
02774  * \note This function assumes fr->callno is locked
02775  *
02776  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02777  * was valid before calling it, it may no longer be valid after calling it.
02778  */
02779 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02780 {
02781    int type, len;
02782    int ret;
02783    int needfree = 0;
02784    struct ast_channel *owner = NULL;
02785    struct ast_channel *bridge = NULL;
02786    
02787    /* Attempt to recover wrapped timestamps */
02788    unwrap_timestamp(fr);
02789 
02790    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02791    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02792       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02793    else {
02794 #if 0
02795       if (option_debug)
02796          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02797 #endif
02798       fr->af.delivery = ast_tv(0,0);
02799    }
02800 
02801    type = JB_TYPE_CONTROL;
02802    len = 0;
02803 
02804    if(fr->af.frametype == AST_FRAME_VOICE) {
02805       type = JB_TYPE_VOICE;
02806       len = ast_codec_get_samples(&fr->af) / 8;
02807    } else if(fr->af.frametype == AST_FRAME_CNG) {
02808       type = JB_TYPE_SILENCE;
02809    }
02810 
02811    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02812       if (tsout)
02813          *tsout = fr->ts;
02814       __do_deliver(fr);
02815       return -1;
02816    }
02817 
02818    if ((owner = iaxs[fr->callno]->owner))
02819       bridge = ast_bridged_channel(owner);
02820 
02821    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02822     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02823    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02824       jb_frame frame;
02825 
02826       /* deliver any frames in the jb */
02827       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02828          __do_deliver(frame.data);
02829          /* __do_deliver() can make the call disappear */
02830          if (!iaxs[fr->callno])
02831             return -1;
02832       }
02833 
02834       jb_reset(iaxs[fr->callno]->jb);
02835 
02836       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02837 
02838       /* deliver this frame now */
02839       if (tsout)
02840          *tsout = fr->ts;
02841       __do_deliver(fr);
02842       return -1;
02843    }
02844 
02845    /* insert into jitterbuffer */
02846    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02847    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02848          calc_rxstamp(iaxs[fr->callno],fr->ts));
02849    if (ret == JB_DROP) {
02850       needfree++;
02851    } else if (ret == JB_SCHED) {
02852       update_jbsched(iaxs[fr->callno]);
02853    }
02854    if (tsout)
02855       *tsout = fr->ts;
02856    if (needfree) {
02857       /* Free our iax frame */
02858       iax2_frame_free(fr);
02859       return -1;
02860    }
02861    return 0;
02862 }
02863 
02864 static int iax2_transmit(struct iax_frame *fr)
02865 {
02866    /* Lock the queue and place this packet at the end */
02867    /* By setting this to 0, the network thread will send it for us, and
02868       queue retransmission if necessary */
02869    fr->sentyet = 0;
02870    AST_LIST_LOCK(&iaxq.queue);
02871    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02872    iaxq.count++;
02873    AST_LIST_UNLOCK(&iaxq.queue);
02874    /* Wake up the network and scheduler thread */
02875    if (netthreadid != AST_PTHREADT_NULL)
02876       pthread_kill(netthreadid, SIGURG);
02877    signal_condition(&sched_lock, &sched_cond);
02878    return 0;
02879 }
02880 
02881 
02882 
02883 static int iax2_digit_begin(struct ast_channel *c, char digit)
02884 {
02885    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02886 }
02887 
02888 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02889 {
02890    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02891 }
02892 
02893 static int iax2_sendtext(struct ast_channel *c, const char *text)
02894 {
02895    
02896    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02897       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02898 }
02899 
02900 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02901 {
02902    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02903 }
02904 
02905 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02906 {
02907    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02908 }
02909 
02910 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02911 {
02912    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02913    ast_mutex_lock(&iaxsl[callno]);
02914    if (iaxs[callno])
02915       iaxs[callno]->owner = newchan;
02916    else
02917       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02918    ast_mutex_unlock(&iaxsl[callno]);
02919    return 0;
02920 }
02921 
02922 /*!
02923  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02924  *       so do not call this with a pvt lock held.
02925  */
02926 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02927 {
02928    struct ast_variable *var = NULL;
02929    struct ast_variable *tmp;
02930    struct iax2_peer *peer=NULL;
02931    time_t regseconds = 0, nowtime;
02932    int dynamic=0;
02933 
02934    if (peername) {
02935       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02936       if (!var && sin)
02937          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02938    } else if (sin) {
02939       char porta[25];
02940       sprintf(porta, "%d", ntohs(sin->sin_port));
02941       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02942       if (var) {
02943          /* We'll need the peer name in order to build the structure! */
02944          for (tmp = var; tmp; tmp = tmp->next) {
02945             if (!strcasecmp(tmp->name, "name"))
02946                peername = tmp->value;
02947          }
02948       }
02949    }
02950    if (!var && peername) { /* Last ditch effort */
02951       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02952       /*!\note
02953        * If this one loaded something, then we need to ensure that the host
02954        * field matched.  The only reason why we can't have this as a criteria
02955        * is because we only have the IP address and the host field might be
02956        * set as a name (and the reverse PTR might not match).
02957        */
02958       if (var && sin) {
02959          for (tmp = var; tmp; tmp = tmp->next) {
02960             if (!strcasecmp(tmp->name, "host")) {
02961                struct ast_hostent ahp;
02962                struct hostent *hp;
02963                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02964                   /* No match */
02965                   ast_variables_destroy(var);
02966                   var = NULL;
02967                }
02968                break;
02969             }
02970          }
02971       }
02972    }
02973    if (!var)
02974       return NULL;
02975 
02976    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02977    
02978    if (!peer) {
02979       ast_variables_destroy(var);
02980       return NULL;
02981    }
02982 
02983    for (tmp = var; tmp; tmp = tmp->next) {
02984       /* Make sure it's not a user only... */
02985       if (!strcasecmp(tmp->name, "type")) {
02986          if (strcasecmp(tmp->value, "friend") &&
02987              strcasecmp(tmp->value, "peer")) {
02988             /* Whoops, we weren't supposed to exist! */
02989             peer = peer_unref(peer);
02990             break;
02991          } 
02992       } else if (!strcasecmp(tmp->name, "regseconds")) {
02993          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02994       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02995          inet_aton(tmp->value, &(peer->addr.sin_addr));
02996       } else if (!strcasecmp(tmp->name, "port")) {
02997          peer->addr.sin_port = htons(atoi(tmp->value));
02998       } else if (!strcasecmp(tmp->name, "host")) {
02999          if (!strcasecmp(tmp->value, "dynamic"))
03000             dynamic = 1;
03001       }
03002    }
03003 
03004    ast_variables_destroy(var);
03005 
03006    if (!peer)
03007       return NULL;
03008 
03009    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03010       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03011       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03012          if (peer->expire > -1) {
03013             if (!ast_sched_del(sched, peer->expire)) {
03014                peer->expire = -1;
03015                peer_unref(peer);
03016             }
03017          }
03018          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03019          if (peer->expire == -1)
03020             peer_unref(peer);
03021       }
03022       ao2_link(peers, peer);
03023       if (ast_test_flag(peer, IAX_DYNAMIC))
03024          reg_source_db(peer);
03025    } else {
03026       ast_set_flag(peer, IAX_TEMPONLY);   
03027    }
03028 
03029    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03030       time(&nowtime);
03031       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03032          memset(&peer->addr, 0, sizeof(peer->addr));
03033          realtime_update_peer(peer->name, &peer->addr, 0);
03034          if (option_debug)
03035             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03036                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03037       }
03038       else {
03039          if (option_debug)
03040             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03041                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03042       }
03043    }
03044 
03045    return peer;
03046 }
03047 
03048 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03049 {
03050    struct ast_variable *var;
03051    struct ast_variable *tmp;
03052    struct iax2_user *user=NULL;
03053 
03054    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03055    if (!var)
03056       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03057    if (!var && sin) {
03058       char porta[6];
03059       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03060       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03061       if (!var)
03062          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03063    }
03064    if (!var) { /* Last ditch effort */
03065       var = ast_load_realtime("iaxusers", "name", username, NULL);
03066       /*!\note
03067        * If this one loaded something, then we need to ensure that the host
03068        * field matched.  The only reason why we can't have this as a criteria
03069        * is because we only have the IP address and the host field might be
03070        * set as a name (and the reverse PTR might not match).
03071        */
03072       if (var) {
03073          for (tmp = var; tmp; tmp = tmp->next) {
03074             if (!strcasecmp(tmp->name, "host")) {
03075                struct ast_hostent ahp;
03076                struct hostent *hp;
03077                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03078                   /* No match */
03079                   ast_variables_destroy(var);
03080                   var = NULL;
03081                }
03082                break;
03083             }
03084          }
03085       }
03086    }
03087    if (!var)
03088       return NULL;
03089 
03090    tmp = var;
03091    while(tmp) {
03092       /* Make sure it's not a peer only... */
03093       if (!strcasecmp(tmp->name, "type")) {
03094          if (strcasecmp(tmp->value, "friend") &&
03095              strcasecmp(tmp->value, "user")) {
03096             return NULL;
03097          } 
03098       }
03099       tmp = tmp->next;
03100    }
03101 
03102    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03103 
03104    ast_variables_destroy(var);
03105 
03106    if (!user)
03107       return NULL;
03108 
03109    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03110       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03111       ao2_link(users, user);
03112    } else {
03113       ast_set_flag(user, IAX_TEMPONLY);   
03114    }
03115 
03116    return user;
03117 }
03118 
03119 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03120 {
03121    char port[10];
03122    char regseconds[20];
03123    
03124    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03125    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03126    ast_update_realtime("iaxpeers", "name", peername, 
03127       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03128       "regseconds", regseconds, NULL);
03129 }
03130 
03131 struct create_addr_info {
03132    int capability;
03133    unsigned int flags;
03134    int maxtime;
03135    int encmethods;
03136    int found;
03137    int sockfd;
03138    int adsi;
03139    char username[80];
03140    char secret[80];
03141    char outkey[80];
03142    char timezone[80];
03143    char prefs[32];
03144    char context[AST_MAX_CONTEXT];
03145    char peercontext[AST_MAX_CONTEXT];
03146    char mohinterpret[MAX_MUSICCLASS];
03147    char mohsuggest[MAX_MUSICCLASS];
03148 };
03149 
03150 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03151 {
03152    struct ast_hostent ahp;
03153    struct hostent *hp;
03154    struct iax2_peer *peer;
03155    int res = -1;
03156    struct ast_codec_pref ourprefs;
03157 
03158    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03159    cai->sockfd = defaultsockfd;
03160    cai->maxtime = 0;
03161    sin->sin_family = AF_INET;
03162 
03163    if (!(peer = find_peer(peername, 1))) {
03164       cai->found = 0;
03165 
03166       hp = ast_gethostbyname(peername, &ahp);
03167       if (hp) {
03168          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03169          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03170          /* use global iax prefs for unknown peer/user */
03171          /* But move the calling channel's native codec to the top of the preference list */
03172          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03173          if (c)
03174             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03175          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03176          return 0;
03177       } else {
03178          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03179          return -1;
03180       }
03181    }
03182 
03183    cai->found = 1;
03184    
03185    /* if the peer has no address (current or default), return failure */
03186    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03187       goto return_unref;
03188 
03189    /* if the peer is being monitored and is currently unreachable, return failure */
03190    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03191       goto return_unref;
03192 
03193    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03194    cai->maxtime = peer->maxms;
03195    cai->capability = peer->capability;
03196    cai->encmethods = peer->encmethods;
03197    cai->sockfd = peer->sockfd;
03198    cai->adsi = peer->adsi;
03199    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03200    /* Move the calling channel's native codec to the top of the preference list */
03201    if (c) {
03202       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03203       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03204    }
03205    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03206    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03207    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03208    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03209    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03210    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03211    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03212    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03213    if (ast_strlen_zero(peer->dbsecret)) {
03214       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03215    } else {
03216       char *family;
03217       char *key = NULL;
03218 
03219       family = ast_strdupa(peer->dbsecret);
03220       key = strchr(family, '/');
03221       if (key)
03222          *key++ = '\0';
03223       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03224          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03225          goto return_unref;
03226       }
03227    }
03228 
03229    if (peer->addr.sin_addr.s_addr) {
03230       sin->sin_addr = peer->addr.sin_addr;
03231       sin->sin_port = peer->addr.sin_port;
03232    } else {
03233       sin->sin_addr = peer->defaddr.sin_addr;
03234       sin->sin_port = peer->defaddr.sin_port;
03235    }
03236 
03237    res = 0;
03238 
03239 return_unref:
03240    peer_unref(peer);
03241 
03242    return res;
03243 }
03244 
03245 static void __auto_congest(const void *nothing)
03246 {
03247    int callno = PTR_TO_CALLNO(nothing);
03248    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03249    ast_mutex_lock(&iaxsl[callno]);
03250    if (iaxs[callno]) {
03251       iaxs[callno]->initid = -1;
03252       iax2_queue_frame(callno, &f);
03253       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03254    }
03255    ast_mutex_unlock(&iaxsl[callno]);
03256 }
03257 
03258 static int auto_congest(const void *data)
03259 {
03260 #ifdef SCHED_MULTITHREADED
03261    if (schedule_action(__auto_congest, data))
03262 #endif      
03263       __auto_congest(data);
03264    return 0;
03265 }
03266 
03267 static unsigned int iax2_datetime(const char *tz)
03268 {
03269    time_t t;
03270    struct tm tm;
03271    unsigned int tmp;
03272    time(&t);
03273    if (!ast_strlen_zero(tz))
03274       ast_localtime(&t, &tm, tz);
03275    else
03276       ast_localtime(&t, &tm, NULL);
03277    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03278    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03279    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03280    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03281    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03282    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03283    return tmp;
03284 }
03285 
03286 struct parsed_dial_string {
03287    char *username;
03288    char *password;
03289    char *key;
03290    char *peer;
03291    char *port;
03292    char *exten;
03293    char *context;
03294    char *options;
03295 };
03296 
03297 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03298 {
03299    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03300       .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03301       .csub = compress_subclass(command) };
03302 
03303    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03304 }
03305 
03306 /*!
03307  * \brief Parses an IAX dial string into its component parts.
03308  * \param data the string to be parsed
03309  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03310  * \return nothing
03311  *
03312  * This function parses the string and fills the structure
03313  * with pointers to its component parts. The input string
03314  * will be modified.
03315  *
03316  * \note This function supports both plaintext passwords and RSA
03317  * key names; if the password string is formatted as '[keyname]',
03318  * then the keyname will be placed into the key field, and the
03319  * password field will be set to NULL.
03320  *
03321  * \note The dial string format is:
03322  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03323  */
03324 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03325 {
03326    if (ast_strlen_zero(data))
03327       return;
03328 
03329    pds->peer = strsep(&data, "/");
03330    pds->exten = strsep(&data, "/");
03331    pds->options = data;
03332 
03333    if (pds->exten) {
03334       data = pds->exten;
03335       pds->exten = strsep(&data, "@");
03336       pds->context = data;
03337    }
03338 
03339    if (strchr(pds->peer, '@')) {
03340       data = pds->peer;
03341       pds->username = strsep(&data, "@");
03342       pds->peer = data;
03343    }
03344 
03345    if (pds->username) {
03346       data = pds->username;
03347       pds->username = strsep(&data, ":");
03348       pds->password = data;
03349    }
03350 
03351    data = pds->peer;
03352    pds->peer = strsep(&data, ":");
03353    pds->port = data;
03354 
03355    /* check for a key name wrapped in [] in the secret position, if found,
03356       move it to the key field instead
03357    */
03358    if (pds->password && (pds->password[0] == '[')) {
03359       pds->key = ast_strip_quoted(pds->password, "[", "]");
03360       pds->password = NULL;
03361    }
03362 }
03363 
03364 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03365 {
03366    struct sockaddr_in sin;
03367    char *l=NULL, *n=NULL, *tmpstr;
03368    struct iax_ie_data ied;
03369    char *defaultrdest = "s";
03370    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03371    struct parsed_dial_string pds;
03372    struct create_addr_info cai;
03373 
03374    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03375       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03376       return -1;
03377    }
03378 
03379    memset(&cai, 0, sizeof(cai));
03380    cai.encmethods = iax2_encryption;
03381 
03382    memset(&pds, 0, sizeof(pds));
03383    tmpstr = ast_strdupa(dest);
03384    parse_dial_string(tmpstr, &pds);
03385 
03386    if (ast_strlen_zero(pds.peer)) {
03387       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03388       return -1;
03389    }
03390 
03391    if (!pds.exten) {
03392       pds.exten = defaultrdest;
03393    }
03394 
03395    if (create_addr(pds.peer, c, &sin, &cai)) {
03396       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03397       return -1;
03398    }
03399 
03400    if (!pds.username && !ast_strlen_zero(cai.username))
03401       pds.username = cai.username;
03402    if (!pds.password && !ast_strlen_zero(cai.secret))
03403       pds.password = cai.secret;
03404    if (!pds.key && !ast_strlen_zero(cai.outkey))
03405       pds.key = cai.outkey;
03406    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03407       pds.context = cai.peercontext;
03408 
03409    /* Keep track of the context for outgoing calls too */
03410    ast_copy_string(c->context, cai.context, sizeof(c->context));
03411 
03412    if (pds.port)
03413       sin.sin_port = htons(atoi(pds.port));
03414 
03415    l = c->cid.cid_num;
03416    n = c->cid.cid_name;
03417 
03418    /* Now build request */ 
03419    memset(&ied, 0, sizeof(ied));
03420 
03421    /* On new call, first IE MUST be IAX version of caller */
03422    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03423    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03424    if (pds.options && strchr(pds.options, 'a')) {
03425       /* Request auto answer */
03426       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03427    }
03428 
03429    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03430 
03431    if (l) {
03432       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03433       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03434    } else {
03435       if (n)
03436          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03437       else
03438          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03439    }
03440 
03441    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03442    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03443 
03444    if (n)
03445       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03446    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03447       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03448 
03449    if (!ast_strlen_zero(c->language))
03450       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03451    if (!ast_strlen_zero(c->cid.cid_dnid))
03452       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03453    if (!ast_strlen_zero(c->cid.cid_rdnis))
03454       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03455 
03456    if (pds.context)
03457       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03458 
03459    if (pds.username)
03460       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03461 
03462    if (cai.encmethods)
03463       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03464 
03465    ast_mutex_lock(&iaxsl[callno]);
03466 
03467    if (!ast_strlen_zero(c->context))
03468       ast_string_field_set(iaxs[callno], context, c->context);
03469 
03470    if (pds.username)
03471       ast_string_field_set(iaxs[callno], username, pds.username);
03472 
03473    iaxs[callno]->encmethods = cai.encmethods;
03474 
03475    iaxs[callno]->adsi = cai.adsi;
03476    
03477    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03478    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03479 
03480    if (pds.key)
03481       ast_string_field_set(iaxs[callno], outkey, pds.key);
03482    if (pds.password)
03483       ast_string_field_set(iaxs[callno], secret, pds.password);
03484 
03485    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03486    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03487    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03488    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03489 
03490    if (iaxs[callno]->maxtime) {
03491       /* Initialize pingtime and auto-congest time */
03492       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03493       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03494    } else if (autokill) {
03495       iaxs[callno]->pingtime = autokill / 2;
03496       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03497    }
03498 
03499    /* send the command using the appropriate socket for this peer */
03500    iaxs[callno]->sockfd = cai.sockfd;
03501 
03502    /* Transmit the string in a "NEW" request */
03503    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03504 
03505    ast_mutex_unlock(&iaxsl[callno]);
03506    ast_setstate(c, AST_STATE_RINGING);
03507    
03508    return 0;
03509 }
03510 
03511 static int iax2_hangup(struct ast_channel *c) 
03512 {
03513    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03514    struct iax_ie_data ied;
03515    int alreadygone;
03516    memset(&ied, 0, sizeof(ied));
03517    ast_mutex_lock(&iaxsl[callno]);
03518    if (callno && iaxs[callno]) {
03519       if (option_debug)
03520          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03521       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03522       /* Send the hangup unless we have had a transmission error or are already gone */
03523       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03524       if (!iaxs[callno]->error && !alreadygone) {
03525          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03526             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03527          }
03528          if (!iaxs[callno]) {
03529             ast_mutex_unlock(&iaxsl[callno]);
03530             return 0;
03531          }
03532       }
03533       /* Explicitly predestroy it */
03534       iax2_predestroy(callno);
03535       /* If we were already gone to begin with, destroy us now */
03536       if (iaxs[callno] && alreadygone) {
03537          if (option_debug)
03538             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03539          iax2_destroy(callno);
03540       } else if (iaxs[callno]) {
03541          iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
03542       }
03543    } else if (c->tech_pvt) {
03544       /* If this call no longer exists, but the channel still
03545        * references it we need to set the channel's tech_pvt to null
03546        * to avoid ast_channel_free() trying to free it.
03547        */
03548       c->tech_pvt = NULL;
03549    }
03550    ast_mutex_unlock(&iaxsl[callno]);
03551    if (option_verbose > 2) 
03552       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03553    return 0;
03554 }
03555 
03556 /*!
03557  * \note expects the pvt to be locked
03558  */
03559 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03560 {
03561    unsigned short callno = pvt->callno;
03562 
03563    if (!pvt->peercallno) {
03564       /* We don't know the remote side's call number, yet.  :( */
03565       int count = 10;
03566       while (count-- && pvt && !pvt->peercallno) {
03567          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03568          pvt = iaxs[callno];
03569       }
03570       if (!pvt->peercallno) {
03571          return -1;
03572       }
03573    }
03574 
03575    return 0;
03576 }
03577 
03578 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03579 {
03580    struct ast_option_header *h;
03581    int res;
03582 
03583    switch (option) {
03584    case AST_OPTION_TXGAIN:
03585    case AST_OPTION_RXGAIN:
03586       /* these two cannot be sent, because they require a result */
03587       errno = ENOSYS;
03588       return -1;
03589    default:
03590    {
03591       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03592       struct chan_iax2_pvt *pvt;
03593 
03594       ast_mutex_lock(&iaxsl[callno]);
03595       pvt = iaxs[callno];
03596 
03597       if (wait_for_peercallno(pvt)) {
03598          ast_mutex_unlock(&iaxsl[callno]);
03599          return -1;
03600       }
03601 
03602       ast_mutex_unlock(&iaxsl[callno]);
03603 
03604       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03605          return -1;
03606       }
03607 
03608       h->flag = AST_OPTION_FLAG_REQUEST;
03609       h->option = htons(option);
03610       memcpy(h->data, data, datalen);
03611       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03612                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03613                  datalen + sizeof(*h), -1);
03614       free(h);
03615       return res;
03616    }
03617    }
03618 }
03619 
03620 static struct ast_frame *iax2_read(struct ast_channel *c) 
03621 {
03622    ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
03623    return NULL;
03624 }
03625 
03626 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03627 {
03628    int res;
03629    struct iax_ie_data ied0;
03630    struct iax_ie_data ied1;
03631    unsigned int transferid = (unsigned int)ast_random();
03632    memset(&ied0, 0, sizeof(ied0));
03633    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03634    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03635    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03636 
03637    memset(&ied1, 0, sizeof(ied1));
03638    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03639    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03640    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03641    
03642    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03643    if (res)
03644       return -1;
03645    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03646    if (res)
03647       return -1;
03648    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03649    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03650    return 0;
03651 }
03652 
03653 static void lock_both(unsigned short callno0, unsigned short callno1)
03654 {
03655    ast_mutex_lock(&iaxsl[callno0]);
03656    while (ast_mutex_trylock(&iaxsl[callno1])) {
03657       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03658    }
03659 }
03660 
03661 static void unlock_both(unsigned short callno0, unsigned short callno1)
03662 {
03663    ast_mutex_unlock(&iaxsl[callno1]);
03664    ast_mutex_unlock(&iaxsl[callno0]);
03665 }
03666 
03667 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)
03668 {
03669    struct ast_channel *cs[3];
03670    struct ast_channel *who, *other;
03671    int to = -1;
03672    int res = -1;
03673    int transferstarted=0;
03674    struct ast_frame *f;
03675    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03676    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03677    struct timeval waittimer = {0, 0}, tv;
03678 
03679    lock_both(callno0, callno1);
03680    if (!iaxs[callno0] || !iaxs[callno1]) {
03681       unlock_both(callno0, callno1);
03682       return AST_BRIDGE_FAILED;
03683    }
03684    /* Put them in native bridge mode */
03685    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03686       iaxs[callno0]->bridgecallno = callno1;
03687       iaxs[callno1]->bridgecallno = callno0;
03688    }
03689    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
03690    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
03691       transferstarted = 1;
03692    }
03693    unlock_both(callno0, callno1);
03694 
03695    /* If not, try to bridge until we can execute a transfer, if we can */
03696    cs[0] = c0;
03697    cs[1] = c1;
03698    for (/* ever */;;) {
03699       /* Check in case we got masqueraded into */
03700       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03701          if (option_verbose > 2)
03702             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03703          /* Remove from native mode */
03704          if (c0->tech == &iax2_tech) {
03705             ast_mutex_lock(&iaxsl[callno0]);
03706             iaxs[callno0]->bridgecallno = 0;
03707             ast_mutex_unlock(&iaxsl[callno0]);
03708          }
03709          if (c1->tech == &iax2_tech) {
03710             ast_mutex_lock(&iaxsl[callno1]);
03711             iaxs[callno1]->bridgecallno = 0;
03712             ast_mutex_unlock(&iaxsl[callno1]);
03713          }
03714          return AST_BRIDGE_FAILED_NOWARN;
03715       }
03716       if (c0->nativeformats != c1->nativeformats) {
03717          if (option_verbose > 2) {
03718             char buf0[255];
03719             char buf1[255];
03720             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03721             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03722             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03723          }
03724          /* Remove from native mode */
03725          lock_both(callno0, callno1);
03726          if (iaxs[callno0])
03727             iaxs[callno0]->bridgecallno = 0;
03728          if (iaxs[callno1])
03729             iaxs[callno1]->bridgecallno = 0;
03730          unlock_both(callno0, callno1);
03731          return AST_BRIDGE_FAILED_NOWARN;
03732       }
03733       /* check if transfered and if we really want native bridging */
03734       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03735          /* Try the transfer */
03736          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03737                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03738             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03739          transferstarted = 1;
03740       }
03741       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03742          /* Call has been transferred.  We're no longer involved */
03743          gettimeofday(&tv, NULL);
03744          if (ast_tvzero(waittimer)) {
03745             waittimer = tv;
03746          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03747             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03748             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03749             *fo = NULL;
03750             *rc = c0;
03751             res = AST_BRIDGE_COMPLETE;
03752             break;
03753          }
03754       }
03755       to = 1000;
03756       who = ast_waitfor_n(cs, 2, &to);
03757       if (timeoutms > -1) {
03758          timeoutms -= (1000 - to);
03759          if (timeoutms < 0)
03760             timeoutms = 0;
03761       }
03762       if (!who) {
03763          if (!timeoutms) {
03764             res = AST_BRIDGE_RETRY;
03765             break;
03766          }
03767          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03768             res = AST_BRIDGE_FAILED;
03769             break;
03770          }
03771          continue;
03772       }
03773       f = ast_read(who);
03774       if (!f) {
03775          *fo = NULL;
03776          *rc = who;
03777          res = AST_BRIDGE_COMPLETE;
03778          break;
03779       }
03780       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
03781          *fo = f;
03782          *rc = who;
03783          res =  AST_BRIDGE_COMPLETE;
03784          break;
03785       }
03786       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03787       if ((f->frametype == AST_FRAME_VOICE) ||
03788          (f->frametype == AST_FRAME_TEXT) ||
03789          (f->frametype == AST_FRAME_VIDEO) || 
03790          (f->frametype == AST_FRAME_IMAGE) ||
03791          (f->frametype == AST_FRAME_DTMF) ||
03792          (f->frametype == AST_FRAME_CONTROL)) {
03793          /* monitored dtmf take out of the bridge.
03794           * check if we monitor the specific source.
03795           */
03796          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03797          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03798             *rc = who;
03799             *fo = f;
03800             res = AST_BRIDGE_COMPLETE;
03801             /* Remove from native mode */
03802             break;
03803          }
03804          /* everything else goes to the other side */
03805          ast_write(other, f);
03806       }
03807       ast_frfree(f);
03808       /* Swap who gets priority */
03809       cs[2] = cs[0];
03810       cs[0] = cs[1];
03811       cs[1] = cs[2];
03812    }
03813    lock_both(callno0, callno1);
03814    if(iaxs[callno0])
03815       iaxs[callno0]->bridgecallno = 0;
03816    if(iaxs[callno1])
03817       iaxs[callno1]->bridgecallno = 0;
03818    unlock_both(callno0, callno1);
03819    return res;
03820 }
03821 
03822 static int iax2_answer(struct ast_channel *c)
03823 {
03824    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03825    if (option_debug)
03826       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03827    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03828 }
03829 
03830 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03831 {
03832    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03833    struct chan_iax2_pvt *pvt;
03834    int res = 0;
03835 
03836    if (option_debug && iaxdebug)
03837       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03838 
03839    ast_mutex_lock(&iaxsl[callno]);
03840    pvt = iaxs[callno];
03841 
03842    if (wait_for_peercallno(pvt)) {
03843       res = -1;
03844       goto done;
03845    }
03846 
03847    switch (condition) {
03848    case AST_CONTROL_HOLD:
03849       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03850          ast_moh_start(c, data, pvt->mohinterpret);
03851          goto done;
03852       }
03853       break;
03854    case AST_CONTROL_UNHOLD:
03855       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03856          ast_moh_stop(c);
03857          goto done;
03858       }
03859    }
03860 
03861    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03862 
03863 done:
03864    ast_mutex_unlock(&iaxsl[callno]);
03865 
03866    return res;
03867 }
03868    
03869 static int iax2_transfer(struct ast_channel *c, const char *dest)
03870 {
03871    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03872    struct iax_ie_data ied;
03873    char tmp[256], *context;
03874    ast_copy_string(tmp, dest, sizeof(tmp));
03875    context = strchr(tmp, '@');
03876    if (context) {
03877       *context = '\0';
03878       context++;
03879    }
03880    memset(&ied, 0, sizeof(ied));
03881    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03882    if (context)
03883       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03884    if (option_debug)
03885       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03886    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03887 }
03888    
03889 static int iax2_getpeertrunk(struct sockaddr_in sin)
03890 {
03891    struct iax2_peer *peer;
03892    int res = 0;
03893    struct ao2_iterator i;
03894 
03895    i = ao2_iterator_init(peers, 0);
03896    while ((peer = ao2_iterator_next(&i))) {
03897       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03898           (peer->addr.sin_port == sin.sin_port)) {
03899          res = ast_test_flag(peer, IAX_TRUNK);
03900          peer_unref(peer);
03901          break;
03902       }
03903       peer_unref(peer);
03904    }
03905 
03906    return res;
03907 }
03908 
03909 /*! \brief  Create new call, interface with the PBX core */
03910 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03911 {
03912    struct ast_channel *tmp;
03913    struct chan_iax2_pvt *i;
03914    struct ast_variable *v = NULL;
03915 
03916    if (!(i = iaxs[callno])) {
03917       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03918       return NULL;
03919    }
03920 
03921    /* Don't hold call lock */
03922    ast_mutex_unlock(&iaxsl[callno]);
03923    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);
03924    ast_mutex_lock(&iaxsl[callno]);
03925    if (i != iaxs[callno]) {
03926       if (tmp) {
03927          /* unlock and relock iaxsl[callno] to preserve locking order */
03928          ast_mutex_unlock(&iaxsl[callno]);
03929          ast_channel_free(tmp);
03930          ast_mutex_lock(&iaxsl[callno]);
03931       }
03932       return NULL;
03933    }
03934 
03935    if (!tmp)
03936       return NULL;
03937    tmp->tech = &iax2_tech;
03938    /* We can support any format by default, until we get restricted */
03939    tmp->nativeformats = capability;
03940    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
03941    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
03942    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03943 
03944    /* Don't use ast_set_callerid() here because it will
03945     * generate a NewCallerID event before the NewChannel event */
03946    if (!ast_strlen_zero(i->ani))
03947       tmp->cid.cid_ani = ast_strdup(i->ani);
03948    else
03949       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03950    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03951    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03952    tmp->cid.cid_pres = i->calling_pres;
03953    tmp->cid.cid_ton = i->calling_ton;
03954    tmp->cid.cid_tns = i->calling_tns;
03955    if (!ast_strlen_zero(i->language))
03956       ast_string_field_set(tmp, language, i->language);
03957    if (!ast_strlen_zero(i->accountcode))
03958       ast_string_field_set(tmp, accountcode, i->accountcode);
03959    if (i->amaflags)
03960       tmp->amaflags = i->amaflags;
03961    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03962    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03963    if (i->adsi)
03964       tmp->adsicpe = i->peeradsicpe;
03965    else
03966       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03967    i->owner = tmp;
03968    i->capability = capability;
03969 
03970    for (v = i->vars ; v ; v = v->next)
03971       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03972 
03973    if (state != AST_STATE_DOWN) {
03974       if (ast_pbx_start(tmp)) {
03975          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03976          ast_hangup(tmp);
03977          i->owner = NULL;
03978          return NULL;
03979       }
03980    }
03981 
03982    ast_module_ref(ast_module_info->self);
03983    
03984    return tmp;
03985 }
03986 
03987 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03988 {
03989    unsigned long int mssincetx; /* unsigned to handle overflows */
03990    long int ms, pred;
03991 
03992    tpeer->trunkact = *tv;
03993    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03994    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03995       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03996       tpeer->txtrunktime = *tv;
03997       tpeer->lastsent = 999999;
03998    }
03999    /* Update last transmit time now */
04000    tpeer->lasttxtime = *tv;
04001    
04002    /* Calculate ms offset */
04003    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04004    /* Predict from last value */
04005    pred = tpeer->lastsent + sampms;
04006    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04007       ms = pred;
04008    
04009    /* We never send the same timestamp twice, so fudge a little if we must */
04010    if (ms == tpeer->lastsent)
04011       ms = tpeer->lastsent + 1;
04012    tpeer->lastsent = ms;
04013    return ms;
04014 }
04015 
04016 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
04017 {
04018    long ms; /* NOT unsigned */
04019    if (ast_tvzero(iaxs[callno]->rxcore)) {
04020       /* Initialize rxcore time if appropriate */
04021       gettimeofday(&iaxs[callno]->rxcore, NULL);
04022       /* Round to nearest 20ms so traces look pretty */
04023       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04024    }
04025    /* Calculate difference between trunk and channel */
04026    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04027    /* Return as the sum of trunk time and the difference between trunk and real time */
04028    return ms + ts;
04029 }
04030 
04031 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04032 {
04033    int ms;
04034    int voice = 0;
04035    int genuine = 0;
04036    int adjust;
04037    struct timeval *delivery = NULL;
04038 
04039 
04040    /* What sort of frame do we have?: voice is self-explanatory
04041       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
04042       non-genuine frames are CONTROL frames [ringing etc], DTMF
04043       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
04044       the others need a timestamp slaved to the voice frames so that they go in sequence
04045    */
04046    if (f) {
04047       if (f->frametype == AST_FRAME_VOICE) {
04048          voice = 1;
04049          delivery = &f->delivery;
04050       } else if (f->frametype == AST_FRAME_IAX) {
04051          genuine = 1;
04052       } else if (f->frametype == AST_FRAME_CNG) {
04053          p->notsilenttx = 0;  
04054       }
04055    }
04056    if (ast_tvzero(p->offset)) {
04057       gettimeofday(&p->offset, NULL);
04058       /* Round to nearest 20ms for nice looking traces */
04059       p->offset.tv_usec -= p->offset.tv_usec % 20000;
04060    }
04061    /* If the timestamp is specified, just send it as is */
04062    if (ts)
04063       return ts;
04064    /* If we have a time that the frame arrived, always use it to make our timestamp */
04065    if (delivery && !ast_tvzero(*delivery)) {
04066       ms = ast_tvdiff_ms(*delivery, p->offset);
04067       if (option_debug > 2 && iaxdebug)
04068          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04069    } else {
04070       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04071       if (ms < 0)
04072          ms = 0;
04073       if (voice) {
04074          /* On a voice frame, use predicted values if appropriate */
04075          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04076             /* Adjust our txcore, keeping voice and non-voice synchronized */
04077             /* AN EXPLANATION:
04078                When we send voice, we usually send "calculated" timestamps worked out
04079                on the basis of the number of samples sent. When we send other frames,
04080                we usually send timestamps worked out from the real clock.
04081                The problem is that they can tend to drift out of step because the 
04082                   source channel's clock and our clock may not be exactly at the same rate.
04083                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
04084                for this call.  Moving it adjusts timestamps for non-voice frames.
04085                We make the adjustment in the style of a moving average.  Each time we
04086                adjust p->offset by 10% of the difference between our clock-derived
04087                timestamp and the predicted timestamp.  That's why you see "10000"
04088                below even though IAX2 timestamps are in milliseconds.
04089                The use of a moving average avoids offset moving too radically.
04090                Generally, "adjust" roams back and forth around 0, with offset hardly
04091                changing at all.  But if a consistent different starts to develop it
04092                will be eliminated over the course of 10 frames (200-300msecs) 
04093             */
04094             adjust = (ms - p->nextpred);
04095             if (adjust < 0)
04096                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04097             else if (adjust > 0)
04098                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04099 
04100             if (!p->nextpred) {
04101                p->nextpred = ms; /*f->samples / 8;*/
04102                if (p->nextpred <= p->lastsent)
04103                   p->nextpred = p->lastsent + 3;
04104             }
04105             ms = p->nextpred;
04106          } else {
04107                 /* in this case, just use the actual
04108             * time, since we're either way off
04109             * (shouldn't happen), or we're  ending a
04110             * silent period -- and seed the next
04111             * predicted time.  Also, round ms to the
04112             * next multiple of frame size (so our
04113             * silent periods are multiples of
04114             * frame size too) */
04115 
04116             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04117                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04118                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04119 
04120             if (f->samples >= 8) /* check to make sure we dont core dump */
04121             {
04122                int diff = ms % (f->samples / 8);
04123                if (diff)
04124                    ms += f->samples/8 - diff;
04125             }
04126 
04127             p->nextpred = ms;
04128             p->notsilenttx = 1;
04129          }
04130       } else if ( f->frametype == AST_FRAME_VIDEO ) {
04131          /*
04132          * IAX2 draft 03 says that timestamps MUST be in order.
04133          * It does not say anything about several frames having the same timestamp
04134          * When transporting video, we can have a frame that spans multiple iax packets
04135          * (so called slices), so it would make sense to use the same timestamp for all of
04136          * them
04137          * We do want to make sure that frames don't go backwards though
04138          */
04139          if ( (unsigned int)ms < p->lastsent )
04140             ms = p->lastsent;
04141       } else {
04142          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
04143             it's a genuine frame */
04144          if (genuine) {
04145             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
04146             if (ms <= p->lastsent)
04147                ms = p->lastsent + 3;
04148          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04149             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
04150             ms = p->lastsent + 3;
04151          }
04152       }
04153    }
04154    p->lastsent = ms;
04155    if (voice)
04156       p->nextpred = p->nextpred + f->samples / 8;
04157    return ms;
04158 }
04159 
04160 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04161 {
04162    /* Returns where in "receive time" we are.  That is, how many ms
04163       since we received (or would have received) the frame with timestamp 0 */
04164    int ms;
04165 #ifdef IAXTESTS
04166    int jit;
04167 #endif /* IAXTESTS */
04168    /* Setup rxcore if necessary */
04169    if (ast_tvzero(p->rxcore)) {
04170       p->rxcore = ast_tvnow();
04171       if (option_debug && iaxdebug)
04172          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04173                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04174       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04175 #if 1
04176       if (option_debug && iaxdebug)
04177          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04178                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04179 #endif
04180    }
04181 
04182    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04183 #ifdef IAXTESTS
04184    if (test_jit) {
04185       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04186          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04187          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04188             jit = -jit;
04189          ms += jit;
04190       }
04191    }
04192    if (test_late) {
04193       ms += test_late;
04194       test_late = 0;
04195    }
04196 #endif /* IAXTESTS */
04197    return ms;
04198 }
04199 
04200 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04201 {
04202    struct iax2_trunk_peer *tpeer;
04203    
04204    /* Finds and locks trunk peer */
04205    ast_mutex_lock(&tpeerlock);
04206    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04207       /* We don't lock here because tpeer->addr *never* changes */
04208       if (!inaddrcmp(&tpeer->addr, sin)) {
04209          ast_mutex_lock(&tpeer->lock);
04210          break;
04211       }
04212    }
04213    if (!tpeer) {
04214       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04215          ast_mutex_init(&tpeer->lock);
04216          tpeer->lastsent = 9999;
04217          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04218          tpeer->trunkact = ast_tvnow();
04219          ast_mutex_lock(&tpeer->lock);
04220          tpeer->next = tpeers;
04221          tpeer->sockfd = fd;
04222          tpeers = tpeer;
04223 #ifdef SO_NO_CHECK
04224          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04225 #endif
04226          if (option_debug)
04227             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04228       }
04229    }
04230    ast_mutex_unlock(&tpeerlock);
04231    return tpeer;
04232 }
04233 
04234 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04235 {
04236    struct ast_frame *f;
04237    struct iax2_trunk_peer *tpeer;
04238    void *tmp, *ptr;
04239    struct ast_iax2_meta_trunk_entry *met;
04240    struct ast_iax2_meta_trunk_mini *mtm;
04241 
04242    f = &fr->af;
04243    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04244    if (tpeer) {
04245       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04246          /* Need to reallocate space */
04247          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04248             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04249                ast_mutex_unlock(&tpeer->lock);
04250                return -1;
04251             }
04252             
04253             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04254             tpeer->trunkdata = tmp;
04255             if (option_debug)
04256                ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
04257          } else {
04258             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));
04259             ast_mutex_unlock(&tpeer->lock);
04260             return -1;
04261          }
04262       }
04263 
04264       /* Append to meta frame */
04265       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04266       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04267          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04268          mtm->len = htons(f->datalen);
04269          mtm->mini.callno = htons(pvt->callno);
04270          mtm->mini.ts = htons(0xffff & fr->ts);
04271          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04272          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04273       } else {
04274          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04275          /* Store call number and length in meta header */
04276          met->callno = htons(pvt->callno);
04277          met->len = htons(f->datalen);
04278          /* Advance pointers/decrease length past trunk entry header */
04279          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04280          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04281       }
04282       /* Copy actual trunk data */
04283       memcpy(ptr, f->data, f->datalen);
04284       tpeer->trunkdatalen += f->datalen;
04285 
04286       tpeer->calls++;
04287       ast_mutex_unlock(&tpeer->lock);
04288    }
04289    return 0;
04290 }
04291 
04292 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04293 {
04294    aes_encrypt_key128(digest, ecx);
04295    aes_decrypt_key128(digest, dcx);
04296 }
04297 
04298 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04299 {
04300 #if 0
04301    /* Debug with "fake encryption" */
04302    int x;
04303    if (len % 16)
04304       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04305    for (x=0;x<len;x++)
04306       dst[x] = src[x] ^ 0xff;
04307 #else 
04308    unsigned char lastblock[16] = { 0 };
04309    int x;
04310    while(len > 0) {
04311       aes_decrypt(src, dst, dcx);
04312       for (x=0;x<16;x++)
04313          dst[x] ^= lastblock[x];
04314       memcpy(lastblock, src, sizeof(lastblock));
04315       dst += 16;
04316       src += 16;
04317       len -= 16;
04318    }
04319 #endif
04320 }
04321 
04322 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04323 {
04324 #if 0
04325    /* Debug with "fake encryption" */
04326    int x;
04327    if (len % 16)
04328       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04329    for (x=0;x<len;x++)
04330       dst[x] = src[x] ^ 0xff;
04331 #else
04332    unsigned char curblock[16] = { 0 };
04333    int x;
04334    while(len > 0) {
04335       for (x=0;x<16;x++)
04336          curblock[x] ^= src[x];
04337       aes_encrypt(curblock, dst, ecx);
04338       memcpy(curblock, dst, sizeof(curblock)); 
04339       dst += 16;
04340       src += 16;
04341       len -= 16;
04342    }
04343 #endif
04344 }
04345 
04346 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04347 {
04348    int padding;
04349    unsigned char *workspace;
04350 
04351    workspace = alloca(*datalen);
04352    memset(f, 0, sizeof(*f));
04353    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04354       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04355       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04356          return -1;
04357       /* Decrypt */
04358       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04359 
04360       padding = 16 + (workspace[15] & 0xf);
04361       if (option_debug && iaxdebug)
04362          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04363       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04364          return -1;
04365 
04366       *datalen -= padding;
04367       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04368       f->frametype = fh->type;
04369       if (f->frametype == AST_FRAME_VIDEO) {
04370          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04371       } else {
04372          f->subclass = uncompress_subclass(fh->csub);
04373       }
04374    } else {
04375       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04376       if (option_debug && iaxdebug)
04377          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04378       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04379          return -1;
04380       /* Decrypt */
04381       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04382       padding = 16 + (workspace[15] & 0x0f);
04383       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04384          return -1;
04385       *datalen -= padding;
04386       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04387    }
04388    return 0;
04389 }
04390 
04391 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04392 {
04393    int padding;
04394    unsigned char *workspace;
04395    workspace = alloca(*datalen + 32);
04396    if (!workspace)
04397       return -1;
04398    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04399       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04400       if (option_debug && iaxdebug)
04401          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04402       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04403       padding = 16 + (padding & 0xf);
04404       memcpy(workspace, poo, padding);
04405       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04406       workspace[15] &= 0xf0;
04407       workspace[15] |= (padding & 0xf);
04408       if (option_debug && iaxdebug)
04409          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04410       *datalen += padding;
04411       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04412       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04413          memcpy(poo, workspace + *datalen - 32, 32);
04414    } else {
04415       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04416       if (option_debug && iaxdebug)
04417          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04418       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04419       padding = 16 + (padding & 0xf);
04420       memcpy(workspace, poo, padding);
04421       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04422       workspace[15] &= 0xf0;
04423       workspace[15] |= (padding & 0x0f);
04424       *datalen += padding;
04425       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04426       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04427          memcpy(poo, workspace + *datalen - 32, 32);
04428    }
04429    return 0;
04430 }
04431 
04432 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04433 {
04434    int res=-1;
04435    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04436       /* Search for possible keys, given secrets */
04437       struct MD5Context md5;
04438       unsigned char digest[16];
04439       char *tmppw, *stringp;
04440       
04441       tmppw = ast_strdupa(iaxs[callno]->secret);
04442       stringp = tmppw;
04443       while ((tmppw = strsep(&stringp, ";"))) {
04444          MD5Init(&md5);
04445          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04446          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04447          MD5Final(digest, &md5);
04448          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04449          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04450          if (!res) {
04451             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04452             break;
04453          }
04454       }
04455    } else 
04456       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04457    return res;
04458 }
04459 
04460 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04461 {
04462    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04463       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04464       or delayed, with retransmission */
04465    struct ast_iax2_full_hdr *fh;
04466    struct ast_iax2_mini_hdr *mh;
04467    struct ast_iax2_video_hdr *vh;
04468    struct {
04469       struct iax_frame fr2;
04470       unsigned char buffer[4096];
04471    } frb;
04472    struct iax_frame *fr;
04473    int res;
04474    int sendmini=0;
04475    unsigned int lastsent;
04476    unsigned int fts;
04477 
04478    frb.fr2.afdatalen = sizeof(frb.buffer);
04479 
04480    if (!pvt) {
04481       ast_log(LOG_WARNING, "No private structure for packet?\n");
04482       return -1;
04483    }
04484    
04485    lastsent = pvt->lastsent;
04486 
04487    /* Calculate actual timestamp */
04488    fts = calc_timestamp(pvt, ts, f);
04489 
04490    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04491     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04492     * increment the "predicted timestamps" for voice, if we're predecting */
04493    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04494        return 0;
04495 
04496 
04497    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04498          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04499          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04500       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04501        (f->frametype == AST_FRAME_VOICE) 
04502       /* is a voice frame */ &&
04503       (f->subclass == pvt->svoiceformat) 
04504       /* is the same type */ ) {
04505          /* Force immediate rather than delayed transmission */
04506          now = 1;
04507          /* Mark that mini-style frame is appropriate */
04508          sendmini = 1;
04509    }
04510    if ( f->frametype == AST_FRAME_VIDEO ) {
04511       /*
04512        * If the lower 15 bits of the timestamp roll over, or if
04513        * the video format changed then send a full frame.
04514        * Otherwise send a mini video frame
04515        */
04516       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04517           ((f->subclass & ~0x1) == pvt->svideoformat)
04518          ) {
04519          now = 1;
04520          sendmini = 1;
04521       } else {
04522          now = 0;
04523          sendmini = 0;
04524       }
04525       pvt->lastvsent = fts;
04526    }
04527    /* Allocate an iax_frame */
04528    if (now) {
04529       fr = &frb.fr2;
04530    } else
04531       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));
04532    if (!fr) {
04533       ast_log(LOG_WARNING, "Out of memory\n");
04534       return -1;
04535    }
04536    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04537    iax_frame_wrap(fr, f);
04538 
04539    fr->ts = fts;
04540    fr->callno = pvt->callno;
04541    fr->transfer = transfer;
04542    fr->final = final;
04543    if (!sendmini) {
04544       /* We need a full frame */
04545       if (seqno > -1)
04546          fr->oseqno = seqno;
04547       else
04548          fr->oseqno = pvt->oseqno++;
04549       fr->iseqno = pvt->iseqno;
04550       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04551       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04552       fh->ts = htonl(fr->ts);
04553       fh->oseqno = fr->oseqno;
04554       if (transfer) {
04555          fh->iseqno = 0;
04556       } else
04557          fh->iseqno = fr->iseqno;
04558       /* Keep track of the last thing we've acknowledged */
04559       if (!transfer)
04560          pvt->aseqno = fr->iseqno;
04561       fh->type = fr->af.frametype & 0xFF;
04562       if (fr->af.frametype == AST_FRAME_VIDEO)
04563          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04564       else
04565          fh->csub = compress_subclass(fr->af.subclass);
04566       if (transfer) {
04567          fr->dcallno = pvt->transfercallno;
04568       } else
04569          fr->dcallno = pvt->peercallno;
04570       fh->dcallno = htons(fr->dcallno);
04571       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04572       fr->data = fh;
04573       fr->retries = 0;
04574       /* Retry after 2x the ping time has passed */
04575       fr->retrytime = pvt->pingtime * 2;
04576       if (fr->retrytime < MIN_RETRY_TIME)
04577          fr->retrytime = MIN_RETRY_TIME;
04578       if (fr->retrytime > MAX_RETRY_TIME)
04579          fr->retrytime = MAX_RETRY_TIME;
04580       /* Acks' don't get retried */
04581       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04582          fr->retries = -1;
04583       else if (f->frametype == AST_FRAME_VOICE)
04584          pvt->svoiceformat = f->subclass;
04585       else if (f->frametype == AST_FRAME_VIDEO)
04586          pvt->svideoformat = f->subclass & ~0x1;
04587       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04588          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04589             if (iaxdebug) {
04590                if (fr->transfer)
04591                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04592                else
04593                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04594             }
04595             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04596          } else
04597             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04598       }
04599    
04600       if (now) {
04601          res = send_packet(fr);
04602       } else
04603          res = iax2_transmit(fr);
04604    } else {
04605       if (ast_test_flag(pvt, IAX_TRUNK)) {
04606          iax2_trunk_queue(pvt, fr);
04607          res = 0;
04608       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04609          /* Video frame have no sequence number */
04610          fr->oseqno = -1;
04611          fr->iseqno = -1;
04612          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04613          vh->zeros = 0;
04614          vh->callno = htons(0x8000 | fr->callno);
04615          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04616          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04617          fr->data = vh;
04618          fr->retries = -1;
04619          res = send_packet(fr);        
04620       } else {
04621          /* Mini-frames have no sequence number */
04622          fr->oseqno = -1;
04623          fr->iseqno = -1;
04624          /* Mini frame will do */
04625          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04626          mh->callno = htons(fr->callno);
04627          mh->ts = htons(fr->ts & 0xFFFF);
04628          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04629          fr->data = mh;
04630          fr->retries = -1;
04631          if (pvt->transferring == TRANSFER_MEDIAPASS)
04632             fr->transfer = 1;
04633          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04634             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04635                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04636             } else
04637                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04638          }
04639          res = send_packet(fr);
04640       }
04641    }
04642    return res;
04643 }
04644 
04645 static int iax2_show_users(int fd, int argc, char *argv[])
04646 {
04647    regex_t regexbuf;
04648    int havepattern = 0;
04649 
04650 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04651 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04652 
04653    struct iax2_user *user = NULL;
04654    char auth[90];
04655    char *pstr = "";
04656    struct ao2_iterator i;
04657 
04658    switch (argc) {
04659    case 5:
04660       if (!strcasecmp(argv[3], "like")) {
04661          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04662             return RESULT_SHOWUSAGE;
04663          havepattern = 1;
04664       } else
04665          return RESULT_SHOWUSAGE;
04666    case 3:
04667       break;
04668    default:
04669       return RESULT_SHOWUSAGE;
04670    }
04671 
04672    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04673    i = ao2_iterator_init(users, 0);
04674    for (user = ao2_iterator_next(&i); user; 
04675       user_unref(user), user = ao2_iterator_next(&i)) {
04676       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04677          continue;
04678       
04679       if (!ast_strlen_zero(user->secret)) {
04680          ast_copy_string(auth,user->secret,sizeof(auth));
04681       } else if (!ast_strlen_zero(user->inkeys)) {
04682          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04683       } else
04684          ast_copy_string(auth, "-no secret-", sizeof(auth));
04685       
04686       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04687          pstr = "REQ Only";
04688       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04689          pstr = "Disabled";
04690       else
04691          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04692       
04693       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04694          user->contexts ? user->contexts->context : context,
04695          user->ha ? "Yes" : "No", pstr);
04696    }
04697 
04698    if (havepattern)
04699       regfree(&regexbuf);
04700 
04701    return RESULT_SUCCESS;
04702 #undef FORMAT
04703 #undef FORMAT2
04704 }
04705 
04706 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04707 {
04708    regex_t regexbuf;
04709    int havepattern = 0;
04710    int total_peers = 0;
04711    int online_peers = 0;
04712    int offline_peers = 0;
04713    int unmonitored_peers = 0;
04714    struct ao2_iterator i;
04715 
04716 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04717 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04718 
04719    struct iax2_peer *peer = NULL;
04720    char name[256];
04721    int registeredonly=0;
04722    char *term = manager ? "\r\n" : "\n";
04723 
04724    switch (argc) {
04725    case 6:
04726       if (!strcasecmp(argv[3], "registered"))
04727          registeredonly = 1;
04728       else
04729          return RESULT_SHOWUSAGE;
04730       if (!strcasecmp(argv[4], "like")) {
04731          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04732             return RESULT_SHOWUSAGE;
04733          havepattern = 1;
04734       } else
04735          return RESULT_SHOWUSAGE;
04736       break;
04737    case 5:
04738       if (!strcasecmp(argv[3], "like")) {
04739          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04740             return RESULT_SHOWUSAGE;
04741          havepattern = 1;
04742       } else
04743          return RESULT_SHOWUSAGE;
04744       break;
04745    case 4:
04746       if (!strcasecmp(argv[3], "registered"))
04747          registeredonly = 1;
04748       else
04749          return RESULT_SHOWUSAGE;
04750       break;
04751    case 3:
04752       break;
04753    default:
04754       return RESULT_SHOWUSAGE;
04755    }
04756 
04757 
04758    if (s)
04759       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04760    else
04761       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04762 
04763    i = ao2_iterator_init(peers, 0);
04764    for (peer = ao2_iterator_next(&i); peer; 
04765       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04766       char nm[20];
04767       char status[20];
04768       char srch[2000];
04769       int retstatus;
04770 
04771       if (registeredonly && !peer->addr.sin_addr.s_addr)
04772          continue;
04773       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04774          continue;
04775 
04776       if (!ast_strlen_zero(peer->username))
04777          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04778       else
04779          ast_copy_string(name, peer->name, sizeof(name));
04780       
04781       retstatus = peer_status(peer, status, sizeof(status));
04782       if (retstatus > 0)
04783          online_peers++;
04784       else if (!retstatus)
04785          offline_peers++;
04786       else
04787          unmonitored_peers++;
04788       
04789       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04790       
04791       snprintf(srch, sizeof(srch), FORMAT, name, 
04792           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04793           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04794           nm,
04795           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04796           peer->encmethods ? "(E)" : "   ", status, term);
04797       
04798       if (s)
04799          astman_append(s, FORMAT, name, 
04800                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04801                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04802                   nm,
04803                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04804                   peer->encmethods ? "(E)" : "   ", status, term);
04805       else
04806          ast_cli(fd, FORMAT, name, 
04807             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04808             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04809             nm,
04810             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04811             peer->encmethods ? "(E)" : "   ", status, term);
04812       total_peers++;
04813    }
04814 
04815    if (s)
04816       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04817    else
04818       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04819 
04820    if (havepattern)
04821       regfree(&regexbuf);
04822 
04823    return RESULT_SUCCESS;
04824 #undef FORMAT
04825 #undef FORMAT2
04826 }
04827 
04828 static int iax2_show_threads(int fd, int argc, char *argv[])
04829 {
04830    struct iax2_thread *thread = NULL;
04831    time_t t;
04832    int threadcount = 0, dynamiccount = 0;
04833    char type;
04834 
04835    if (argc != 3)
04836       return RESULT_SHOWUSAGE;
04837       
04838    ast_cli(fd, "IAX2 Thread Information\n");
04839    time(&t);
04840    ast_cli(fd, "Idle Threads:\n");
04841    AST_LIST_LOCK(&idle_list);
04842    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04843 #ifdef DEBUG_SCHED_MULTITHREAD
04844       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04845          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04846 #else
04847       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04848          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04849 #endif
04850       threadcount++;
04851    }
04852    AST_LIST_UNLOCK(&idle_list);
04853    ast_cli(fd, "Active Threads:\n");
04854    AST_LIST_LOCK(&active_list);
04855    AST_LIST_TRAVERSE(&active_list, thread, list) {
04856       if (thread->type == IAX_TYPE_DYNAMIC)
04857          type = 'D';
04858       else
04859          type = 'P';
04860 #ifdef DEBUG_SCHED_MULTITHREAD
04861       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04862          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04863 #else
04864       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04865          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04866 #endif
04867       threadcount++;
04868    }
04869    AST_LIST_UNLOCK(&active_list);
04870    ast_cli(fd, "Dynamic Threads:\n");
04871         AST_LIST_LOCK(&dynamic_list);
04872         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04873 #ifdef DEBUG_SCHED_MULTITHREAD
04874                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04875                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04876 #else
04877                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04878                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04879 #endif
04880       dynamiccount++;
04881         }
04882         AST_LIST_UNLOCK(&dynamic_list);
04883    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04884    return RESULT_SUCCESS;
04885 }
04886 
04887 static int iax2_show_peers(int fd, int argc, char *argv[])
04888 {
04889    return __iax2_show_peers(0, fd, NULL, argc, argv);
04890 }
04891 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04892 {
04893    ast_cli_netstats(s, -1, 0);
04894    astman_append(s, "\r\n");
04895    return RESULT_SUCCESS;
04896 }
04897 
04898 static int iax2_show_firmware(int fd, int argc, char *argv[])
04899 {
04900 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04901 #if !defined(__FreeBSD__)
04902 #define FORMAT "%-15.15s  %-15d %-15d\n"
04903 #else /* __FreeBSD__ */
04904 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04905 #endif /* __FreeBSD__ */
04906    struct iax_firmware *cur;
04907    if ((argc != 3) && (argc != 4))
04908       return RESULT_SHOWUSAGE;
04909    ast_mutex_lock(&waresl.lock);
04910    
04911    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04912    for (cur = waresl.wares;cur;cur = cur->next) {
04913       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04914          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04915             (int)ntohl(cur->fwh->datalen));
04916    }
04917    ast_mutex_unlock(&waresl.lock);
04918    return RESULT_SUCCESS;
04919 #undef FORMAT
04920 #undef FORMAT2
04921 }
04922 
04923 /* JDG: callback to display iax peers in manager */
04924 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04925 {
04926    char *a[] = { "iax2", "show", "users" };
04927    int ret;
04928    const char *id = astman_get_header(m,"ActionID");
04929 
04930    if (!ast_strlen_zero(id))
04931       astman_append(s, "ActionID: %s\r\n",id);
04932    ret = __iax2_show_peers(1, -1, s, 3, a );
04933    astman_append(s, "\r\n\r\n" );
04934    return ret;
04935 } /* /JDG */
04936 
04937 static char *regstate2str(int regstate)
04938 {
04939    switch(regstate) {
04940    case REG_STATE_UNREGISTERED:
04941       return "Unregistered";
04942    case REG_STATE_REGSENT:
04943       return "Request Sent";
04944    case REG_STATE_AUTHSENT:
04945       return "Auth. Sent";
04946    case REG_STATE_REGISTERED:
04947       return "Registered";
04948    case REG_STATE_REJECTED:
04949       return "Rejected";
04950    case REG_STATE_TIMEOUT:
04951       return "Timeout";
04952    case REG_STATE_NOAUTH:
04953       return "No Authentication";
04954    default:
04955       return "Unknown";
04956    }
04957 }
04958 
04959 static int iax2_show_registry(int fd, int argc, char *argv[])
04960 {
04961 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04962 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04963    struct iax2_registry *reg = NULL;
04964 
04965    char host[80];
04966    char perceived[80];
04967    if (argc != 3)
04968       return RESULT_SHOWUSAGE;
04969    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04970    AST_LIST_LOCK(&registrations);
04971    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04972       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04973       if (reg->us.sin_addr.s_addr) 
04974          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04975       else
04976          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04977       ast_cli(fd, FORMAT, host, 
04978                (reg->dnsmgr) ? "Y" : "N", 
04979                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04980    }
04981    AST_LIST_UNLOCK(&registrations);
04982    return RESULT_SUCCESS;
04983 #undef FORMAT
04984 #undef FORMAT2
04985 }
04986 
04987 static int iax2_show_channels(int fd, int argc, char *argv[])
04988 {
04989 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04990 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
04991 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04992    int x;
04993    int numchans = 0;
04994 
04995    if (argc != 3)
04996       return RESULT_SHOWUSAGE;
04997    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04998    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04999       ast_mutex_lock(&iaxsl[x]);
05000       if (iaxs[x]) {
05001          int lag, jitter, localdelay;
05002          jb_info jbinfo;
05003          
05004          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05005             jb_getinfo(iaxs[x]->jb, &jbinfo);
05006             jitter = jbinfo.jitter;
05007             localdelay = jbinfo.current - jbinfo.min;
05008          } else {
05009             jitter = -1;
05010             localdelay = 0;
05011          }
05012          lag = iaxs[x]->remote_rr.delay;
05013          ast_cli(fd, FORMAT,
05014             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05015             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
05016             S_OR(iaxs[x]->username, "(None)"),
05017             iaxs[x]->callno, iaxs[x]->peercallno,
05018             iaxs[x]->oseqno, iaxs[x]->iseqno,
05019             lag,
05020             jitter,
05021             localdelay,
05022             ast_getformatname(iaxs[x]->voiceformat) );
05023          numchans++;
05024       }
05025       ast_mutex_unlock(&iaxsl[x]);
05026    }
05027    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05028    return RESULT_SUCCESS;
05029 #undef FORMAT
05030 #undef FORMAT2
05031 #undef FORMATB
05032 }
05033 
05034 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05035 {
05036    int x;
05037    int numchans = 0;
05038    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05039       ast_mutex_lock(&iaxsl[x]);
05040       if (iaxs[x]) {
05041          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05042          char *fmt;
05043          jb_info jbinfo;
05044          
05045          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05046             jb_getinfo(iaxs[x]->jb, &jbinfo);
05047             localjitter = jbinfo.jitter;
05048             localdelay = jbinfo.current - jbinfo.min;
05049             locallost = jbinfo.frames_lost;
05050             locallosspct = jbinfo.losspct/1000;
05051             localdropped = jbinfo.frames_dropped;
05052             localooo = jbinfo.frames_ooo;
05053          } else {
05054             localjitter = -1;
05055             localdelay = 0;
05056             locallost = -1;
05057             locallosspct = -1;
05058             localdropped = 0;
05059             localooo = -1;
05060          }
05061          if (limit_fmt)
05062             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
05063          else
05064             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
05065          if (s)
05066             
05067             astman_append(s, fmt,
05068                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05069                      iaxs[x]->pingtime,
05070                      localjitter, 
05071                      localdelay,
05072                      locallost,
05073                      locallosspct,
05074                      localdropped,
05075                      localooo,
05076                      iaxs[x]->frames_received/1000,
05077                      iaxs[x]->remote_rr.jitter,
05078                      iaxs[x]->remote_rr.delay,
05079                      iaxs[x]->remote_rr.losscnt,
05080                      iaxs[x]->remote_rr.losspct,
05081                      iaxs[x]->remote_rr.dropped,
05082                      iaxs[x]->remote_rr.ooo,
05083                      iaxs[x]->remote_rr.packets/1000);
05084          else
05085             ast_cli(fd, fmt,
05086                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05087                iaxs[x]->pingtime,
05088                localjitter, 
05089                localdelay,
05090                locallost,
05091                locallosspct,
05092                localdropped,
05093                localooo,
05094                iaxs[x]->frames_received/1000,
05095                iaxs[x]->remote_rr.jitter,
05096                iaxs[x]->remote_rr.delay,
05097                iaxs[x]->remote_rr.losscnt,
05098                iaxs[x]->remote_rr.losspct,
05099                iaxs[x]->remote_rr.dropped,
05100                iaxs[x]->remote_rr.ooo,
05101                iaxs[x]->remote_rr.packets/1000
05102                );
05103          numchans++;
05104       }
05105       ast_mutex_unlock(&iaxsl[x]);
05106    }
05107    return numchans;
05108 }
05109 
05110 static int iax2_show_netstats(int fd, int argc, char *argv[])
05111 {
05112    int numchans = 0;
05113    if (argc != 3)
05114       return RESULT_SHOWUSAGE;
05115    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
05116    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
05117    numchans = ast_cli_netstats(NULL, fd, 1);
05118    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05119    return RESULT_SUCCESS;
05120 }
05121 
05122 static int iax2_do_debug(int fd, int argc, char *argv[])
05123 {
05124    if (argc < 2 || argc > 3)
05125       return RESULT_SHOWUSAGE;
05126    iaxdebug = 1;
05127    ast_cli(fd, "IAX2 Debugging Enabled\n");
05128    return RESULT_SUCCESS;
05129 }
05130 
05131 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
05132 {
05133    if (argc < 3 || argc > 4)
05134       return RESULT_SHOWUSAGE;
05135    iaxtrunkdebug = 1;
05136    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
05137    return RESULT_SUCCESS;
05138 }
05139 
05140 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
05141 {
05142    if (argc < 3 || argc > 4)
05143       return RESULT_SHOWUSAGE;
05144    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05145    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05146    return RESULT_SUCCESS;
05147 }
05148 
05149 static int iax2_no_debug(int fd, int argc, char *argv[])
05150 {
05151    if (argc < 3 || argc > 4)
05152       return RESULT_SHOWUSAGE;
05153    iaxdebug = 0;
05154    ast_cli(fd, "IAX2 Debugging Disabled\n");
05155    return RESULT_SUCCESS;
05156 }
05157 
05158 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05159 {
05160    if (argc < 4 || argc > 5)
05161       return RESULT_SHOWUSAGE;
05162    iaxtrunkdebug = 0;
05163    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05164    return RESULT_SUCCESS;
05165 }
05166 
05167 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05168 {
05169    if (argc < 4 || argc > 5)
05170       return RESULT_SHOWUSAGE;
05171    jb_setoutput(jb_error_output, jb_warning_output, NULL);
05172    jb_debug_output("\n");
05173    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05174    return RESULT_SUCCESS;
05175 }
05176 
05177 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05178 {
05179    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05180    int res = -1;
05181    ast_mutex_lock(&iaxsl[callno]);
05182    if (iaxs[callno]) {
05183    /* If there's an outstanding error, return failure now */
05184       if (!iaxs[callno]->error) {
05185          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05186             res = 0;
05187             /* Don't waste bandwidth sending null frames */
05188          else if (f->frametype == AST_FRAME_NULL)
05189             res = 0;
05190          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05191             res = 0;
05192          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05193             res = 0;
05194          else
05195          /* Simple, just queue for transmission */
05196             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05197       } else {
05198          if (option_debug)
05199             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05200       }
05201    }
05202    /* If it's already gone, just return */
05203    ast_mutex_unlock(&iaxsl[callno]);
05204    return res;
05205 }
05206 
05207 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05208       int now, int transfer, int final)
05209 {
05210    struct ast_frame f = { 0, };
05211 
05212    f.frametype = type;
05213    f.subclass = command;
05214    f.datalen = datalen;
05215    f.src = __FUNCTION__;
05216    f.data = (void *) data;
05217 
05218    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05219 }
05220 
05221 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05222 {
05223    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05224 }
05225 
05226 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05227 {
05228    int res;
05229    ast_mutex_lock(&iaxsl[callno]);
05230    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05231    ast_mutex_unlock(&iaxsl[callno]);
05232    return res;
05233 }
05234 
05235 /*!
05236  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05237  *       the pvt struct for the given call number may disappear during its 
05238  *       execution.
05239  */
05240 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)
05241 {
05242    int call_num = i->callno;
05243    /* It is assumed that the callno has already been locked */
05244    iax2_predestroy(i->callno);
05245    if (!iaxs[call_num])
05246       return -1;
05247    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05248 }
05249 
05250 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)
05251 {
05252    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05253 }
05254 
05255 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05256 {
05257    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05258 }
05259 
05260 static int apply_context(struct iax2_context *con, const char *context)
05261 {
05262    while(con) {
05263       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05264          return -1;
05265       con = con->next;
05266    }
05267    return 0;
05268 }
05269 
05270 
05271 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05272 {
05273    /* Start pessimistic */
05274    int res = -1;
05275    int version = 2;
05276    struct iax2_user *user = NULL, *best = NULL;
05277    int bestscore = 0;
05278    int gotcapability = 0;
05279    struct ast_variable *v = NULL, *tmpvar = NULL;
05280    struct ao2_iterator i;
05281 
05282    if (!iaxs[callno])
05283       return res;
05284    if (ies->called_number)
05285       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05286    if (ies->calling_number) {
05287       ast_shrink_phone_number(ies->calling_number);
05288       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05289    }
05290    if (ies->calling_name)
05291       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05292    if (ies->calling_ani)
05293       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05294    if (ies->dnid)
05295       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05296    if (ies->rdnis)
05297       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05298    if (ies->called_context)
05299       ast_string_field_set(iaxs[callno], context, ies->called_context);
05300    if (ies->language)
05301       ast_string_field_set(iaxs[callno], language, ies->language);
05302    if (ies->username)
05303       ast_string_field_set(iaxs[callno], username, ies->username);
05304    if (ies->calling_ton > -1)
05305       iaxs[callno]->calling_ton = ies->calling_ton;
05306    if (ies->calling_tns > -1)
05307       iaxs[callno]->calling_tns = ies->calling_tns;
05308    if (ies->calling_pres > -1)
05309       iaxs[callno]->calling_pres = ies->calling_pres;
05310    if (ies->format)
05311       iaxs[callno]->peerformat = ies->format;
05312    if (ies->adsicpe)
05313       iaxs[callno]->peeradsicpe = ies->adsicpe;
05314    if (ies->capability) {
05315       gotcapability = 1;
05316       iaxs[callno]->peercapability = ies->capability;
05317    } 
05318    if (ies->version)
05319       version = ies->version;
05320 
05321    /* Use provided preferences until told otherwise for actual preferences */
05322    if(ies->codec_prefs) {
05323       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05324       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05325    }
05326 
05327    if (!gotcapability) 
05328       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05329    if (version > IAX_PROTO_VERSION) {
05330       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05331          ast_inet_ntoa(sin->sin_addr), version);
05332       return res;
05333    }
05334    /* Search the userlist for a compatible entry, and fill in the rest */
05335    i = ao2_iterator_init(users, 0);
05336    while ((user = ao2_iterator_next(&i))) {
05337       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05338          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05339          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05340          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05341               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05342          if (!ast_strlen_zero(iaxs[callno]->username)) {
05343             /* Exact match, stop right now. */
05344             if (best)
05345                user_unref(best);
05346             best = user;
05347             break;
05348          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05349             /* No required authentication */
05350             if (user->ha) {
05351                /* There was host authentication and we passed, bonus! */
05352                if (bestscore < 4) {
05353                   bestscore = 4;
05354                   if (best)
05355                      user_unref(best);
05356                   best = user;
05357                   continue;
05358                }
05359             } else {
05360                /* No host access, but no secret, either, not bad */
05361                if (bestscore < 3) {
05362                   bestscore = 3;
05363                   if (best)
05364                      user_unref(best);
05365                   best = user;
05366                   continue;
05367                }
05368             }
05369          } else {
05370             if (user->ha) {
05371                /* Authentication, but host access too, eh, it's something.. */
05372                if (bestscore < 2) {
05373                   bestscore = 2;
05374                   if (best)
05375                      user_unref(best);
05376                   best = user;
05377                   continue;
05378                }
05379             } else {
05380                /* Authentication and no host access...  This is our baseline */
05381                if (bestscore < 1) {
05382                   bestscore = 1;
05383                   if (best)
05384                      user_unref(best);
05385                   best = user;
05386                   continue;
05387                }
05388             }
05389          }
05390       }
05391       user_unref(user);
05392    }
05393    user = best;
05394    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05395       user = realtime_user(iaxs[callno]->username, sin);
05396       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05397           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05398          user = user_unref(user);
05399       }
05400    }
05401    if (user) {
05402       /* We found our match (use the first) */
05403       /* copy vars */
05404       for (v = user->vars ; v ; v = v->next) {
05405          if((tmpvar = ast_variable_new(v->name, v->value))) {
05406             tmpvar->next = iaxs[callno]->vars; 
05407             iaxs[callno]->vars = tmpvar;
05408          }
05409       }
05410       /* If a max AUTHREQ restriction is in place, activate it */
05411       if (user->maxauthreq > 0)
05412          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05413       iaxs[callno]->prefs = user->prefs;
05414       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05415       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05416       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05417       iaxs[callno]->encmethods = user->encmethods;
05418       /* Store the requested username if not specified */
05419       if (ast_strlen_zero(iaxs[callno]->username))
05420          ast_string_field_set(iaxs[callno], username, user->name);
05421       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05422       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05423       iaxs[callno]->capability = user->capability;
05424       /* And use the default context */
05425       if (ast_strlen_zero(iaxs[callno]->context)) {
05426          if (user->contexts)
05427             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05428          else
05429             ast_string_field_set(iaxs[callno], context, context);
05430       }
05431       /* And any input keys */
05432       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05433       /* And the permitted authentication methods */
05434       iaxs[callno]->authmethods = user->authmethods;
05435       iaxs[callno]->adsi = user->adsi;
05436       /* If the user has callerid, override the remote caller id. */
05437       if (ast_test_flag(user, IAX_HASCALLERID)) {
05438          iaxs[callno]->calling_tns = 0;
05439          iaxs[callno]->calling_ton = 0;
05440          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05441          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05442          ast_string_field_set(iaxs[callno], ani, user->cid_num);
05443          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05444       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
05445          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05446       } /* else user is allowed to set their own CID settings */
05447       if (!ast_strlen_zero(user->accountcode))
05448          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05449       if (!ast_strlen_zero(user->mohinterpret))
05450          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05451       if (!ast_strlen_zero(user->mohsuggest))
05452          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05453       if (user->amaflags)
05454          iaxs[callno]->amaflags = user->amaflags;
05455       if (!ast_strlen_zero(user->language))
05456          ast_string_field_set(iaxs[callno], language, user->language);
05457       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05458       /* Keep this check last */
05459       if (!ast_strlen_zero(user->dbsecret)) {
05460          char *family, *key=NULL;
05461          char buf[80];
05462          family = ast_strdupa(user->dbsecret);
05463          key = strchr(family, '/');
05464          if (key) {
05465             *key = '\0';
05466             key++;
05467          }
05468          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05469             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05470          else
05471             ast_string_field_set(iaxs[callno], secret, buf);
05472       } else
05473          ast_string_field_set(iaxs[callno], secret, user->secret);
05474       res = 0;
05475       user = user_unref(user);
05476    }
05477    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05478    return res;
05479 }
05480 
05481 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05482 {
05483    struct ast_iax2_full_hdr fh;
05484    fh.scallno = htons(src | IAX_FLAG_FULL);
05485    fh.dcallno = htons(dst);
05486    fh.ts = 0;
05487    fh.oseqno = 0;
05488    fh.iseqno = 0;
05489    fh.type = AST_FRAME_IAX;
05490    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05491    if (iaxdebug)
05492        iax_showframe(NULL, &fh, 0, sin, 0);
05493    if (option_debug)
05494       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05495          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05496    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05497 }
05498 
05499 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05500 {
05501    /* Select exactly one common encryption if there are any */
05502    p->encmethods &= enc;
05503    if (p->encmethods) {
05504       if (p->encmethods & IAX_ENCRYPT_AES128)
05505          p->encmethods = IAX_ENCRYPT_AES128;
05506       else
05507          p->encmethods = 0;
05508    }
05509 }
05510 
05511 /*!
05512  * \pre iaxsl[call_num] is locked
05513  *
05514  * \note Since this function calls send_command_final(), the pvt struct for the given
05515  *       call number may disappear while executing this function.
05516  */
05517 static int authenticate_request(int call_num)
05518 {
05519    struct iax_ie_data ied;
05520    int res = -1, authreq_restrict = 0;
05521    char challenge[10];
05522    struct chan_iax2_pvt *p = iaxs[call_num];
05523 
05524    memset(&ied, 0, sizeof(ied));
05525 
05526    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05527    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05528       struct iax2_user *user, tmp_user = {
05529          .name = p->username, 
05530       };
05531 
05532       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05533       if (user) {
05534          if (user->curauthreq == user->maxauthreq)
05535             authreq_restrict = 1;
05536          else
05537             user->curauthreq++;
05538          user = user_unref(user);
05539       }
05540    }
05541 
05542    /* If the AUTHREQ limit test failed, send back an error */
05543    if (authreq_restrict) {
05544       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05545       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05546       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05547       return 0;
05548    }
05549 
05550    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05551    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05552       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05553       ast_string_field_set(p, challenge, challenge);
05554       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05555       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05556    }
05557    if (p->encmethods)
05558       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05559 
05560    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05561 
05562    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05563 
05564    if (p->encmethods)
05565       ast_set_flag(p, IAX_ENCRYPTED);
05566 
05567    return res;
05568 }
05569 
05570 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05571 {
05572    char requeststr[256];
05573    char md5secret[256] = "";
05574    char secret[256] = "";
05575    char rsasecret[256] = "";
05576    int res = -1; 
05577    int x;
05578    struct iax2_user *user, tmp_user = {
05579       .name = p->username, 
05580    };
05581 
05582    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05583    if (user) {
05584       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05585          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05586          ast_clear_flag(p, IAX_MAXAUTHREQ);
05587       }
05588       ast_string_field_set(p, host, user->name);
05589       user = user_unref(user);
05590    }
05591 
05592    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05593       return res;
05594    if (ies->password)
05595       ast_copy_string(secret, ies->password, sizeof(secret));
05596    if (ies->md5_result)
05597       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05598    if (ies->rsa_result)
05599       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05600    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05601       struct ast_key *key;
05602       char *keyn;
05603       char tmpkey[256];
05604       char *stringp=NULL;
05605       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05606       stringp=tmpkey;
05607       keyn = strsep(&stringp, ":");
05608       while(keyn) {
05609          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05610          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05611             res = 0;
05612             break;
05613          } else if (!key)
05614             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05615          keyn = strsep(&stringp, ":");
05616       }
05617    } else if (p->authmethods & IAX_AUTH_MD5) {
05618       struct MD5Context md5;
05619       unsigned char digest[16];
05620       char *tmppw, *stringp;
05621       
05622       tmppw = ast_strdupa(p->secret);
05623       stringp = tmppw;
05624       while((tmppw = strsep(&stringp, ";"))) {
05625          MD5Init(&md5);
05626          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05627          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05628          MD5Final(digest, &md5);
05629          /* If they support md5, authenticate with it.  */
05630          for (x=0;x<16;x++)
05631             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05632          if (!strcasecmp(requeststr, md5secret)) {
05633             res = 0;
05634             break;
05635          }
05636       }
05637    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05638       if (!strcmp(secret, p->secret))
05639          res = 0;
05640    }
05641    return res;
05642 }
05643 
05644 /*! \brief Verify inbound registration */
05645 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05646 {
05647    char requeststr[256] = "";
05648    char peer[256] = "";
05649    char md5secret[256] = "";
05650    char rsasecret[256] = "";
05651    char secret[256] = "";
05652    struct iax2_peer *p = NULL;
05653    struct ast_key *key;
05654    char *keyn;
05655    int x;
05656    int expire = 0;
05657    int res = -1;
05658 
05659    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05660    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05661    if (ies->username)
05662       ast_copy_string(peer, ies->username, sizeof(peer));
05663    if (ies->password)
05664       ast_copy_string(secret, ies->password, sizeof(secret));
05665    if (ies->md5_result)
05666       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05667    if (ies->rsa_result)
05668       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05669    if (ies->refresh)
05670       expire = ies->refresh;
05671 
05672    if (ast_strlen_zero(peer)) {
05673       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05674       return -1;
05675    }
05676 
05677    /* SLD: first call to lookup peer during registration */
05678    ast_mutex_unlock(&iaxsl[callno]);
05679    p = find_peer(peer, 1);
05680    ast_mutex_lock(&iaxsl[callno]);
05681    if (!p || !iaxs[callno]) {
05682       if (iaxs[callno]) {
05683          ast_string_field_set(iaxs[callno], secret, "badsecret");
05684       }
05685       if (authdebug && !p)
05686          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05687       goto return_unref;
05688    }
05689 
05690    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05691       if (authdebug)
05692          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05693       goto return_unref;
05694    }
05695 
05696    if (!ast_apply_ha(p->ha, sin)) {
05697       if (authdebug)
05698          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05699       goto return_unref;
05700    }
05701    if (!inaddrcmp(&p->addr, sin))
05702       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05703    ast_string_field_set(iaxs[callno], secret, p->secret);
05704    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05705    /* Check secret against what we have on file */
05706    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05707       if (!ast_strlen_zero(p->inkeys)) {
05708          char tmpkeys[256];
05709          char *stringp=NULL;
05710          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05711          stringp=tmpkeys;
05712          keyn = strsep(&stringp, ":");
05713          while(keyn) {
05714             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05715             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05716                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05717                break;
05718             } else if (!key) 
05719                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05720             keyn = strsep(&stringp, ":");
05721          }
05722          if (!keyn) {
05723             if (authdebug)
05724                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05725             goto return_unref;
05726          }
05727       } else {
05728          if (authdebug)
05729             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05730          goto return_unref;
05731       }
05732    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05733       struct MD5Context md5;
05734       unsigned char digest[16];
05735       char *tmppw, *stringp;
05736       
05737       tmppw = ast_strdupa(p->secret);
05738       stringp = tmppw;
05739       while((tmppw = strsep(&stringp, ";"))) {
05740          MD5Init(&md5);
05741          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05742          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05743          MD5Final(digest, &md5);
05744          for (x=0;x<16;x++)
05745             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05746          if (!strcasecmp(requeststr, md5secret)) 
05747             break;
05748       }
05749       if (tmppw) {
05750          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05751       } else {
05752          if (authdebug)
05753             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05754          goto return_unref;
05755       }
05756    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05757       /* They've provided a plain text password and we support that */
05758       if (strcmp(secret, p->secret)) {
05759          if (authdebug)
05760             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05761          goto return_unref;
05762       } else
05763          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05764    } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) {
05765       if (authdebug &&
05766          ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) ||
05767           (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) {
05768          ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name);
05769       } /* ELSE this is the first time through and no challenge exists, so it's not quite yet a failure. */
05770       goto return_unref;
05771    }
05772    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05773 
05774 return_unref:
05775    ast_string_field_set(iaxs[callno], peer, peer);
05776    /* Choose lowest expiry number */
05777    if (expire && (expire < iaxs[callno]->expiry)) 
05778       iaxs[callno]->expiry = expire;
05779 
05780    res = 0;
05781 
05782    if (p)
05783       peer_unref(p);
05784 
05785    return res;
05786 }
05787 
05788 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05789 {
05790    int res = -1;
05791    int x;
05792    if (!ast_strlen_zero(keyn)) {
05793       if (!(authmethods & IAX_AUTH_RSA)) {
05794          if (ast_strlen_zero(secret)) 
05795             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));
05796       } else if (ast_strlen_zero(challenge)) {
05797          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05798       } else {
05799          char sig[256];
05800          struct ast_key *key;
05801          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05802          if (!key) {
05803             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05804          } else {
05805             if (ast_sign(key, (char*)challenge, sig)) {
05806                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05807                res = -1;
05808             } else {
05809                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05810                res = 0;
05811             }
05812          }
05813       }
05814    } 
05815    /* Fall back */
05816    if (res && !ast_strlen_zero(secret)) {
05817       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05818          struct MD5Context md5;
05819          unsigned char digest[16];
05820          char digres[128];
05821          MD5Init(&md5);
05822          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05823          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05824          MD5Final(digest, &md5);
05825          /* If they support md5, authenticate with it.  */
05826          for (x=0;x<16;x++)
05827             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05828          if (ecx && dcx)
05829             build_enc_keys(digest, ecx, dcx);
05830          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05831          res = 0;
05832       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05833          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05834          res = 0;
05835       } else
05836          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05837    }
05838    return res;
05839 }
05840 
05841 /*!
05842  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05843  *       so do not call this function with a pvt lock held.
05844  */
05845 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05846 {
05847    struct iax2_peer *peer = NULL;
05848    /* Start pessimistic */
05849    int res = -1;
05850    int authmethods = 0;
05851    struct iax_ie_data ied;
05852    uint16_t callno = p->callno;
05853 
05854    memset(&ied, 0, sizeof(ied));
05855    
05856    if (ies->username)
05857       ast_string_field_set(p, username, ies->username);
05858    if (ies->challenge)
05859       ast_string_field_set(p, challenge, ies->challenge);
05860    if (ies->authmethods)
05861       authmethods = ies->authmethods;
05862    if (authmethods & IAX_AUTH_MD5)
05863       merge_encryption(p, ies->encmethods);
05864    else
05865       p->encmethods = 0;
05866 
05867    /* Check for override RSA authentication first */
05868    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05869       /* Normal password authentication */
05870       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05871    } else {
05872       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05873       while ((peer = ao2_iterator_next(&i))) {
05874          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05875              /* No peer specified at our end, or this is the peer */
05876              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05877              /* No username specified in peer rule, or this is the right username */
05878              && (!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)))
05879              /* No specified host, or this is our host */
05880             ) {
05881             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05882             if (!res) {
05883                peer_unref(peer);
05884                break;
05885             }
05886          }
05887          peer_unref(peer);
05888       }
05889       if (!peer) {
05890          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05891             that we're trying to authenticate *to* a realtime peer */
05892          const char *peer_name = ast_strdupa(p->peer);
05893          ast_mutex_unlock(&iaxsl[callno]);
05894          if ((peer = realtime_peer(peer_name, NULL))) {
05895             ast_mutex_lock(&iaxsl[callno]);
05896             if (!(p = iaxs[callno])) {
05897                peer_unref(peer);
05898                return -1;
05899             }
05900             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05901             peer_unref(peer);
05902          }
05903          if (!peer) {
05904             ast_mutex_lock(&iaxsl[callno]);
05905             if (!(p = iaxs[callno]))
05906                return -1;
05907          }
05908       }
05909    }
05910    if (ies->encmethods)
05911       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05912    if (!res)
05913       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05914    return res;
05915 }
05916 
05917 static int iax2_do_register(struct iax2_registry *reg);
05918 
05919 static void __iax2_do_register_s(const void *data)
05920 {
05921    struct iax2_registry *reg = (struct iax2_registry *)data;
05922    reg->expire = -1;
05923    iax2_do_register(reg);
05924 }
05925 
05926 static int iax2_do_register_s(const void *data)
05927 {
05928 #ifdef SCHED_MULTITHREADED
05929    if (schedule_action(__iax2_do_register_s, data))
05930 #endif      
05931       __iax2_do_register_s(data);
05932    return 0;
05933 }
05934 
05935 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05936 {
05937    int newcall = 0;
05938    char newip[256];
05939    struct iax_ie_data ied;
05940    struct sockaddr_in new;
05941    
05942    
05943    memset(&ied, 0, sizeof(ied));
05944    if (ies->apparent_addr)
05945       bcopy(ies->apparent_addr, &new, sizeof(new));
05946    if (ies->callno)
05947       newcall = ies->callno;
05948    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05949       ast_log(LOG_WARNING, "Invalid transfer request\n");
05950       return -1;
05951    }
05952    pvt->transfercallno = newcall;
05953    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05954    inet_aton(newip, &pvt->transfer.sin_addr);
05955    pvt->transfer.sin_family = AF_INET;
05956    pvt->transferring = TRANSFER_BEGIN;
05957    pvt->transferid = ies->transferid;
05958    store_by_transfercallno(pvt);
05959    if (ies->transferid)
05960       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05961    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05962    return 0;
05963 }
05964 
05965 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05966 {
05967    char exten[256] = "";
05968    int status = CACHE_FLAG_UNKNOWN;
05969    int expiry = iaxdefaultdpcache;
05970    int x;
05971    int matchmore = 0;
05972    struct iax2_dpcache *dp, *prev;
05973    
05974    if (ies->called_number)
05975       ast_copy_string(exten, ies->called_number, sizeof(exten));
05976 
05977    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05978       status = CACHE_FLAG_EXISTS;
05979    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05980       status = CACHE_FLAG_CANEXIST;
05981    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05982       status = CACHE_FLAG_NONEXISTENT;
05983 
05984    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05985       /* Don't really do anything with this */
05986    }
05987    if (ies->refresh)
05988       expiry = ies->refresh;
05989    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05990       matchmore = CACHE_FLAG_MATCHMORE;
05991    ast_mutex_lock(&dpcache_lock);
05992    prev = NULL;
05993    dp = pvt->dpentries;
05994    while(dp) {
05995       if (!strcmp(dp->exten, exten)) {
05996          /* Let them go */
05997          if (prev)
05998             prev->peer = dp->peer;
05999          else
06000             pvt->dpentries = dp->peer;
06001          dp->peer = NULL;
06002          dp->callno = 0;
06003          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06004          if (dp->flags & CACHE_FLAG_PENDING) {
06005             dp->flags &= ~CACHE_FLAG_PENDING;
06006             dp->flags |= status;
06007             dp->flags |= matchmore;
06008          }
06009          /* Wake up waiters */
06010          for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06011             if (dp->waiters[x] > -1) {
06012                if (write(dp->waiters[x], "asdf", 4) < 0) {
06013                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06014                }
06015             }
06016          }
06017       }
06018       prev = dp;
06019       dp = dp->peer;
06020    }
06021    ast_mutex_unlock(&dpcache_lock);
06022    return 0;
06023 }
06024 
06025 static int complete_transfer(int callno, struct iax_ies *ies)
06026 {
06027    int peercallno = 0;
06028    struct chan_iax2_pvt *pvt = iaxs[callno];
06029    struct iax_frame *cur;
06030    jb_frame frame;
06031 
06032    if (ies->callno)
06033       peercallno = ies->callno;
06034 
06035    if (peercallno < 1) {
06036       ast_log(LOG_WARNING, "Invalid transfer request\n");
06037       return -1;
06038    }
06039    remove_by_transfercallno(pvt);
06040    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06041    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06042    /* Reset sequence numbers */
06043    pvt->oseqno = 0;
06044    pvt->rseqno = 0;
06045    pvt->iseqno = 0;
06046    pvt->aseqno = 0;
06047 
06048    if (pvt->peercallno) {
06049       remove_by_peercallno(pvt);
06050    }
06051    pvt->peercallno = peercallno;
06052    /*this is where the transfering call swiches hash tables */
06053    store_by_peercallno(pvt);
06054    pvt->transferring = TRANSFER_NONE;
06055    pvt->svoiceformat = -1;
06056    pvt->voiceformat = 0;
06057    pvt->svideoformat = -1;
06058    pvt->videoformat = 0;
06059    pvt->transfercallno = -1;
06060    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06061    memset(&pvt->offset, 0, sizeof(pvt->offset));
06062    /* reset jitterbuffer */
06063    while(jb_getall(pvt->jb,&frame) == JB_OK)
06064       iax2_frame_free(frame.data);
06065    jb_reset(pvt->jb);
06066    pvt->lag = 0;
06067    pvt->last = 0;
06068    pvt->lastsent = 0;
06069    pvt->nextpred = 0;
06070    pvt->pingtime = DEFAULT_RETRY_TIME;
06071    AST_LIST_LOCK(&iaxq.queue);
06072    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06073       /* We must cancel any packets that would have been transmitted
06074          because now we're talking to someone new.  It's okay, they
06075          were transmitted to someone that didn't care anyway. */
06076       if (callno == cur->callno) 
06077          cur->retries = -1;
06078    }
06079    AST_LIST_UNLOCK(&iaxq.queue);
06080    return 0; 
06081 }
06082 
06083 /*! \brief Acknowledgment received for OUR registration */
06084 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06085 {
06086    struct iax2_registry *reg;
06087    /* Start pessimistic */
06088    char peer[256] = "";
06089    char msgstatus[60];
06090    int refresh = 60;
06091    char ourip[256] = "<Unspecified>";
06092    struct sockaddr_in oldus;
06093    struct sockaddr_in us;
06094    int oldmsgs;
06095 
06096    memset(&us, 0, sizeof(us));
06097    if (ies->apparent_addr)
06098       bcopy(ies->apparent_addr, &us, sizeof(us));
06099    if (ies->username)
06100       ast_copy_string(peer, ies->username, sizeof(peer));
06101    if (ies->refresh)
06102       refresh = ies->refresh;
06103    if (ies->calling_number) {
06104       /* We don't do anything with it really, but maybe we should */
06105    }
06106    reg = iaxs[callno]->reg;
06107    if (!reg) {
06108       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06109       return -1;
06110    }
06111    memcpy(&oldus, &reg->us, sizeof(oldus));
06112    oldmsgs = reg->messages;
06113    if (inaddrcmp(&reg->addr, sin)) {
06114       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06115       return -1;
06116    }
06117    memcpy(&reg->us, &us, sizeof(reg->us));
06118    if (ies->msgcount >= 0)
06119       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
06120    /* always refresh the registration at the interval requested by the server
06121       we are registering to
06122    */
06123    reg->refresh = refresh;
06124    AST_SCHED_DEL(sched, reg->expire);
06125    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06126    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
06127       if (option_verbose > 2) {
06128          if (reg->messages > 255)
06129             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06130          else if (reg->messages > 1)
06131             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06132          else if (reg->messages > 0)
06133             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
06134          else
06135             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
06136          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06137          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06138       }
06139       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06140    }
06141    reg->regstate = REG_STATE_REGISTERED;
06142    return 0;
06143 }
06144 
06145 static int iax2_register(char *value, int lineno)
06146 {
06147    struct iax2_registry *reg;
06148    char copy[256];
06149    char *username, *hostname, *secret;
06150    char *porta;
06151    char *stringp=NULL;
06152    
06153    if (!value)
06154       return -1;
06155    ast_copy_string(copy, value, sizeof(copy));
06156    stringp=copy;
06157    username = strsep(&stringp, "@");
06158    hostname = strsep(&stringp, "@");
06159    if (!hostname) {
06160       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06161       return -1;
06162    }
06163    stringp=username;
06164    username = strsep(&stringp, ":");
06165    secret = strsep(&stringp, ":");
06166    stringp=hostname;
06167    hostname = strsep(&stringp, ":");
06168    porta = strsep(&stringp, ":");
06169    
06170    if (porta && !atoi(porta)) {
06171       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06172       return -1;
06173    }
06174    if (!(reg = ast_calloc(1, sizeof(*reg))))
06175       return -1;
06176    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06177       free(reg);
06178       return -1;
06179    }
06180    ast_copy_string(reg->username, username, sizeof(reg->username));
06181    if (secret)
06182       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06183    reg->expire = -1;
06184    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06185    reg->addr.sin_family = AF_INET;
06186    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06187    AST_LIST_LOCK(&registrations);
06188    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06189    AST_LIST_UNLOCK(&registrations);
06190    
06191    return 0;
06192 }
06193 
06194 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06195 {
06196    char multi[256];
06197    char *stringp, *ext;
06198    if (!ast_strlen_zero(regcontext)) {
06199       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06200       stringp = multi;
06201       while((ext = strsep(&stringp, "&"))) {
06202          if (onoff) {
06203             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06204                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06205                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06206          } else
06207             ast_context_remove_extension(regcontext, ext, 1, NULL);
06208       }
06209    }
06210 }
06211 static void prune_peers(void);
06212 
06213 static void unlink_peer(struct iax2_peer *peer)
06214 {
06215    if (peer->expire > -1) {
06216       if (!ast_sched_del(sched, peer->expire)) {
06217          peer->expire = -1;
06218          peer_unref(peer);
06219       }
06220    }
06221 
06222    if (peer->pokeexpire > -1) {
06223       if (!ast_sched_del(sched, peer->pokeexpire)) {
06224          peer->pokeexpire = -1;
06225          peer_unref(peer);
06226       }
06227    }
06228 
06229    ao2_unlink(peers, peer);
06230 }
06231 
06232 static void __expire_registry(const void *data)
06233 {
06234    struct iax2_peer *peer = (struct iax2_peer *) data;
06235 
06236    if (!peer)
06237       return;
06238 
06239    peer->expire = -1;
06240 
06241    if (option_debug)
06242       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06243    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06244       realtime_update_peer(peer->name, &peer->addr, 0);
06245    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06246    /* Reset the address */
06247    memset(&peer->addr, 0, sizeof(peer->addr));
06248    /* Reset expiry value */
06249    peer->expiry = min_reg_expire;
06250    if (!ast_test_flag(peer, IAX_TEMPONLY))
06251       ast_db_del("IAX/Registry", peer->name);
06252    register_peer_exten(peer, 0);
06253    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06254    if (iax2_regfunk)
06255       iax2_regfunk(peer->name, 0);
06256 
06257    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06258       unlink_peer(peer);
06259 
06260    peer_unref(peer);
06261 }
06262 
06263 static int expire_registry(const void *data)
06264 {
06265 #ifdef SCHED_MULTITHREADED
06266    if (schedule_action(__expire_registry, data))
06267 #endif      
06268       __expire_registry(data);
06269    return 0;
06270 }
06271 
06272 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06273 
06274 static void reg_source_db(struct iax2_peer *p)
06275 {
06276    char data[80];
06277    struct in_addr in;
06278    char *c, *d;
06279    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06280       c = strchr(data, ':');
06281       if (c) {
06282          *c = '\0';
06283          c++;
06284          if (inet_aton(data, &in)) {
06285             d = strchr(c, ':');
06286             if (d) {
06287                *d = '\0';
06288                d++;
06289                if (option_verbose > 2)
06290                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06291                   ast_inet_ntoa(in), atoi(c), atoi(d));
06292                iax2_poke_peer(p, 0);
06293                p->expiry = atoi(d);
06294                memset(&p->addr, 0, sizeof(p->addr));
06295                p->addr.sin_family = AF_INET;
06296                p->addr.sin_addr = in;
06297                p->addr.sin_port = htons(atoi(c));
06298                if (p->expire > -1) {
06299                   if (!ast_sched_del(sched, p->expire)) {
06300                      p->expire = -1;
06301                      peer_unref(p);
06302                   }
06303                }
06304                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06305                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06306                if (p->expire == -1)
06307                   peer_unref(p);
06308                if (iax2_regfunk)
06309                   iax2_regfunk(p->name, 1);
06310                register_peer_exten(p, 1);
06311             }              
06312                
06313          }
06314       }
06315    }
06316 }
06317 
06318 /*!
06319  * \pre iaxsl[callno] is locked
06320  *
06321  * \note Since this function calls send_command_final(), the pvt struct for
06322  *       the given call number may disappear while executing this function.
06323  */
06324 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06325 {
06326    /* Called from IAX thread only, with proper iaxsl lock */
06327    struct iax_ie_data ied;
06328    struct iax2_peer *p;
06329    int msgcount;
06330    char data[80];
06331    int version;
06332    const char *peer_name;
06333    int res = -1;
06334 
06335    memset(&ied, 0, sizeof(ied));
06336 
06337    peer_name = ast_strdupa(iaxs[callno]->peer);
06338 
06339    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06340    ast_mutex_unlock(&iaxsl[callno]);
06341    if (!(p = find_peer(peer_name, 1))) {
06342       ast_mutex_lock(&iaxsl[callno]);
06343       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06344       return -1;
06345    }
06346    ast_mutex_lock(&iaxsl[callno]);
06347    if (!iaxs[callno])
06348       goto return_unref;
06349 
06350    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06351       if (sin->sin_addr.s_addr) {
06352          time_t nowtime;
06353          time(&nowtime);
06354          realtime_update_peer(peer_name, sin, nowtime);
06355       } else {
06356          realtime_update_peer(peer_name, sin, 0);
06357       }
06358    }
06359    if (inaddrcmp(&p->addr, sin)) {
06360       if (iax2_regfunk)
06361          iax2_regfunk(p->name, 1);
06362       /* Stash the IP address from which they registered */
06363       memcpy(&p->addr, sin, sizeof(p->addr));
06364       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06365       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06366          ast_db_put("IAX/Registry", p->name, data);
06367          if  (option_verbose > 2)
06368             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06369                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06370          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06371          register_peer_exten(p, 1);
06372          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06373       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06374          if  (option_verbose > 2)
06375             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06376                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06377          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06378          register_peer_exten(p, 0);
06379          ast_db_del("IAX/Registry", p->name);
06380          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06381       }
06382       /* Update the host */
06383       /* Verify that the host is really there */
06384       iax2_poke_peer(p, callno);
06385    }     
06386 
06387    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06388    if (!iaxs[callno]) {
06389       res = -1;
06390       goto return_unref;
06391    }
06392 
06393    /* Store socket fd */
06394    p->sockfd = fd;
06395    /* Setup the expiry */
06396    if (p->expire > -1) {
06397       if (!ast_sched_del(sched, p->expire)) {
06398          p->expire = -1;
06399          peer_unref(p);
06400       }
06401    }
06402    /* treat an unspecified refresh interval as the minimum */
06403    if (!refresh)
06404       refresh = min_reg_expire;
06405    if (refresh > max_reg_expire) {
06406       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06407          p->name, max_reg_expire, refresh);
06408       p->expiry = max_reg_expire;
06409    } else if (refresh < min_reg_expire) {
06410       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06411          p->name, min_reg_expire, refresh);
06412       p->expiry = min_reg_expire;
06413    } else {
06414       p->expiry = refresh;
06415    }
06416    if (p->expiry && sin->sin_addr.s_addr) {
06417       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06418       if (p->expire == -1)
06419          peer_unref(p);
06420    }
06421    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06422    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06423    if (sin->sin_addr.s_addr) {
06424       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06425       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06426       if (!ast_strlen_zero(p->mailbox)) {
06427          int new, old;
06428          ast_app_inboxcount(p->mailbox, &new, &old);
06429          if (new > 255)
06430             new = 255;
06431          if (old > 255)
06432             old = 255;
06433          msgcount = (old << 8) | new;
06434          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06435       }
06436       if (ast_test_flag(p, IAX_HASCALLERID)) {
06437          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06438          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06439       }
06440    }
06441    version = iax_check_version(devtype);
06442    if (version) 
06443       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06444 
06445    res = 0;
06446 
06447 return_unref:
06448    peer_unref(p);
06449 
06450    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06451 }
06452 
06453 static int registry_authrequest(int callno)
06454 {
06455    struct iax_ie_data ied;
06456    struct iax2_peer *p;
06457    char challenge[10];
06458    const char *peer_name;
06459    int sentauthmethod;
06460 
06461    peer_name = ast_strdupa(iaxs[callno]->peer);
06462 
06463    /* SLD: third call to find_peer in registration */
06464    ast_mutex_unlock(&iaxsl[callno]);
06465    if ((p = find_peer(peer_name, 1))) {
06466       last_authmethod = p->authmethods;
06467    }
06468 
06469    ast_mutex_lock(&iaxsl[callno]);
06470    if (!iaxs[callno])
06471       goto return_unref;
06472 
06473    memset(&ied, 0, sizeof(ied));
06474    /* The selection of which delayed reject is sent may leak information,
06475     * if it sets a static response.  For example, if a host is known to only
06476     * use MD5 authentication, then an RSA response would indicate that the
06477     * peer does not exist, and vice-versa.
06478     * Therefore, we use whatever the last peer used (which may vary over the
06479     * course of a server, which should leak minimal information). */
06480    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06481    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06482    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06483       /* Build the challenge */
06484       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06485       ast_string_field_set(iaxs[callno], challenge, challenge);
06486       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06487    }
06488    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06489 
06490 return_unref:
06491    if (p) {
06492       peer_unref(p);
06493    }
06494 
06495    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06496 }
06497 
06498 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06499 {
06500    struct iax2_registry *reg;
06501    /* Start pessimistic */
06502    struct iax_ie_data ied;
06503    char peer[256] = "";
06504    char challenge[256] = "";
06505    int res;
06506    int authmethods = 0;
06507    if (ies->authmethods)
06508       authmethods = ies->authmethods;
06509    if (ies->username)
06510       ast_copy_string(peer, ies->username, sizeof(peer));
06511    if (ies->challenge)
06512       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06513    memset(&ied, 0, sizeof(ied));
06514    reg = iaxs[callno]->reg;
06515    if (reg) {
06516          if (inaddrcmp(&reg->addr, sin)) {
06517             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06518             return -1;
06519          }
06520          if (ast_strlen_zero(reg->secret)) {
06521             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06522             reg->regstate = REG_STATE_NOAUTH;
06523             return -1;
06524          }
06525          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06526          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06527          if (reg->secret[0] == '[') {
06528             char tmpkey[256];
06529             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06530             tmpkey[strlen(tmpkey) - 1] = '\0';
06531             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06532          } else
06533             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06534          if (!res) {
06535             reg->regstate = REG_STATE_AUTHSENT;
06536             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06537          } else
06538             return -1;
06539          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06540    } else   
06541       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06542    return -1;
06543 }
06544 
06545 static void stop_stuff(int callno)
06546 {
06547    iax2_destroy_helper(iaxs[callno]);
06548 }
06549 
06550 static void __auth_reject(const void *nothing)
06551 {
06552    /* Called from IAX thread only, without iaxs lock */
06553    int callno = (int)(long)(nothing);
06554    struct iax_ie_data ied;
06555    ast_mutex_lock(&iaxsl[callno]);
06556    if (iaxs[callno]) {
06557       memset(&ied, 0, sizeof(ied));
06558       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06559          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06560          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06561       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06562          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06563          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06564       }
06565       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06566    }
06567    ast_mutex_unlock(&iaxsl[callno]);
06568 }
06569 
06570 static int auth_reject(const void *data)
06571 {
06572    int callno = (int)(long)(data);
06573    ast_mutex_lock(&iaxsl[callno]);
06574    if (iaxs[callno])
06575       iaxs[callno]->authid = -1;
06576    ast_mutex_unlock(&iaxsl[callno]);
06577 #ifdef SCHED_MULTITHREADED
06578    if (schedule_action(__auth_reject, data))
06579 #endif      
06580       __auth_reject(data);
06581    return 0;
06582 }
06583 
06584 static int auth_fail(int callno, int failcode)
06585 {
06586    /* Schedule sending the authentication failure in one second, to prevent
06587       guessing */
06588    if (iaxs[callno]) {
06589       iaxs[callno]->authfail = failcode;
06590       if (delayreject) {
06591          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06592          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06593       } else
06594          auth_reject((void *)(long)callno);
06595    }
06596    return 0;
06597 }
06598 
06599 static void __auto_hangup(const void *nothing)
06600 {
06601    /* Called from IAX thread only, without iaxs lock */
06602    int callno = (int)(long)(nothing);
06603    struct iax_ie_data ied;
06604    ast_mutex_lock(&iaxsl[callno]);
06605    if (iaxs[callno]) {
06606       memset(&ied, 0, sizeof(ied));
06607       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06608       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06609       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06610    }
06611    ast_mutex_unlock(&iaxsl[callno]);
06612 }
06613 
06614 static int auto_hangup(const void *data)
06615 {
06616    int callno = (int)(long)(data);
06617    ast_mutex_lock(&iaxsl[callno]);
06618    if (iaxs[callno]) {
06619       iaxs[callno]->autoid = -1;
06620    }
06621    ast_mutex_unlock(&iaxsl[callno]);
06622 #ifdef SCHED_MULTITHREADED
06623    if (schedule_action(__auto_hangup, data))
06624 #endif      
06625       __auto_hangup(data);
06626    return 0;
06627 }
06628 
06629 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06630 {
06631    struct iax_ie_data ied;
06632    /* Auto-hangup with 30 seconds of inactivity */
06633    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06634    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06635    memset(&ied, 0, sizeof(ied));
06636    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06637    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06638    dp->flags |= CACHE_FLAG_TRANSMITTED;
06639 }
06640 
06641 static int iax2_vnak(int callno)
06642 {
06643    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06644 }
06645 
06646 static void vnak_retransmit(int callno, int last)
06647 {
06648    struct iax_frame *f;
06649 
06650    AST_LIST_LOCK(&iaxq.queue);
06651    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06652       /* Send a copy immediately */
06653       if ((f->callno == callno) && iaxs[f->callno] &&
06654          ((unsigned char ) (f->oseqno - last) < 128) &&
06655          (f->retries >= 0)) {
06656          send_packet(f);
06657       }
06658    }
06659    AST_LIST_UNLOCK(&iaxq.queue);
06660 }
06661 
06662 static void __iax2_poke_peer_s(const void *data)
06663 {
06664    struct iax2_peer *peer = (struct iax2_peer *)data;
06665    iax2_poke_peer(peer, 0);
06666    peer_unref(peer);
06667 }
06668 
06669 static int iax2_poke_peer_s(const void *data)
06670 {
06671    struct iax2_peer *peer = (struct iax2_peer *)data;
06672    peer->pokeexpire = -1;
06673 #ifdef SCHED_MULTITHREADED
06674    if (schedule_action(__iax2_poke_peer_s, data))
06675 #endif      
06676       __iax2_poke_peer_s(data);
06677    return 0;
06678 }
06679 
06680 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06681 {
06682    int res = 0;
06683    struct iax_frame *fr;
06684    struct ast_iax2_meta_hdr *meta;
06685    struct ast_iax2_meta_trunk_hdr *mth;
06686    int calls = 0;
06687    
06688    /* Point to frame */
06689    fr = (struct iax_frame *)tpeer->trunkdata;
06690    /* Point to meta data */
06691    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06692    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06693    if (tpeer->trunkdatalen) {
06694       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06695       meta->zeros = 0;
06696       meta->metacmd = IAX_META_TRUNK;
06697       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06698          meta->cmddata = IAX_META_TRUNK_MINI;
06699       else
06700          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06701       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06702       /* And the rest of the ast_iax2 header */
06703       fr->direction = DIRECTION_OUTGRESS;
06704       fr->retrans = -1;
06705       fr->transfer = 0;
06706       /* Any appropriate call will do */
06707       fr->data = fr->afdata;
06708       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06709       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06710       calls = tpeer->calls;
06711 #if 0
06712       if (option_debug)
06713          ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
06714 #endif      
06715       /* Reset transmit trunk side data */
06716       tpeer->trunkdatalen = 0;
06717       tpeer->calls = 0;
06718    }
06719    if (res < 0)
06720       return res;
06721    return calls;
06722 }
06723 
06724 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06725 {
06726    /* Drop when trunk is about 5 seconds idle */
06727    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06728       return 1;
06729    return 0;
06730 }
06731 
06732 static int timing_read(int *id, int fd, short events, void *cbdata)
06733 {
06734    char buf[1024];
06735    int res;
06736    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06737    int processed = 0;
06738    int totalcalls = 0;
06739 #ifdef DAHDI_TIMERACK
06740    int x = 1;
06741 #endif
06742    struct timeval now;
06743    if (iaxtrunkdebug)
06744       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06745    gettimeofday(&now, NULL);
06746    if (events & AST_IO_PRI) {
06747 #ifdef DAHDI_TIMERACK
06748       /* Great, this is a timing interface, just call the ioctl */
06749       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
06750          ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
06751          usleep(1);
06752          return -1;
06753       }
06754 #endif      
06755    } else {
06756       /* Read and ignore from the pseudo channel for timing */
06757       res = read(fd, buf, sizeof(buf));
06758       if (res < 1) {
06759          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06760          return 1;
06761       }
06762    }
06763    /* For each peer that supports trunking... */
06764    ast_mutex_lock(&tpeerlock);
06765    tpeer = tpeers;
06766    while(tpeer) {
06767       processed++;
06768       res = 0;
06769       ast_mutex_lock(&tpeer->lock);
06770       /* We can drop a single tpeer per pass.  That makes all this logic
06771          substantially easier */
06772       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06773          /* Take it out of the list, but don't free it yet, because it
06774             could be in use */
06775          if (prev)
06776             prev->next = tpeer->next;
06777          else
06778             tpeers = tpeer->next;
06779          drop = tpeer;
06780       } else {
06781          res = send_trunk(tpeer, &now);
06782          if (iaxtrunkdebug)
06783             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);
06784       }     
06785       totalcalls += res;   
06786       res = 0;
06787       ast_mutex_unlock(&tpeer->lock);
06788       prev = tpeer;
06789       tpeer = tpeer->next;
06790    }
06791    ast_mutex_unlock(&tpeerlock);
06792    if (drop) {
06793       ast_mutex_lock(&drop->lock);
06794       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06795          because by the time they could get tpeerlock, we've already grabbed it */
06796       if (option_debug)
06797          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06798       if (drop->trunkdata) {
06799          free(drop->trunkdata);
06800          drop->trunkdata = NULL;
06801       }
06802       ast_mutex_unlock(&drop->lock);
06803       ast_mutex_destroy(&drop->lock);
06804       free(drop);
06805       
06806    }
06807    if (iaxtrunkdebug)
06808       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06809    iaxtrunkdebug =0;
06810    return 1;
06811 }
06812 
06813 struct dpreq_data {
06814    int callno;
06815    char context[AST_MAX_EXTENSION];
06816    char callednum[AST_MAX_EXTENSION];
06817    char *callerid;
06818 };
06819 
06820 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06821 {
06822    unsigned short dpstatus = 0;
06823    struct iax_ie_data ied1;
06824    int mm;
06825 
06826    memset(&ied1, 0, sizeof(ied1));
06827    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06828    /* Must be started */
06829    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06830       dpstatus = IAX_DPSTATUS_EXISTS;
06831    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06832       dpstatus = IAX_DPSTATUS_CANEXIST;
06833    } else {
06834       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06835    }
06836    if (ast_ignore_pattern(context, callednum))
06837       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06838    if (mm)
06839       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06840    if (!skiplock)
06841       ast_mutex_lock(&iaxsl[callno]);
06842    if (iaxs[callno]) {
06843       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06844       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06845       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06846       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06847    }
06848    if (!skiplock)
06849       ast_mutex_unlock(&iaxsl[callno]);
06850 }
06851 
06852 static void *dp_lookup_thread(void *data)
06853 {
06854    /* Look up for dpreq */
06855    struct dpreq_data *dpr = data;
06856    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06857    if (dpr->callerid)
06858       free(dpr->callerid);
06859    free(dpr);
06860    return NULL;
06861 }
06862 
06863 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06864 {
06865    pthread_t newthread;
06866    struct dpreq_data *dpr;
06867    pthread_attr_t attr;
06868    
06869    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06870       return;
06871 
06872    pthread_attr_init(&attr);
06873    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06874 
06875    dpr->callno = callno;
06876    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06877    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06878    if (callerid)
06879       dpr->callerid = ast_strdup(callerid);
06880    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06881       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06882    }
06883 
06884    pthread_attr_destroy(&attr);
06885 }
06886 
06887 struct iax_dual {
06888    struct ast_channel *chan1;
06889    struct ast_channel *chan2;
06890 };
06891 
06892 static void *iax_park_thread(void *stuff)
06893 {
06894    struct ast_channel *chan1, *chan2;
06895    struct iax_dual *d;
06896    struct ast_frame *f;
06897    int ext;
06898    int res;
06899    d = stuff;
06900    chan1 = d->chan1;
06901    chan2 = d->chan2;
06902    free(d);
06903    f = ast_read(chan1);
06904    if (f)
06905       ast_frfree(f);
06906    res = ast_park_call(chan1, chan2, 0, &ext);
06907    ast_hangup(chan2);
06908    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06909    return NULL;
06910 }
06911 
06912 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06913 {
06914    struct iax_dual *d;
06915    struct ast_channel *chan1m, *chan2m;
06916    pthread_t th;
06917    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06918    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06919    if (chan2m && chan1m) {
06920       /* Make formats okay */
06921       chan1m->readformat = chan1->readformat;
06922       chan1m->writeformat = chan1->writeformat;
06923       ast_channel_masquerade(chan1m, chan1);
06924       /* Setup the extensions and such */
06925       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06926       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06927       chan1m->priority = chan1->priority;
06928       
06929       /* We make a clone of the peer channel too, so we can play
06930          back the announcement */
06931       /* Make formats okay */
06932       chan2m->readformat = chan2->readformat;
06933       chan2m->writeformat = chan2->writeformat;
06934       ast_channel_masquerade(chan2m, chan2);
06935       /* Setup the extensions and such */
06936       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06937       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06938       chan2m->priority = chan2->priority;
06939       if (ast_do_masquerade(chan2m)) {
06940          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06941          ast_hangup(chan2m);
06942          return -1;
06943       }
06944    } else {
06945       if (chan1m)
06946          ast_hangup(chan1m);
06947       if (chan2m)
06948          ast_hangup(chan2m);
06949       return -1;
06950    }
06951    if ((d = ast_calloc(1, sizeof(*d)))) {
06952       pthread_attr_t attr;
06953 
06954       pthread_attr_init(&attr);
06955       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06956 
06957       d->chan1 = chan1m;
06958       d->chan2 = chan2m;
06959       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06960          pthread_attr_destroy(&attr);
06961          return 0;
06962       }
06963       pthread_attr_destroy(&attr);
06964       free(d);
06965    }
06966    return -1;
06967 }
06968 
06969 
06970 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06971 
06972 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06973 {
06974    unsigned int ourver;
06975    char rsi[80];
06976    snprintf(rsi, sizeof(rsi), "si-%s", si);
06977    if (iax_provision_version(&ourver, rsi, 1))
06978       return 0;
06979    if (option_debug)
06980       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06981    if (ourver != ver) 
06982       iax2_provision(sin, sockfd, NULL, rsi, 1);
06983    return 0;
06984 }
06985 
06986 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06987 {
06988    jb_info stats;
06989    jb_getinfo(pvt->jb, &stats);
06990    
06991    memset(iep, 0, sizeof(*iep));
06992 
06993    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06994    if(stats.frames_in == 0) stats.frames_in = 1;
06995    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06996    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06997    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06998    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06999    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07000 }
07001 
07002 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
07003 {
07004    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07005    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07006    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07007    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07008    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07009    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07010    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07011 }
07012 
07013 static int socket_process(struct iax2_thread *thread);
07014 
07015 /*!
07016  * \brief Handle any deferred full frames for this thread
07017  */
07018 static void handle_deferred_full_frames(struct iax2_thread *thread)
07019 {
07020    struct iax2_pkt_buf *pkt_buf;
07021 
07022    ast_mutex_lock(&thread->lock);
07023 
07024    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07025       ast_mutex_unlock(&thread->lock);
07026 
07027       thread->buf = pkt_buf->buf;
07028       thread->buf_len = pkt_buf->len;
07029       thread->buf_size = pkt_buf->len + 1;
07030       
07031       socket_process(thread);
07032 
07033       thread->buf = NULL;
07034       ast_free(pkt_buf);
07035 
07036       ast_mutex_lock(&thread->lock);
07037    }
07038 
07039    ast_mutex_unlock(&thread->lock);
07040 }
07041 
07042 /*!
07043  * \brief Queue the last read full frame for processing by a certain thread
07044  *
07045  * If there are already any full frames queued, they are sorted
07046  * by sequence number.
07047  */
07048 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07049 {
07050    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07051    struct ast_iax2_full_hdr *fh, *cur_fh;
07052 
07053    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07054       return;
07055 
07056    pkt_buf->len = from_here->buf_len;
07057    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07058 
07059    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07060    ast_mutex_lock(&to_here->lock);
07061    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07062       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07063       if (fh->oseqno < cur_fh->oseqno) {
07064          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
07065          break;
07066       }
07067    }
07068    AST_LIST_TRAVERSE_SAFE_END
07069 
07070    if (!cur_pkt_buf)
07071       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07072    
07073    ast_mutex_unlock(&to_here->lock);
07074 }
07075 
07076 static int socket_read(int *id, int fd, short events, void *cbdata)
07077 {
07078    struct iax2_thread *thread;
07079    socklen_t len;
07080    time_t t;
07081    static time_t last_errtime = 0;
07082    struct ast_iax2_full_hdr *fh;
07083 
07084    if (!(thread = find_idle_thread())) {
07085       time(&t);
07086       if (t != last_errtime && option_debug)
07087          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
07088       last_errtime = t;
07089       usleep(1);
07090       return 1;
07091    }
07092 
07093    len = sizeof(thread->iosin);
07094    thread->iofd = fd;
07095    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07096    thread->buf_size = sizeof(thread->readbuf);
07097    thread->buf = thread->readbuf;
07098    if (thread->buf_len < 0) {
07099       if (errno != ECONNREFUSED && errno != EAGAIN)
07100          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07101       handle_error();
07102       thread->iostate = IAX_IOSTATE_IDLE;
07103       signal_condition(&thread->lock, &thread->cond);
07104       return 1;
07105    }
07106    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
07107       thread->iostate = IAX_IOSTATE_IDLE;
07108       signal_condition(&thread->lock, &thread->cond);
07109       return 1;
07110    }
07111    
07112    /* Determine if this frame is a full frame; if so, and any thread is currently
07113       processing a full frame for the same callno from this peer, then drop this
07114       frame (and the peer will retransmit it) */
07115    fh = (struct ast_iax2_full_hdr *) thread->buf;
07116    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
07117       struct iax2_thread *cur = NULL;
07118       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
07119       
07120       AST_LIST_LOCK(&active_list);
07121       AST_LIST_TRAVERSE(&active_list, cur, list) {
07122          if ((cur->ffinfo.callno == callno) &&
07123              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
07124             break;
07125       }
07126       if (cur) {
07127          /* we found another thread processing a full frame for this call,
07128             so queue it up for processing later. */
07129          defer_full_frame(thread, cur);
07130          AST_LIST_UNLOCK(&active_list);
07131          thread->iostate = IAX_IOSTATE_IDLE;
07132          signal_condition(&thread->lock, &thread->cond);
07133          return 1;
07134       } else {
07135          /* this thread is going to process this frame, so mark it */
07136          thread->ffinfo.callno = callno;
07137          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
07138          thread->ffinfo.type = fh->type;
07139          thread->ffinfo.csub = fh->csub;
07140       }
07141       AST_LIST_UNLOCK(&active_list);
07142    }
07143    
07144    /* Mark as ready and send on its way */
07145    thread->iostate = IAX_IOSTATE_READY;
07146 #ifdef DEBUG_SCHED_MULTITHREAD
07147    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07148 #endif
07149    signal_condition(&thread->lock, &thread->cond);
07150 
07151    return 1;
07152 }
07153 
07154 static int socket_process(struct iax2_thread *thread)
07155 {
07156    struct sockaddr_in sin;
07157    int res;
07158    int updatehistory=1;
07159    int new = NEW_PREVENT;
07160    void *ptr;
07161    int dcallno = 0;
07162    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07163    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07164    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07165    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07166    struct ast_iax2_meta_trunk_hdr *mth;
07167    struct ast_iax2_meta_trunk_entry *mte;
07168    struct ast_iax2_meta_trunk_mini *mtm;
07169    struct iax_frame *fr;
07170    struct iax_frame *cur;
07171    struct ast_frame f = { 0, };
07172    struct ast_channel *c;
07173    struct iax2_dpcache *dp;
07174    struct iax2_peer *peer;
07175    struct iax2_trunk_peer *tpeer;
07176    struct timeval rxtrunktime;
07177    struct iax_ies ies;
07178    struct iax_ie_data ied0, ied1;
07179    int format;
07180    int fd;
07181    int exists;
07182    int minivid = 0;
07183    unsigned int ts;
07184    char empty[32]="";      /* Safety measure */
07185    struct iax_frame *duped_fr;
07186    char host_pref_buf[128];
07187    char caller_pref_buf[128];
07188    struct ast_codec_pref pref;
07189    char *using_prefs = "mine";
07190 
07191    /* allocate an iax_frame with 4096 bytes of data buffer */
07192    fr = alloca(sizeof(*fr) + 4096);
07193    memset(fr, 0, sizeof(*fr));
07194    fr->afdatalen = 4096; /* From alloca() above */
07195 
07196    /* Copy frequently used parameters to the stack */
07197    res = thread->buf_len;
07198    fd = thread->iofd;
07199    memcpy(&sin, &thread->iosin, sizeof(sin));
07200 
07201    if (res < sizeof(*mh)) {
07202       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07203       return 1;
07204    }
07205    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07206       if (res < sizeof(*vh)) {
07207          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));
07208          return 1;
07209       }
07210 
07211       /* This is a video frame, get call number */
07212       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07213       minivid = 1;
07214    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07215       unsigned char metatype;
07216 
07217       if (res < sizeof(*meta)) {
07218          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07219          return 1;
07220       }
07221 
07222       /* This is a meta header */
07223       switch(meta->metacmd) {
07224       case IAX_META_TRUNK:
07225          if (res < (sizeof(*meta) + sizeof(*mth))) {
07226             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07227                sizeof(*meta) + sizeof(*mth));
07228             return 1;
07229          }
07230          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07231          ts = ntohl(mth->ts);
07232          metatype = meta->cmddata;
07233          res -= (sizeof(*meta) + sizeof(*mth));
07234          ptr = mth->data;
07235          tpeer = find_tpeer(&sin, fd);
07236          if (!tpeer) {
07237             ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07238             return 1;
07239          }
07240          tpeer->trunkact = ast_tvnow();
07241          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07242             tpeer->rxtrunktime = tpeer->trunkact;
07243          rxtrunktime = tpeer->rxtrunktime;
07244          ast_mutex_unlock(&tpeer->lock);
07245          while(res >= sizeof(*mte)) {
07246             /* Process channels */
07247             unsigned short callno, trunked_ts, len;
07248 
07249             if (metatype == IAX_META_TRUNK_MINI) {
07250                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07251                ptr += sizeof(*mtm);
07252                res -= sizeof(*mtm);
07253                len = ntohs(mtm->len);
07254                callno = ntohs(mtm->mini.callno);
07255                trunked_ts = ntohs(mtm->mini.ts);
07256             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07257                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07258                ptr += sizeof(*mte);
07259                res -= sizeof(*mte);
07260                len = ntohs(mte->len);
07261                callno = ntohs(mte->callno);
07262                trunked_ts = 0;
07263             } else {
07264                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07265                break;
07266             }
07267             /* Stop if we don't have enough data */
07268             if (len > res)
07269                break;
07270             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07271             if (fr->callno) {
07272                /* If it's a valid call, deliver the contents.  If not, we
07273                   drop it, since we don't have a scallno to use for an INVAL */
07274                /* Process as a mini frame */
07275                memset(&f, 0, sizeof(f));
07276                f.frametype = AST_FRAME_VOICE;
07277                if (iaxs[fr->callno]) {
07278                   if (iaxs[fr->callno]->voiceformat > 0) {
07279                      f.subclass = iaxs[fr->callno]->voiceformat;
07280                      f.datalen = len;
07281                      if (f.datalen >= 0) {
07282                         if (f.datalen)
07283                            f.data = ptr;
07284                         if(trunked_ts) {
07285                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07286                         } else
07287                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07288                         /* Don't pass any packets until we're started */
07289                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07290                            /* Common things */
07291                            f.src = "IAX2";
07292                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07293                               f.samples = ast_codec_get_samples(&f);
07294                            iax_frame_wrap(fr, &f);
07295                            duped_fr = iaxfrdup2(fr);
07296                            if (duped_fr) {
07297                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07298                            }
07299                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07300                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07301                               iaxs[fr->callno]->last = fr->ts;
07302 #if 1
07303                               if (option_debug && iaxdebug)
07304                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07305 #endif
07306                            }
07307                         }
07308                      } else {
07309                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07310                      }
07311                   } else {
07312                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
07313                      iax2_vnak(fr->callno);
07314                   }
07315                }
07316                ast_mutex_unlock(&iaxsl[fr->callno]);
07317             }
07318             ptr += len;
07319             res -= len;
07320          }
07321          
07322       }
07323       return 1;
07324    }
07325 
07326 #ifdef DEBUG_SUPPORT
07327    if (iaxdebug && (res >= sizeof(*fh)))
07328       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07329 #endif
07330    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07331       if (res < sizeof(*fh)) {
07332          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));
07333          return 1;
07334       }
07335 
07336       /* Get the destination call number */
07337       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07338       /* Retrieve the type and subclass */
07339       f.frametype = fh->type;
07340       if (f.frametype == AST_FRAME_VIDEO) {
07341          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07342       } else {
07343          f.subclass = uncompress_subclass(fh->csub);
07344       }
07345 
07346       /* Deal with POKE/PONG without allocating a callno */
07347       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07348          /* Reply back with a PONG, but don't care about the result. */
07349          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1);
07350          return 1;
07351       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07352          /* Ignore */
07353          return 1;
07354       }
07355 
07356       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07357                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07358                          (f.subclass == IAX_COMMAND_REGREL)))
07359          new = NEW_ALLOW;
07360    } else {
07361       /* Don't know anything about it yet */
07362       f.frametype = AST_FRAME_NULL;
07363       f.subclass = 0;
07364    }
07365 
07366    if (!fr->callno) {
07367       int check_dcallno = 0;
07368 
07369       /*
07370        * We enforce accurate destination call numbers for all full frames except
07371        * LAGRQ and PING commands.  This is because older versions of Asterisk
07372        * schedule these commands to get sent very quickly, and they will sometimes
07373        * be sent before they receive the first frame from the other side.  When
07374        * that happens, it doesn't contain the destination call number.  However,
07375        * not checking it for these frames is safe.
07376        * 
07377        * Discussed in the following thread:
07378        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07379        */
07380 
07381       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07382          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07383       }
07384 
07385       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07386    }
07387 
07388    if (fr->callno > 0)
07389       ast_mutex_lock(&iaxsl[fr->callno]);
07390 
07391    if (!fr->callno || !iaxs[fr->callno]) {
07392       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07393          frame, reply with an inval */
07394       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07395          /* We can only raw hangup control frames */
07396          if (((f.subclass != IAX_COMMAND_INVAL) &&
07397              (f.subclass != IAX_COMMAND_TXCNT) &&
07398              (f.subclass != IAX_COMMAND_TXACC) &&
07399              (f.subclass != IAX_COMMAND_FWDOWNL))||
07400              (f.frametype != AST_FRAME_IAX))
07401             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07402             fd);
07403       }
07404       if (fr->callno > 0) 
07405          ast_mutex_unlock(&iaxsl[fr->callno]);
07406       return 1;
07407    }
07408    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07409       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07410          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07411          ast_mutex_unlock(&iaxsl[fr->callno]);
07412          return 1;
07413       }
07414 #ifdef DEBUG_SUPPORT
07415       else if (iaxdebug)
07416          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07417 #endif
07418    }
07419 
07420    /* count this frame */
07421    iaxs[fr->callno]->frames_received++;
07422 
07423    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07424       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07425       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07426       unsigned short new_peercallno;
07427 
07428       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07429       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07430          if (iaxs[fr->callno]->peercallno) {
07431             remove_by_peercallno(iaxs[fr->callno]);
07432          }
07433          iaxs[fr->callno]->peercallno = new_peercallno;
07434          store_by_peercallno(iaxs[fr->callno]);
07435       }
07436    }
07437    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07438       if (option_debug  && iaxdebug)
07439          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07440       /* Check if it's out of order (and not an ACK or INVAL) */
07441       fr->oseqno = fh->oseqno;
07442       fr->iseqno = fh->iseqno;
07443       fr->ts = ntohl(fh->ts);
07444 #ifdef IAXTESTS
07445       if (test_resync) {
07446          if (option_debug)
07447             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07448          fr->ts += test_resync;
07449       }
07450 #endif /* IAXTESTS */
07451 #if 0
07452       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07453            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07454                         (f.subclass == IAX_COMMAND_NEW ||
07455                          f.subclass == IAX_COMMAND_AUTHREQ ||
07456                          f.subclass == IAX_COMMAND_ACCEPT ||
07457                          f.subclass == IAX_COMMAND_REJECT))      ) )
07458 #endif
07459       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07460          updatehistory = 0;
07461       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07462          (iaxs[fr->callno]->iseqno ||
07463             ((f.subclass != IAX_COMMAND_TXCNT) &&
07464             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07465             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07466             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07467             (f.subclass != IAX_COMMAND_TXACC)) ||
07468             (f.frametype != AST_FRAME_IAX))) {
07469          if (
07470           ((f.subclass != IAX_COMMAND_ACK) &&
07471            (f.subclass != IAX_COMMAND_INVAL) &&
07472            (f.subclass != IAX_COMMAND_TXCNT) &&
07473            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07474            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07475            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07476            (f.subclass != IAX_COMMAND_TXACC) &&
07477            (f.subclass != IAX_COMMAND_VNAK)) ||
07478            (f.frametype != AST_FRAME_IAX)) {
07479             /* If it's not an ACK packet, it's out of order. */
07480             if (option_debug)
07481                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07482                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07483             /* Check to see if we need to request retransmission,
07484              * and take sequence number wraparound into account */
07485             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07486                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07487                if ((f.frametype != AST_FRAME_IAX) || 
07488                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07489                   if (option_debug)
07490                      ast_log(LOG_DEBUG, "Acking anyway\n");
07491                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07492                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07493                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07494                }
07495             } else {
07496                /* Send a VNAK requesting retransmission */
07497                iax2_vnak(fr->callno);
07498             }
07499             ast_mutex_unlock(&iaxsl[fr->callno]);
07500             return 1;
07501          }
07502       } else {
07503          /* Increment unless it's an ACK or VNAK */
07504          if (((f.subclass != IAX_COMMAND_ACK) &&
07505              (f.subclass != IAX_COMMAND_INVAL) &&
07506              (f.subclass != IAX_COMMAND_TXCNT) &&
07507              (f.subclass != IAX_COMMAND_TXACC) &&
07508             (f.subclass != IAX_COMMAND_VNAK)) ||
07509              (f.frametype != AST_FRAME_IAX))
07510             iaxs[fr->callno]->iseqno++;
07511       }
07512       /* A full frame */
07513       if (res < sizeof(*fh)) {
07514          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07515          ast_mutex_unlock(&iaxsl[fr->callno]);
07516          return 1;
07517       }
07518       /* Ensure text frames are NULL-terminated */
07519       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07520          if (res < thread->buf_size)
07521             thread->buf[res++] = '\0';
07522          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07523             thread->buf[res - 1] = '\0';
07524       }
07525       f.datalen = res - sizeof(*fh);
07526 
07527       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07528          from the real peer, not the transfer peer */
07529       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07530           ((f.subclass != IAX_COMMAND_INVAL) ||
07531            (f.frametype != AST_FRAME_IAX))) {
07532          unsigned char x;
07533          int call_to_destroy;
07534          /* XXX This code is not very efficient.  Surely there is a better way which still
07535                 properly handles boundary conditions? XXX */
07536          /* First we have to qualify that the ACKed value is within our window */
07537          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07538             if (fr->iseqno == x)
07539                break;
07540          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07541             /* The acknowledgement is within our window.  Time to acknowledge everything
07542                that it says to */
07543             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07544                /* Ack the packet with the given timestamp */
07545                if (option_debug && iaxdebug)
07546                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07547                call_to_destroy = 0;
07548                AST_LIST_LOCK(&iaxq.queue);
07549                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07550                   /* If it's our call, and our timestamp, mark -1 retries */
07551                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07552                      cur->retries = -1;
07553                      /* Destroy call if this is the end */
07554                      if (cur->final)
07555                         call_to_destroy = fr->callno;
07556                   }
07557                }
07558                AST_LIST_UNLOCK(&iaxq.queue);
07559                if (call_to_destroy) {
07560                   if (iaxdebug && option_debug)
07561                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07562                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07563                   iax2_destroy(call_to_destroy);
07564                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07565                }
07566             }
07567             /* Note how much we've received acknowledgement for */
07568             if (iaxs[fr->callno])
07569                iaxs[fr->callno]->rseqno = fr->iseqno;
07570             else {
07571                /* Stop processing now */
07572                ast_mutex_unlock(&iaxsl[fr->callno]);
07573                return 1;
07574             }
07575          } else if (option_debug)
07576             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07577       }
07578       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07579          ((f.frametype != AST_FRAME_IAX) || 
07580           ((f.subclass != IAX_COMMAND_TXACC) &&
07581            (f.subclass != IAX_COMMAND_TXCNT)))) {
07582          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07583          ast_mutex_unlock(&iaxsl[fr->callno]);
07584          return 1;
07585       }
07586 
07587       if (f.datalen) {
07588          if (f.frametype == AST_FRAME_IAX) {
07589             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07590                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07591                ast_mutex_unlock(&iaxsl[fr->callno]);
07592                return 1;
07593             }
07594             f.data = NULL;
07595             f.datalen = 0;
07596          } else
07597             f.data = thread->buf + sizeof(*fh);
07598       } else {
07599          if (f.frametype == AST_FRAME_IAX)
07600             f.data = NULL;
07601          else
07602             f.data = empty;
07603          memset(&ies, 0, sizeof(ies));
07604       }
07605 
07606       /* when we receive the first full frame for a new incoming channel,
07607          it is safe to start the PBX on the channel because we have now
07608          completed a 3-way handshake with the peer */
07609       if ((f.frametype == AST_FRAME_VOICE) ||
07610           (f.frametype == AST_FRAME_VIDEO) ||
07611           (f.frametype == AST_FRAME_IAX)) {
07612          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07613             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07614             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07615                ast_mutex_unlock(&iaxsl[fr->callno]);
07616                return 1;
07617             }
07618          }
07619       }
07620 
07621       if (f.frametype == AST_FRAME_VOICE) {
07622          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07623                iaxs[fr->callno]->voiceformat = f.subclass;
07624                if (option_debug)
07625                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07626                if (iaxs[fr->callno]->owner) {
07627                   int orignative;
07628 retryowner:
07629                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07630                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07631                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07632                   }
07633                   if (iaxs[fr->callno]) {
07634                      if (iaxs[fr->callno]->owner) {
07635                         orignative = iaxs[fr->callno]->owner->nativeformats;
07636                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07637                         if (iaxs[fr->callno]->owner->readformat)
07638                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07639                         iaxs[fr->callno]->owner->nativeformats = orignative;
07640                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07641                      }
07642                   } else {
07643                      if (option_debug)
07644                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07645                      ast_mutex_unlock(&iaxsl[fr->callno]);
07646                      return 1;
07647                   }
07648                }
07649          }
07650       }
07651       if (f.frametype == AST_FRAME_VIDEO) {
07652          if (f.subclass != iaxs[fr->callno]->videoformat) {
07653             if (option_debug)
07654                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07655             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07656          }
07657       }
07658       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
07659          if (f.subclass == AST_CONTROL_BUSY) {
07660             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
07661          } else if (f.subclass == AST_CONTROL_CONGESTION) {
07662             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
07663          }
07664       }
07665       if (f.frametype == AST_FRAME_IAX) {
07666          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07667          /* Handle the IAX pseudo frame itself */
07668          if (option_debug && iaxdebug)
07669             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07670 
07671                         /* Update last ts unless the frame's timestamp originated with us. */
07672          if (iaxs[fr->callno]->last < fr->ts &&
07673                             f.subclass != IAX_COMMAND_ACK &&
07674                             f.subclass != IAX_COMMAND_PONG &&
07675                             f.subclass != IAX_COMMAND_LAGRP) {
07676             iaxs[fr->callno]->last = fr->ts;
07677             if (option_debug && iaxdebug)
07678                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07679          }
07680 
07681          switch(f.subclass) {
07682          case IAX_COMMAND_ACK:
07683             /* Do nothing */
07684             break;
07685          case IAX_COMMAND_QUELCH:
07686             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07687                     /* Generate Manager Hold event, if necessary*/
07688                if (iaxs[fr->callno]->owner) {
07689                   manager_event(EVENT_FLAG_CALL, "Hold",
07690                      "Channel: %s\r\n"
07691                      "Uniqueid: %s\r\n",
07692                      iaxs[fr->callno]->owner->name, 
07693                      iaxs[fr->callno]->owner->uniqueid);
07694                }
07695 
07696                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07697                if (ies.musiconhold) {
07698                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07699                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07700                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07701                         S_OR(mohsuggest, NULL),
07702                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07703                      if (!iaxs[fr->callno]) {
07704                         ast_mutex_unlock(&iaxsl[fr->callno]);
07705                         return 1;
07706                      }
07707                   }
07708                }
07709             }
07710             break;
07711          case IAX_COMMAND_UNQUELCH:
07712             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07713                     /* Generate Manager Unhold event, if necessary*/
07714                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07715                   manager_event(EVENT_FLAG_CALL, "Unhold",
07716                      "Channel: %s\r\n"
07717                      "Uniqueid: %s\r\n",
07718                      iaxs[fr->callno]->owner->name, 
07719                      iaxs[fr->callno]->owner->uniqueid);
07720                }
07721 
07722                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07723                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07724                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07725                   if (!iaxs[fr->callno]) {
07726                      ast_mutex_unlock(&iaxsl[fr->callno]);
07727                      return 1;
07728                   }
07729                }
07730             }
07731             break;
07732          case IAX_COMMAND_TXACC:
07733             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07734                /* Ack the packet with the given timestamp */
07735                AST_LIST_LOCK(&iaxq.queue);
07736                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07737                   /* Cancel any outstanding txcnt's */
07738                   if ((fr->callno == cur->callno) && (cur->transfer))
07739                      cur->retries = -1;
07740                }
07741                AST_LIST_UNLOCK(&iaxq.queue);
07742                memset(&ied1, 0, sizeof(ied1));
07743                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07744                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07745                iaxs[fr->callno]->transferring = TRANSFER_READY;
07746             }
07747             break;
07748          case IAX_COMMAND_NEW:
07749             /* Ignore if it's already up */
07750             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07751                break;
07752             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07753                ast_mutex_unlock(&iaxsl[fr->callno]);
07754                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07755                ast_mutex_lock(&iaxsl[fr->callno]);
07756                if (!iaxs[fr->callno]) {
07757                   ast_mutex_unlock(&iaxsl[fr->callno]);
07758                   return 1;
07759                }
07760             }
07761             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07762             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07763                int new_callno;
07764                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07765                   fr->callno = new_callno;
07766             }
07767             /* For security, always ack immediately */
07768             if (delayreject)
07769                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07770             if (check_access(fr->callno, &sin, &ies)) {
07771                /* They're not allowed on */
07772                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07773                if (authdebug)
07774                   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);
07775                break;
07776             }
07777             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07778                const char *context, *exten, *cid_num;
07779 
07780                context = ast_strdupa(iaxs[fr->callno]->context);
07781                exten = ast_strdupa(iaxs[fr->callno]->exten);
07782                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07783 
07784                /* This might re-enter the IAX code and need the lock */
07785                ast_mutex_unlock(&iaxsl[fr->callno]);
07786                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07787                ast_mutex_lock(&iaxsl[fr->callno]);
07788 
07789                if (!iaxs[fr->callno]) {
07790                   ast_mutex_unlock(&iaxsl[fr->callno]);
07791                   return 1;
07792                }
07793             } else
07794                exists = 0;
07795             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07796                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07797                   memset(&ied0, 0, sizeof(ied0));
07798                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07799                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07800                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07801                   if (!iaxs[fr->callno]) {
07802                      ast_mutex_unlock(&iaxsl[fr->callno]);
07803                      return 1;
07804                   }
07805                   if (authdebug)
07806                      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);
07807                } else {
07808                   /* Select an appropriate format */
07809 
07810                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07811                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07812                         using_prefs = "reqonly";
07813                      } else {
07814                         using_prefs = "disabled";
07815                      }
07816                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07817                      memset(&pref, 0, sizeof(pref));
07818                      strcpy(caller_pref_buf, "disabled");
07819                      strcpy(host_pref_buf, "disabled");
07820                   } else {
07821                      using_prefs = "mine";
07822                      /* If the information elements are in here... use them */
07823                      if (ies.codec_prefs)
07824                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07825                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07826                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07827                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07828                            pref = iaxs[fr->callno]->rprefs;
07829                            using_prefs = "caller";
07830                         } else {
07831                            pref = iaxs[fr->callno]->prefs;
07832                         }
07833                      } else
07834                         pref = iaxs[fr->callno]->prefs;
07835                      
07836                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07837                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07838                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07839                   }
07840                   if (!format) {
07841                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07842                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07843                      if (!format) {
07844                         memset(&ied0, 0, sizeof(ied0));
07845                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07846                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07847                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07848                         if (!iaxs[fr->callno]) {
07849                            ast_mutex_unlock(&iaxsl[fr->callno]);
07850                            return 1;
07851                         }
07852                         if (authdebug) {
07853                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07854                               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);
07855                            else 
07856                               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);
07857                         }
07858                      } else {
07859                         /* Pick one... */
07860                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07861                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07862                               format = 0;
07863                         } else {
07864                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07865                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07866                               memset(&pref, 0, sizeof(pref));
07867                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07868                               strcpy(caller_pref_buf,"disabled");
07869                               strcpy(host_pref_buf,"disabled");
07870                            } else {
07871                               using_prefs = "mine";
07872                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07873                                  /* Do the opposite of what we tried above. */
07874                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07875                                     pref = iaxs[fr->callno]->prefs;                       
07876                                  } else {
07877                                     pref = iaxs[fr->callno]->rprefs;
07878                                     using_prefs = "caller";
07879                                  }
07880                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07881                            
07882                               } else /* if no codec_prefs IE do it the old way */
07883                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07884                            }
07885                         }
07886 
07887                         if (!format) {
07888                            memset(&ied0, 0, sizeof(ied0));
07889                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07890                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07891                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07892                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07893                            if (!iaxs[fr->callno]) {
07894                               ast_mutex_unlock(&iaxsl[fr->callno]);
07895                               return 1;
07896                            }
07897                            if (authdebug)
07898                               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);
07899                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07900                            break;
07901                         }
07902                      }
07903                   }
07904                   if (format) {
07905                      /* No authentication required, let them in */
07906                      memset(&ied1, 0, sizeof(ied1));
07907                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07908                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07909                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07910                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07911                         if (option_verbose > 2) 
07912                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07913                                     "%srequested format = %s,\n"
07914                                     "%srequested prefs = %s,\n"
07915                                     "%sactual format = %s,\n"
07916                                     "%shost prefs = %s,\n"
07917                                     "%spriority = %s\n",
07918                                     ast_inet_ntoa(sin.sin_addr), 
07919                                     VERBOSE_PREFIX_4,
07920                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07921                                     VERBOSE_PREFIX_4,
07922                                     caller_pref_buf,
07923                                     VERBOSE_PREFIX_4,
07924                                     ast_getformatname(format), 
07925                                     VERBOSE_PREFIX_4,
07926                                     host_pref_buf, 
07927                                     VERBOSE_PREFIX_4,
07928                                     using_prefs);
07929                         
07930                         iaxs[fr->callno]->chosenformat = format;
07931                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07932                      } else {
07933                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07934                         /* If this is a TBD call, we're ready but now what...  */
07935                         if (option_verbose > 2)
07936                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07937                      }
07938                   }
07939                }
07940                break;
07941             }
07942             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07943                merge_encryption(iaxs[fr->callno],ies.encmethods);
07944             else
07945                iaxs[fr->callno]->encmethods = 0;
07946             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07947                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07948             if (!iaxs[fr->callno]) {
07949                ast_mutex_unlock(&iaxsl[fr->callno]);
07950                return 1;
07951             }
07952             break;
07953          case IAX_COMMAND_DPREQ:
07954             /* Request status in the dialplan */
07955             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07956                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07957                if (iaxcompat) {
07958                   /* Spawn a thread for the lookup */
07959                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07960                } else {
07961                   /* Just look it up */
07962                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07963                }
07964             }
07965             break;
07966          case IAX_COMMAND_HANGUP:
07967             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07968             if (option_debug)
07969                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07970             /* Set hangup cause according to remote */
07971             if (ies.causecode && iaxs[fr->callno]->owner)
07972                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07973             /* Send ack immediately, before we destroy */
07974             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07975             iax2_destroy(fr->callno);
07976             break;
07977          case IAX_COMMAND_REJECT:
07978             /* Set hangup cause according to remote */
07979             if (ies.causecode && iaxs[fr->callno]->owner)
07980                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07981 
07982             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07983                if (iaxs[fr->callno]->owner && authdebug)
07984                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07985                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07986                      ies.cause ? ies.cause : "<Unknown>");
07987                if (option_debug)
07988                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07989                      fr->callno);
07990             }
07991             /* Send ack immediately, before we destroy */
07992             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07993                          fr->ts, NULL, 0, fr->iseqno);
07994             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07995                iaxs[fr->callno]->error = EPERM;
07996             iax2_destroy(fr->callno);
07997             break;
07998          case IAX_COMMAND_TRANSFER:
07999          {
08000             struct ast_channel *bridged_chan;
08001 
08002             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
08003                /* Set BLINDTRANSFER channel variables */
08004 
08005                ast_mutex_unlock(&iaxsl[fr->callno]);
08006                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
08007                ast_mutex_lock(&iaxsl[fr->callno]);
08008                if (!iaxs[fr->callno]) {
08009                   ast_mutex_unlock(&iaxsl[fr->callno]);
08010                   return 1;
08011                }
08012 
08013                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
08014                if (!strcmp(ies.called_number, ast_parking_ext())) {
08015                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
08016                   ast_mutex_unlock(&iaxsl[fr->callno]);
08017                   if (iax_park(bridged_chan, saved_channel)) {
08018                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
08019                   } else {
08020                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
08021                   }
08022                   ast_mutex_lock(&iaxsl[fr->callno]);
08023                } else {
08024                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
08025                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
08026                         ies.called_number, iaxs[fr->callno]->context);
08027                   else
08028                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
08029                         ies.called_number, iaxs[fr->callno]->context);
08030                }
08031             } else
08032                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
08033 
08034             break;
08035          }
08036          case IAX_COMMAND_ACCEPT:
08037             /* Ignore if call is already up or needs authentication or is a TBD */
08038             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
08039                break;
08040             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
08041                /* Send ack immediately, before we destroy */
08042                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08043                iax2_destroy(fr->callno);
08044                break;
08045             }
08046             if (ies.format) {
08047                iaxs[fr->callno]->peerformat = ies.format;
08048             } else {
08049                if (iaxs[fr->callno]->owner)
08050                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
08051                else
08052                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
08053             }
08054             if (option_verbose > 2)
08055                ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
08056             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
08057                memset(&ied0, 0, sizeof(ied0));
08058                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08059                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08060                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08061                if (!iaxs[fr->callno]) {
08062                   ast_mutex_unlock(&iaxsl[fr->callno]);
08063                   return 1;
08064                }
08065                if (authdebug)
08066                   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);
08067             } else {
08068                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08069                if (iaxs[fr->callno]->owner) {
08070                   /* Switch us to use a compatible format */
08071                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
08072                   if (option_verbose > 2)
08073                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
08074 retryowner2:
08075                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08076                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08077                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
08078                   }
08079                   
08080                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
08081                      /* Setup read/write formats properly. */
08082                      if (iaxs[fr->callno]->owner->writeformat)
08083                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
08084                      if (iaxs[fr->callno]->owner->readformat)
08085                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
08086                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08087                   }
08088                }
08089             }
08090             if (iaxs[fr->callno]) {
08091                ast_mutex_lock(&dpcache_lock);
08092                dp = iaxs[fr->callno]->dpentries;
08093                while(dp) {
08094                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
08095                      iax2_dprequest(dp, fr->callno);
08096                   }
08097                   dp = dp->peer;
08098                }
08099                ast_mutex_unlock(&dpcache_lock);
08100             }
08101             break;
08102          case IAX_COMMAND_POKE:
08103             /* Send back a pong packet with the original timestamp */
08104             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
08105             if (!iaxs[fr->callno]) {
08106                ast_mutex_unlock(&iaxsl[fr->callno]);
08107                return 1;
08108             }
08109             break;
08110          case IAX_COMMAND_PING:
08111          {
08112             struct iax_ie_data pingied;
08113             construct_rr(iaxs[fr->callno], &pingied);
08114             /* Send back a pong packet with the original timestamp */
08115             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
08116          }
08117             break;
08118          case IAX_COMMAND_PONG:
08119             /* Calculate ping time */
08120             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
08121             /* save RR info */
08122             save_rr(fr, &ies);
08123 
08124             if (iaxs[fr->callno]->peerpoke) {
08125                peer = iaxs[fr->callno]->peerpoke;
08126                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
08127                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
08128                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
08129                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08130                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08131                   }
08132                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
08133                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
08134                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
08135                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08136                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08137                   }
08138                }
08139                peer->lastms = iaxs[fr->callno]->pingtime;
08140                if (peer->smoothing && (peer->lastms > -1))
08141                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
08142                else if (peer->smoothing && peer->lastms < 0)
08143                   peer->historicms = (0 + peer->historicms) / 2;
08144                else              
08145                   peer->historicms = iaxs[fr->callno]->pingtime;
08146 
08147                /* Remove scheduled iax2_poke_noanswer */
08148                if (peer->pokeexpire > -1) {
08149                   if (!ast_sched_del(sched, peer->pokeexpire)) {
08150                      peer_unref(peer);
08151                      peer->pokeexpire = -1;
08152                   }
08153                }
08154                /* Schedule the next cycle */
08155                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
08156                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08157                else
08158                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08159                if (peer->pokeexpire == -1)
08160                   peer_unref(peer);
08161                /* and finally send the ack */
08162                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08163                /* And wrap up the qualify call */
08164                iax2_destroy(fr->callno);
08165                peer->callno = 0;
08166                if (option_debug)
08167                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08168             }
08169             break;
08170          case IAX_COMMAND_LAGRQ:
08171          case IAX_COMMAND_LAGRP:
08172             f.src = "LAGRQ";
08173             f.mallocd = 0;
08174             f.offset = 0;
08175             f.samples = 0;
08176             iax_frame_wrap(fr, &f);
08177             if(f.subclass == IAX_COMMAND_LAGRQ) {
08178                /* Received a LAGRQ - echo back a LAGRP */
08179                fr->af.subclass = IAX_COMMAND_LAGRP;
08180                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08181             } else {
08182                /* Received LAGRP in response to our LAGRQ */
08183                unsigned int ts;
08184                /* This is a reply we've been given, actually measure the difference */
08185                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08186                iaxs[fr->callno]->lag = ts - fr->ts;
08187                if (option_debug && iaxdebug)
08188                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08189                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08190             }
08191             break;
08192          case IAX_COMMAND_AUTHREQ:
08193             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08194                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>");
08195                break;
08196             }
08197             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08198                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08199                         .subclass = AST_CONTROL_HANGUP,
08200                };
08201                ast_log(LOG_WARNING, 
08202                   "I don't know how to authenticate %s to %s\n", 
08203                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08204                iax2_queue_frame(fr->callno, &hangup_fr);
08205             }
08206             if (!iaxs[fr->callno]) {
08207                ast_mutex_unlock(&iaxsl[fr->callno]);
08208                return 1;
08209             }
08210             break;
08211          case IAX_COMMAND_AUTHREP:
08212             /* For security, always ack immediately */
08213             if (delayreject)
08214                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08215             /* Ignore once we've started */
08216             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08217                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>");
08218                break;
08219             }
08220             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08221                if (authdebug)
08222                   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);
08223                memset(&ied0, 0, sizeof(ied0));
08224                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08225                break;
08226             }
08227             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08228                /* This might re-enter the IAX code and need the lock */
08229                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08230             } else
08231                exists = 0;
08232             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08233                if (authdebug)
08234                   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);
08235                memset(&ied0, 0, sizeof(ied0));
08236                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08237                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08238                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08239                if (!iaxs[fr->callno]) {
08240                   ast_mutex_unlock(&iaxsl[fr->callno]);
08241                   return 1;
08242                }
08243             } else {
08244                /* Select an appropriate format */
08245                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08246                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08247                      using_prefs = "reqonly";
08248                   } else {
08249                      using_prefs = "disabled";
08250                   }
08251                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08252                   memset(&pref, 0, sizeof(pref));
08253                   strcpy(caller_pref_buf, "disabled");
08254                   strcpy(host_pref_buf, "disabled");
08255                } else {
08256                   using_prefs = "mine";
08257                   if (ies.codec_prefs)
08258                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08259                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08260                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08261                         pref = iaxs[fr->callno]->rprefs;
08262                         using_prefs = "caller";
08263                      } else {
08264                         pref = iaxs[fr->callno]->prefs;
08265                      }
08266                   } else /* if no codec_prefs IE do it the old way */
08267                      pref = iaxs[fr->callno]->prefs;
08268                
08269                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08270                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08271                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08272                }
08273                if (!format) {
08274                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08275                      if (option_debug)
08276                         ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
08277                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08278                   }
08279                   if (!format) {
08280                      if (authdebug) {
08281                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08282                            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);
08283                         else
08284                            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);
08285                      }
08286                      memset(&ied0, 0, sizeof(ied0));
08287                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08288                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08289                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08290                      if (!iaxs[fr->callno]) {
08291                         ast_mutex_unlock(&iaxsl[fr->callno]);
08292                         return 1;
08293                      }
08294                   } else {
08295                      /* Pick one... */
08296                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08297                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08298                            format = 0;
08299                      } else {
08300                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08301                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08302                            memset(&pref, 0, sizeof(pref));
08303                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08304                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08305                            strcpy(caller_pref_buf,"disabled");
08306                            strcpy(host_pref_buf,"disabled");
08307                         } else {
08308                            using_prefs = "mine";
08309                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08310                               /* Do the opposite of what we tried above. */
08311                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08312                                  pref = iaxs[fr->callno]->prefs;                 
08313                               } else {
08314                                  pref = iaxs[fr->callno]->rprefs;
08315                                  using_prefs = "caller";
08316                               }
08317                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08318                            } else /* if no codec_prefs IE do it the old way */
08319                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08320                         }
08321                      }
08322                      if (!format) {
08323                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08324                         if (authdebug) {
08325                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08326                               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);
08327                            else
08328                               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);
08329                         }
08330                         memset(&ied0, 0, sizeof(ied0));
08331                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08332                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08333                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08334                         if (!iaxs[fr->callno]) {
08335                            ast_mutex_unlock(&iaxsl[fr->callno]);
08336                            return 1;
08337                         }
08338                      }
08339                   }
08340                }
08341                if (format) {
08342                   /* Authentication received */
08343                   memset(&ied1, 0, sizeof(ied1));
08344                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08345                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08346                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08347                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08348                      if (option_verbose > 2) 
08349                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08350                                  "%srequested format = %s,\n"
08351                                  "%srequested prefs = %s,\n"
08352                                  "%sactual format = %s,\n"
08353                                  "%shost prefs = %s,\n"
08354                                  "%spriority = %s\n", 
08355                                  ast_inet_ntoa(sin.sin_addr), 
08356                                  VERBOSE_PREFIX_4,
08357                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08358                                  VERBOSE_PREFIX_4,
08359                                  caller_pref_buf,
08360                                  VERBOSE_PREFIX_4,
08361                                  ast_getformatname(format),
08362                                  VERBOSE_PREFIX_4,
08363                                  host_pref_buf,
08364                                  VERBOSE_PREFIX_4,
08365                                  using_prefs);
08366 
08367                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08368                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08369                         iax2_destroy(fr->callno);
08370                   } else {
08371                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08372                      /* If this is a TBD call, we're ready but now what...  */
08373                      if (option_verbose > 2)
08374                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08375                   }
08376                }
08377             }
08378             break;
08379          case IAX_COMMAND_DIAL:
08380             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08381                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08382                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08383                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08384                   if (authdebug)
08385                      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);
08386                   memset(&ied0, 0, sizeof(ied0));
08387                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08388                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08389                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08390                   if (!iaxs[fr->callno]) {
08391                      ast_mutex_unlock(&iaxsl[fr->callno]);
08392                      return 1;
08393                   }
08394                } else {
08395                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08396                   if (option_verbose > 2) 
08397                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08398                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08399                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08400                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08401                      iax2_destroy(fr->callno);
08402                }
08403             }
08404             break;
08405          case IAX_COMMAND_INVAL:
08406             iaxs[fr->callno]->error = ENOTCONN;
08407             if (option_debug)
08408                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08409             iax2_destroy(fr->callno);
08410             if (option_debug)
08411                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08412             break;
08413          case IAX_COMMAND_VNAK:
08414             if (option_debug)
08415                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08416             /* Force retransmission */
08417             vnak_retransmit(fr->callno, fr->iseqno);
08418             break;
08419          case IAX_COMMAND_REGREQ:
08420          case IAX_COMMAND_REGREL:
08421             /* For security, always ack immediately */
08422             if (delayreject)
08423                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08424             if (register_verify(fr->callno, &sin, &ies)) {
08425                if (!iaxs[fr->callno]) {
08426                   ast_mutex_unlock(&iaxsl[fr->callno]);
08427                   return 1;
08428                }
08429                /* Send delayed failure */
08430                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08431                break;
08432             }
08433             if (!iaxs[fr->callno]) {
08434                ast_mutex_unlock(&iaxsl[fr->callno]);
08435                return 1;
08436             }
08437             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08438                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08439                if (f.subclass == IAX_COMMAND_REGREL)
08440                   memset(&sin, 0, sizeof(sin));
08441                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08442                   ast_log(LOG_WARNING, "Registry error\n");
08443                if (!iaxs[fr->callno]) {
08444                   ast_mutex_unlock(&iaxsl[fr->callno]);
08445                   return 1;
08446                }
08447                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08448                   ast_mutex_unlock(&iaxsl[fr->callno]);
08449                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08450                   ast_mutex_lock(&iaxsl[fr->callno]);
08451                   if (!iaxs[fr->callno]) {
08452                      ast_mutex_unlock(&iaxsl[fr->callno]);
08453                      return 1;
08454                   }
08455                }
08456                break;
08457             }
08458             registry_authrequest(fr->callno);
08459             if (!iaxs[fr->callno]) {
08460                ast_mutex_unlock(&iaxsl[fr->callno]);
08461                return 1;
08462             }
08463             break;
08464          case IAX_COMMAND_REGACK:
08465             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08466                ast_log(LOG_WARNING, "Registration failure\n");
08467             /* Send ack immediately, before we destroy */
08468             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08469             iax2_destroy(fr->callno);
08470             break;
08471          case IAX_COMMAND_REGREJ:
08472             if (iaxs[fr->callno]->reg) {
08473                if (authdebug) {
08474                   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));
08475                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
08476                }
08477                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08478             }
08479             /* Send ack immediately, before we destroy */
08480             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08481             iax2_destroy(fr->callno);
08482             break;
08483          case IAX_COMMAND_REGAUTH:
08484             /* Authentication request */
08485             if (registry_rerequest(&ies, fr->callno, &sin)) {
08486                memset(&ied0, 0, sizeof(ied0));
08487                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08488                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08489                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08490                if (!iaxs[fr->callno]) {
08491                   ast_mutex_unlock(&iaxsl[fr->callno]);
08492                   return 1;
08493                }
08494             }
08495             break;
08496          case IAX_COMMAND_TXREJ:
08497             iaxs[fr->callno]->transferring = 0;
08498             if (option_verbose > 2) 
08499                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08500             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08501             if (iaxs[fr->callno]->bridgecallno) {
08502                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08503                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08504                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08505                }
08506             }
08507             break;
08508          case IAX_COMMAND_TXREADY:
08509             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08510                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08511                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08512                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08513                else
08514                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08515                if (option_verbose > 2) 
08516                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08517                if (iaxs[fr->callno]->bridgecallno) {
08518                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08519                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08520                      /* They're both ready, now release them. */
08521                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08522                         if (option_verbose > 2) 
08523                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08524                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08525 
08526                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08527                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08528 
08529                         memset(&ied0, 0, sizeof(ied0));
08530                         memset(&ied1, 0, sizeof(ied1));
08531                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08532                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08533                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08534                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08535                      } else {
08536                         if (option_verbose > 2) 
08537                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08538                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08539 
08540                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08541                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08542                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08543                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08544 
08545                         /* Stop doing lag & ping requests */
08546                         stop_stuff(fr->callno);
08547                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08548 
08549                         memset(&ied0, 0, sizeof(ied0));
08550                         memset(&ied1, 0, sizeof(ied1));
08551                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08552                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08553                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08554                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08555                      }
08556 
08557                   }
08558                }
08559             }
08560             break;
08561          case IAX_COMMAND_TXREQ:
08562             try_transfer(iaxs[fr->callno], &ies);
08563             break;
08564          case IAX_COMMAND_TXCNT:
08565             if (iaxs[fr->callno]->transferring)
08566                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08567             break;
08568          case IAX_COMMAND_TXREL:
08569             /* Send ack immediately, rather than waiting until we've changed addresses */
08570             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08571             complete_transfer(fr->callno, &ies);
08572             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08573             break;   
08574          case IAX_COMMAND_TXMEDIA:
08575             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08576                                         AST_LIST_LOCK(&iaxq.queue);
08577                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08578                                                 /* Cancel any outstanding frames and start anew */
08579                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08580                                                         cur->retries = -1;
08581                                                 }
08582                                         }
08583                                         AST_LIST_UNLOCK(&iaxq.queue);
08584                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08585                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08586             }
08587             break;   
08588          case IAX_COMMAND_DPREP:
08589             complete_dpreply(iaxs[fr->callno], &ies);
08590             break;
08591          case IAX_COMMAND_UNSUPPORT:
08592             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08593             break;
08594          case IAX_COMMAND_FWDOWNL:
08595             /* Firmware download */
08596             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08597                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08598                break;
08599             }
08600             memset(&ied0, 0, sizeof(ied0));
08601             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08602             if (res < 0)
08603                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08604             else if (res > 0)
08605                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08606             else
08607                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08608             if (!iaxs[fr->callno]) {
08609                ast_mutex_unlock(&iaxsl[fr->callno]);
08610                return 1;
08611             }
08612             break;
08613          default:
08614             if (option_debug)
08615                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08616             memset(&ied0, 0, sizeof(ied0));
08617             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08618             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08619          }
08620          /* Don't actually pass these frames along */
08621          if ((f.subclass != IAX_COMMAND_ACK) && 
08622            (f.subclass != IAX_COMMAND_TXCNT) && 
08623            (f.subclass != IAX_COMMAND_TXACC) && 
08624            (f.subclass != IAX_COMMAND_INVAL) &&
08625            (f.subclass != IAX_COMMAND_VNAK)) { 
08626             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08627                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08628          }
08629          ast_mutex_unlock(&iaxsl[fr->callno]);
08630          return 1;
08631       }
08632       /* Unless this is an ACK or INVAL frame, ack it */
08633       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08634          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08635    } else if (minivid) {
08636       f.frametype = AST_FRAME_VIDEO;
08637       if (iaxs[fr->callno]->videoformat > 0) 
08638          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08639       else {
08640          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
08641          iax2_vnak(fr->callno);
08642          ast_mutex_unlock(&iaxsl[fr->callno]);
08643          return 1;
08644       }
08645       f.datalen = res - sizeof(*vh);
08646       if (f.datalen)
08647          f.data = thread->buf + sizeof(*vh);
08648       else
08649          f.data = NULL;
08650 #ifdef IAXTESTS
08651       if (test_resync) {
08652          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08653       } else
08654 #endif /* IAXTESTS */
08655          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08656    } else {
08657       /* A mini frame */
08658       f.frametype = AST_FRAME_VOICE;
08659       if (iaxs[fr->callno]->voiceformat > 0)
08660          f.subclass = iaxs[fr->callno]->voiceformat;
08661       else {
08662          if (option_debug)
08663             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08664          iax2_vnak(fr->callno);
08665          ast_mutex_unlock(&iaxsl[fr->callno]);
08666          return 1;
08667       }
08668       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08669       if (f.datalen < 0) {
08670          ast_log(LOG_WARNING, "Datalen < 0?\n");
08671          ast_mutex_unlock(&iaxsl[fr->callno]);
08672          return 1;
08673       }
08674       if (f.datalen)
08675          f.data = thread->buf + sizeof(*mh);
08676       else
08677          f.data = NULL;
08678 #ifdef IAXTESTS
08679       if (test_resync) {
08680          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08681       } else
08682 #endif /* IAXTESTS */
08683       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08684       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08685    }
08686    /* Don't pass any packets until we're started */
08687    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08688       ast_mutex_unlock(&iaxsl[fr->callno]);
08689       return 1;
08690    }
08691    /* Common things */
08692    f.src = "IAX2";
08693    f.mallocd = 0;
08694    f.offset = 0;
08695    f.len = 0;
08696    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08697       f.samples = ast_codec_get_samples(&f);
08698       /* We need to byteswap incoming slinear samples from network byte order */
08699       if (f.subclass == AST_FORMAT_SLINEAR)
08700          ast_frame_byteswap_be(&f);
08701    } else
08702       f.samples = 0;
08703    iax_frame_wrap(fr, &f);
08704 
08705    /* If this is our most recent packet, use it as our basis for timestamping */
08706    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08707       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08708       fr->outoforder = 0;
08709    } else {
08710       if (option_debug && iaxdebug && iaxs[fr->callno])
08711          ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
08712       fr->outoforder = -1;
08713    }
08714    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08715    duped_fr = iaxfrdup2(fr);
08716    if (duped_fr) {
08717       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08718    }
08719    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08720       iaxs[fr->callno]->last = fr->ts;
08721 #if 1
08722       if (option_debug && iaxdebug)
08723          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08724 #endif
08725    }
08726 
08727    /* Always run again */
08728    ast_mutex_unlock(&iaxsl[fr->callno]);
08729    return 1;
08730 }
08731 
08732 /* Function to clean up process thread if it is cancelled */
08733 static void iax2_process_thread_cleanup(void *data)
08734 {
08735    struct iax2_thread *thread = data;
08736    ast_mutex_destroy(&thread->lock);
08737    ast_cond_destroy(&thread->cond);
08738    free(thread);
08739    ast_atomic_dec_and_test(&iaxactivethreadcount);
08740 }
08741 
08742 static void *iax2_process_thread(void *data)
08743 {
08744    struct iax2_thread *thread = data;
08745    struct timeval tv;
08746    struct timespec ts;
08747    int put_into_idle = 0;
08748 
08749    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08750    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08751    for(;;) {
08752       /* Wait for something to signal us to be awake */
08753       ast_mutex_lock(&thread->lock);
08754 
08755       /* Flag that we're ready to accept signals */
08756       thread->ready_for_signal = 1;
08757       
08758       /* Put into idle list if applicable */
08759       if (put_into_idle)
08760          insert_idle_thread(thread);
08761 
08762       if (thread->type == IAX_TYPE_DYNAMIC) {
08763          struct iax2_thread *t = NULL;
08764          /* Wait to be signalled or time out */
08765          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08766          ts.tv_sec = tv.tv_sec;
08767          ts.tv_nsec = tv.tv_usec * 1000;
08768          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08769             /* This thread was never put back into the available dynamic
08770              * thread list, so just go away. */
08771             if (!put_into_idle) {
08772                ast_mutex_unlock(&thread->lock);
08773                break;
08774             }
08775             AST_LIST_LOCK(&dynamic_list);
08776             /* Account for the case where this thread is acquired *right* after a timeout */
08777             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08778                iaxdynamicthreadcount--;
08779             AST_LIST_UNLOCK(&dynamic_list);
08780             if (t) {
08781                /* This dynamic thread timed out waiting for a task and was
08782                 * not acquired immediately after the timeout, 
08783                 * so it's time to go away. */
08784                ast_mutex_unlock(&thread->lock);
08785                break;
08786             }
08787             /* Someone grabbed our thread *right* after we timed out.
08788              * Wait for them to set us up with something to do and signal
08789              * us to continue. */
08790             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08791             ts.tv_sec = tv.tv_sec;
08792             ts.tv_nsec = tv.tv_usec * 1000;
08793             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08794             {
08795                ast_mutex_unlock(&thread->lock);
08796                break;
08797             }
08798          }
08799       } else {
08800          ast_cond_wait(&thread->cond, &thread->lock);
08801       }
08802 
08803       /* Go back into our respective list */
08804       put_into_idle = 1;
08805 
08806       ast_mutex_unlock(&thread->lock);
08807 
08808       if (thread->iostate == IAX_IOSTATE_IDLE)
08809          continue;
08810 
08811       /* Add ourselves to the active list now */
08812       AST_LIST_LOCK(&active_list);
08813       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08814       AST_LIST_UNLOCK(&active_list);
08815 
08816       /* See what we need to do */
08817       switch(thread->iostate) {
08818       case IAX_IOSTATE_READY:
08819          thread->actions++;
08820          thread->iostate = IAX_IOSTATE_PROCESSING;
08821          socket_process(thread);
08822          handle_deferred_full_frames(thread);
08823          break;
08824       case IAX_IOSTATE_SCHEDREADY:
08825          thread->actions++;
08826          thread->iostate = IAX_IOSTATE_PROCESSING;
08827 #ifdef SCHED_MULTITHREADED
08828          thread->schedfunc(thread->scheddata);
08829 #endif      
08830          break;
08831       }
08832       time(&thread->checktime);
08833       thread->iostate = IAX_IOSTATE_IDLE;
08834 #ifdef DEBUG_SCHED_MULTITHREAD
08835       thread->curfunc[0]='\0';
08836 #endif      
08837 
08838       /* Now... remove ourselves from the active list, and return to the idle list */
08839       AST_LIST_LOCK(&active_list);
08840       AST_LIST_REMOVE(&active_list, thread, list);
08841       AST_LIST_UNLOCK(&active_list);
08842 
08843       /* Make sure another frame didn't sneak in there after we thought we were done. */
08844       handle_deferred_full_frames(thread);
08845    }
08846 
08847    /*!\note For some reason, idle threads are exiting without being removed
08848     * from an idle list, which is causing memory corruption.  Forcibly remove
08849     * it from the list, if it's there.
08850     */
08851    AST_LIST_LOCK(&idle_list);
08852    AST_LIST_REMOVE(&idle_list, thread, list);
08853    AST_LIST_UNLOCK(&idle_list);
08854 
08855    AST_LIST_LOCK(&dynamic_list);
08856    AST_LIST_REMOVE(&dynamic_list, thread, list);
08857    AST_LIST_UNLOCK(&dynamic_list);
08858 
08859    /* I am exiting here on my own volition, I need to clean up my own data structures
08860    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08861    */
08862    pthread_cleanup_pop(1);
08863 
08864    return NULL;
08865 }
08866 
08867 static int iax2_do_register(struct iax2_registry *reg)
08868 {
08869    struct iax_ie_data ied;
08870    if (option_debug && iaxdebug)
08871       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08872 
08873    if (reg->dnsmgr && 
08874        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08875       /* Maybe the IP has changed, force DNS refresh */
08876       ast_dnsmgr_refresh(reg->dnsmgr);
08877    }
08878    
08879    /*
08880     * if IP has Changed, free allocated call to create a new one with new IP
08881     * call has the pointer to IP and must be updated to the new one
08882     */
08883    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08884       int callno = reg->callno;
08885       ast_mutex_lock(&iaxsl[callno]);
08886       iax2_destroy(callno);
08887       ast_mutex_unlock(&iaxsl[callno]);
08888       reg->callno = 0;
08889    }
08890    if (!reg->addr.sin_addr.s_addr) {
08891       if (option_debug && iaxdebug)
08892          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08893       /* Setup the next registration attempt */
08894       AST_SCHED_DEL(sched, reg->expire);
08895       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08896       return -1;
08897    }
08898 
08899    if (!reg->callno) {
08900       if (option_debug)
08901          ast_log(LOG_DEBUG, "Allocate call number\n");
08902       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08903       if (reg->callno < 1) {
08904          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08905          return -1;
08906       } else if (option_debug)
08907          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08908       iaxs[reg->callno]->reg = reg;
08909       ast_mutex_unlock(&iaxsl[reg->callno]);
08910    }
08911    /* Schedule the next registration attempt */
08912    AST_SCHED_DEL(sched, reg->expire);
08913    /* Setup the next registration a little early */
08914    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08915    /* Send the request */
08916    memset(&ied, 0, sizeof(ied));
08917    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08918    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08919    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08920    reg->regstate = REG_STATE_REGSENT;
08921    return 0;
08922 }
08923 
08924 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08925 {
08926    if (pos != 3)
08927       return NULL;
08928    return iax_prov_complete_template(line, word, pos, state);
08929 }
08930 
08931 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08932 {
08933    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08934       is found for template */
08935    struct iax_ie_data provdata;
08936    struct iax_ie_data ied;
08937    unsigned int sig;
08938    struct sockaddr_in sin;
08939    int callno;
08940    struct create_addr_info cai;
08941 
08942    memset(&cai, 0, sizeof(cai));
08943 
08944    if (option_debug)
08945       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08946 
08947    if (iax_provision_build(&provdata, &sig, template, force)) {
08948       if (option_debug)
08949          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08950       return 0;
08951    }
08952 
08953    if (end) {
08954       memcpy(&sin, end, sizeof(sin));
08955       cai.sockfd = sockfd;
08956    } else if (create_addr(dest, NULL, &sin, &cai))
08957       return -1;
08958 
08959    /* Build the rest of the message */
08960    memset(&ied, 0, sizeof(ied));
08961    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08962 
08963    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08964    if (!callno)
08965       return -1;
08966 
08967    if (iaxs[callno]) {
08968       /* Schedule autodestruct in case they don't ever give us anything back */
08969       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08970       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08971       ast_set_flag(iaxs[callno], IAX_PROVISION);
08972       /* Got a call number now, so go ahead and send the provisioning information */
08973       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08974    }
08975    ast_mutex_unlock(&iaxsl[callno]);
08976 
08977    return 1;
08978 }
08979 
08980 static char *papp = "IAX2Provision";
08981 static char *psyn = "Provision a calling IAXy with a given template";
08982 static char *pdescrip = 
08983 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08984 "the calling entity is in fact an IAXy) with the given template or\n"
08985 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08986 
08987 /*! iax2provision
08988 \ingroup applications
08989 */
08990 static int iax2_prov_app(struct ast_channel *chan, void *data)
08991 {
08992    int res;
08993    char *sdata;
08994    char *opts;
08995    int force =0;
08996    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08997    if (ast_strlen_zero(data))
08998       data = "default";
08999    sdata = ast_strdupa(data);
09000    opts = strchr(sdata, '|');
09001    if (opts)
09002       *opts='\0';
09003 
09004    if (chan->tech != &iax2_tech) {
09005       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
09006       return -1;
09007    } 
09008    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
09009       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
09010       return -1;
09011    }
09012    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
09013    if (option_verbose > 2)
09014       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
09015       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
09016       sdata, res);
09017    return res;
09018 }
09019 
09020 
09021 static int iax2_prov_cmd(int fd, int argc, char *argv[])
09022 {
09023    int force = 0;
09024    int res;
09025    if (argc < 4)
09026       return RESULT_SHOWUSAGE;
09027    if ((argc > 4)) {
09028       if (!strcasecmp(argv[4], "forced"))
09029          force = 1;
09030       else
09031          return RESULT_SHOWUSAGE;
09032    }
09033    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
09034    if (res < 0)
09035       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
09036    else if (res < 1)
09037       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
09038    else
09039       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
09040    return RESULT_SUCCESS;
09041 }
09042 
09043 static void __iax2_poke_noanswer(const void *data)
09044 {
09045    struct iax2_peer *peer = (struct iax2_peer *)data;
09046    int callno;
09047 
09048    if (peer->lastms > -1) {
09049       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
09050       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
09051       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09052    }
09053    if ((callno = peer->callno) > 0) {
09054       ast_mutex_lock(&iaxsl[callno]);
09055       iax2_destroy(callno);
09056       ast_mutex_unlock(&iaxsl[callno]);
09057    }
09058    peer->callno = 0;
09059    peer->lastms = -1;
09060    /* Try again quickly */
09061    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09062    if (peer->pokeexpire == -1)
09063       peer_unref(peer);
09064 }
09065 
09066 static int iax2_poke_noanswer(const void *data)
09067 {
09068    struct iax2_peer *peer = (struct iax2_peer *)data;
09069    peer->pokeexpire = -1;
09070 #ifdef SCHED_MULTITHREADED
09071    if (schedule_action(__iax2_poke_noanswer, data))
09072 #endif      
09073       __iax2_poke_noanswer(data);
09074    peer_unref(peer);
09075    return 0;
09076 }
09077 
09078 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
09079 {
09080    struct iax2_peer *peer = obj;
09081 
09082    iax2_poke_peer(peer, 0);
09083 
09084    return 0;
09085 }
09086 
09087 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
09088 {
09089    int callno;
09090    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
09091       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
09092         immediately after clearing things out */
09093       peer->lastms = 0;
09094       peer->historicms = 0;
09095       peer->pokeexpire = -1;
09096       peer->callno = 0;
09097       return 0;
09098    }
09099 
09100    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
09101    if ((callno = peer->callno) > 0) {
09102       ast_log(LOG_NOTICE, "Still have a callno...\n");
09103       ast_mutex_lock(&iaxsl[callno]);
09104       iax2_destroy(callno);
09105       ast_mutex_unlock(&iaxsl[callno]);
09106    }
09107    if (heldcall)
09108       ast_mutex_unlock(&iaxsl[heldcall]);
09109    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
09110    if (heldcall)
09111       ast_mutex_lock(&iaxsl[heldcall]);
09112    if (peer->callno < 1) {
09113       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
09114       return -1;
09115    }
09116 
09117    /* Speed up retransmission times for this qualify call */
09118    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
09119    iaxs[peer->callno]->peerpoke = peer;
09120    
09121    /* Remove any pending pokeexpire task */
09122    if (peer->pokeexpire > -1) {
09123       if (!ast_sched_del(sched, peer->pokeexpire)) {
09124          peer->pokeexpire = -1;
09125          peer_unref(peer);
09126       }
09127    }
09128 
09129    /* Queue up a new task to handle no reply */
09130    /* If the host is already unreachable then use the unreachable interval instead */
09131    if (peer->lastms < 0) {
09132       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
09133    } else
09134       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
09135 
09136    if (peer->pokeexpire == -1)
09137       peer_unref(peer);
09138 
09139    /* And send the poke */
09140    ast_mutex_lock(&iaxsl[callno]);
09141    if (iaxs[callno]) {
09142       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
09143    }
09144    ast_mutex_unlock(&iaxsl[callno]);
09145 
09146    return 0;
09147 }
09148 
09149 static void free_context(struct iax2_context *con)
09150 {
09151    struct iax2_context *conl;
09152    while(con) {
09153       conl = con;
09154       con = con->next;
09155       free(conl);
09156    }
09157 }
09158 
09159 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09160 {
09161    int callno;
09162    int res;
09163    int fmt, native;
09164    struct sockaddr_in sin;
09165    struct ast_channel *c;
09166    struct parsed_dial_string pds;
09167    struct create_addr_info cai;
09168    char *tmpstr;
09169 
09170    memset(&pds, 0, sizeof(pds));
09171    tmpstr = ast_strdupa(data);
09172    parse_dial_string(tmpstr, &pds);
09173 
09174    if (ast_strlen_zero(pds.peer)) {
09175       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09176       return NULL;
09177    }
09178           
09179    memset(&cai, 0, sizeof(cai));
09180    cai.capability = iax2_capability;
09181 
09182    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09183    
09184    /* Populate our address from the given */
09185    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09186       *cause = AST_CAUSE_UNREGISTERED;
09187       return NULL;
09188    }
09189 
09190    if (pds.port)
09191       sin.sin_port = htons(atoi(pds.port));
09192 
09193    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09194    if (callno < 1) {
09195       ast_log(LOG_WARNING, "Unable to create call\n");
09196       *cause = AST_CAUSE_CONGESTION;
09197       return NULL;
09198    }
09199 
09200    /* If this is a trunk, update it now */
09201    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09202    if (ast_test_flag(&cai, IAX_TRUNK)) {
09203       int new_callno;
09204       if ((new_callno = make_trunk(callno, 1)) != -1)
09205          callno = new_callno;
09206    }
09207    iaxs[callno]->maxtime = cai.maxtime;
09208    if (cai.found)
09209       ast_string_field_set(iaxs[callno], host, pds.peer);
09210 
09211    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09212 
09213    ast_mutex_unlock(&iaxsl[callno]);
09214 
09215    if (c) {
09216       /* Choose a format we can live with */
09217       if (c->nativeformats & format) 
09218          c->nativeformats &= format;
09219       else {
09220          native = c->nativeformats;
09221          fmt = format;
09222          res = ast_translator_best_choice(&fmt, &native);
09223          if (res < 0) {
09224             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09225                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09226             ast_hangup(c);
09227             return NULL;
09228          }
09229          c->nativeformats = native;
09230       }
09231       c->readformat = ast_best_codec(c->nativeformats);
09232       c->writeformat = c->readformat;
09233    }
09234 
09235    return c;
09236 }
09237 
09238 static void *sched_thread(void *ignore)
09239 {
09240    for (;;) {
09241       int ms, count;
09242       struct timespec ts;
09243 
09244       pthread_testcancel();
09245 
09246       ast_mutex_lock(&sched_lock);
09247 
09248       ms = ast_sched_wait(sched);
09249 
09250       if (ms == -1) {
09251          ast_cond_wait(&sched_cond, &sched_lock);
09252       } else {
09253          struct timeval tv;
09254          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
09255          ts.tv_sec = tv.tv_sec;
09256          ts.tv_nsec = tv.tv_usec * 1000;
09257          ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09258       }
09259 
09260       ast_mutex_unlock(&sched_lock);
09261 
09262       pthread_testcancel();
09263 
09264       count = ast_sched_runq(sched);
09265       if (option_debug && count >= 20) {
09266          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09267       }
09268    }
09269 
09270    return NULL;
09271 }
09272 
09273 static void *network_thread(void *ignore)
09274 {
09275    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09276       from the network, and queue them for delivery to the channels */
09277    int res, count, wakeup;
09278    struct iax_frame *f;
09279 
09280    if (timingfd > -1)
09281       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09282    
09283    for(;;) {
09284       pthread_testcancel();
09285 
09286       /* Go through the queue, sending messages which have not yet been
09287          sent, and scheduling retransmissions if appropriate */
09288       AST_LIST_LOCK(&iaxq.queue);
09289       count = 0;
09290       wakeup = -1;
09291       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09292          if (f->sentyet)
09293             continue;
09294          
09295          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09296          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09297             wakeup = 1;
09298             continue;
09299          }
09300 
09301          f->sentyet++;
09302 
09303          if (iaxs[f->callno]) {
09304             send_packet(f);
09305             count++;
09306          } 
09307 
09308          ast_mutex_unlock(&iaxsl[f->callno]);
09309 
09310          if (f->retries < 0) {
09311             /* This is not supposed to be retransmitted */
09312             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09313             iaxq.count--;
09314             /* Free the iax frame */
09315             iax_frame_free(f);
09316          } else {
09317             /* We need reliable delivery.  Schedule a retransmission */
09318             f->retries++;
09319             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09320          }
09321       }
09322       AST_LIST_TRAVERSE_SAFE_END
09323       AST_LIST_UNLOCK(&iaxq.queue);
09324 
09325       pthread_testcancel();
09326 
09327       if (option_debug && count >= 20)
09328          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09329 
09330       /* Now do the IO, and run scheduled tasks */
09331       res = ast_io_wait(io, wakeup);
09332       if (res >= 0) {
09333          if (option_debug && res >= 20)
09334             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09335       }
09336    }
09337    return NULL;
09338 }
09339 
09340 static int start_network_thread(void)
09341 {
09342    pthread_attr_t attr;
09343    int threadcount = 0;
09344    int x;
09345    for (x = 0; x < iaxthreadcount; x++) {
09346       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09347       if (thread) {
09348          thread->type = IAX_TYPE_POOL;
09349          thread->threadnum = ++threadcount;
09350          ast_mutex_init(&thread->lock);
09351          ast_cond_init(&thread->cond, NULL);
09352          pthread_attr_init(&attr);
09353          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09354          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09355             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09356             free(thread);
09357             thread = NULL;
09358          }
09359          AST_LIST_LOCK(&idle_list);
09360          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09361          AST_LIST_UNLOCK(&idle_list);
09362       }
09363    }
09364    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09365    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09366    if (option_verbose > 1)
09367       ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
09368    return 0;
09369 }
09370 
09371 static struct iax2_context *build_context(char *context)
09372 {
09373    struct iax2_context *con;
09374 
09375    if ((con = ast_calloc(1, sizeof(*con))))
09376       ast_copy_string(con->context, context, sizeof(con->context));
09377    
09378    return con;
09379 }
09380 
09381 static int get_auth_methods(char *value)
09382 {
09383    int methods = 0;
09384    if (strstr(value, "rsa"))
09385       methods |= IAX_AUTH_RSA;
09386    if (strstr(value, "md5"))
09387       methods |= IAX_AUTH_MD5;
09388    if (strstr(value, "plaintext"))
09389       methods |= IAX_AUTH_PLAINTEXT;
09390    return methods;
09391 }
09392 
09393 
09394 /*! \brief Check if address can be used as packet source.
09395  \return 0  address available, 1  address unavailable, -1  error
09396 */
09397 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09398 {
09399    int sd;
09400    int res;
09401    
09402    sd = socket(AF_INET, SOCK_DGRAM, 0);
09403    if (sd < 0) {
09404       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09405       return -1;
09406    }
09407 
09408    res = bind(sd, sa, salen);
09409    if (res < 0) {
09410       if (option_debug)
09411          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09412       close(sd);
09413       return 1;
09414    }
09415 
09416    close(sd);
09417    return 0;
09418 }
09419 
09420 /*! \brief Parse the "sourceaddress" value,
09421   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09422   not found. */
09423 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09424 {
09425    struct sockaddr_in sin;
09426    int nonlocal = 1;
09427    int port = IAX_DEFAULT_PORTNO;
09428    int sockfd = defaultsockfd;
09429    char *tmp;
09430    char *addr;
09431    char *portstr;
09432 
09433    if (!(tmp = ast_strdupa(srcaddr)))
09434       return -1;
09435 
09436    addr = strsep(&tmp, ":");
09437    portstr = tmp;
09438 
09439    if (portstr) {
09440       port = atoi(portstr);
09441       if (port < 1)
09442          port = IAX_DEFAULT_PORTNO;
09443    }
09444    
09445    if (!ast_get_ip(&sin, addr)) {
09446       struct ast_netsock *sock;
09447       int res;
09448 
09449       sin.sin_port = 0;
09450       sin.sin_family = AF_INET;
09451       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09452       if (res == 0) {
09453          /* ip address valid. */
09454          sin.sin_port = htons(port);
09455          if (!(sock = ast_netsock_find(netsock, &sin)))
09456             sock = ast_netsock_find(outsock, &sin);
09457          if (sock) {
09458             sockfd = ast_netsock_sockfd(sock);
09459             nonlocal = 0;
09460          } else {
09461             unsigned int orig_saddr = sin.sin_addr.s_addr;
09462             /* INADDR_ANY matches anyway! */
09463             sin.sin_addr.s_addr = INADDR_ANY;
09464             if (ast_netsock_find(netsock, &sin)) {
09465                sin.sin_addr.s_addr = orig_saddr;
09466                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09467                if (sock) {
09468                   sockfd = ast_netsock_sockfd(sock);
09469                   ast_netsock_unref(sock);
09470                   nonlocal = 0;
09471                } else {
09472                   nonlocal = 2;
09473                }
09474             }
09475          }
09476       }
09477    }
09478       
09479    peer->sockfd = sockfd;
09480 
09481    if (nonlocal == 1) {
09482       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09483          srcaddr, peer->name);
09484       return -1;
09485         } else if (nonlocal == 2) {
09486       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09487          srcaddr, peer->name);
09488          return -1;
09489    } else {
09490       if (option_debug)
09491          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09492       return 0;
09493    }
09494 }
09495 
09496 static void peer_destructor(void *obj)
09497 {
09498    struct iax2_peer *peer = obj;
09499    int callno = peer->callno;
09500 
09501    ast_free_ha(peer->ha);
09502 
09503    if (callno > 0) {
09504       ast_mutex_lock(&iaxsl[callno]);
09505       iax2_destroy(callno);
09506       ast_mutex_unlock(&iaxsl[callno]);
09507    }
09508 
09509    register_peer_exten(peer, 0);
09510 
09511    if (peer->dnsmgr)
09512       ast_dnsmgr_release(peer->dnsmgr);
09513 
09514    ast_string_field_free_memory(peer);
09515 }
09516 
09517 /*! \brief Create peer structure based on configuration */
09518 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09519 {
09520    struct iax2_peer *peer = NULL;
09521    struct ast_ha *oldha = NULL;
09522    int maskfound=0;
09523    int found=0;
09524    int firstpass=1;
09525    struct iax2_peer tmp_peer = {
09526       .name = name,
09527    };
09528 
09529    if (!temponly) {
09530       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09531       if (peer && !ast_test_flag(peer, IAX_DELME))
09532          firstpass = 0;
09533    }
09534 
09535    if (peer) {
09536       found++;
09537       if (firstpass) {
09538          oldha = peer->ha;
09539          peer->ha = NULL;
09540       }
09541       unlink_peer(peer);
09542    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09543       peer->expire = -1;
09544       peer->pokeexpire = -1;
09545       peer->sockfd = defaultsockfd;
09546       if (ast_string_field_init(peer, 32))
09547          peer = peer_unref(peer);
09548    }
09549 
09550    if (peer) {
09551       if (firstpass) {
09552          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09553          peer->encmethods = iax2_encryption;
09554          peer->adsi = adsi;
09555          ast_string_field_set(peer,secret,"");
09556          if (!found) {
09557             ast_string_field_set(peer, name, name);
09558             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09559             peer->expiry = min_reg_expire;
09560          }
09561          peer->prefs = prefs;
09562          peer->capability = iax2_capability;
09563          peer->smoothing = 0;
09564          peer->pokefreqok = DEFAULT_FREQ_OK;
09565          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09566          ast_string_field_set(peer,context,"");
09567          ast_string_field_set(peer,peercontext,"");
09568          ast_clear_flag(peer, IAX_HASCALLERID);
09569          ast_string_field_set(peer, cid_name, "");
09570          ast_string_field_set(peer, cid_num, "");
09571       }
09572 
09573       if (!v) {
09574          v = alt;
09575          alt = NULL;
09576       }
09577       while(v) {
09578          if (!strcasecmp(v->name, "secret")) {
09579             ast_string_field_set(peer, secret, v->value);
09580          } else if (!strcasecmp(v->name, "mailbox")) {
09581             ast_string_field_set(peer, mailbox, v->value);
09582          } else if (!strcasecmp(v->name, "hasvoicemail")) {
09583             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
09584                ast_string_field_set(peer, mailbox, name);
09585             }
09586          } else if (!strcasecmp(v->name, "mohinterpret")) {
09587             ast_string_field_set(peer, mohinterpret, v->value);
09588          } else if (!strcasecmp(v->name, "mohsuggest")) {
09589             ast_string_field_set(peer, mohsuggest, v->value);
09590          } else if (!strcasecmp(v->name, "dbsecret")) {
09591             ast_string_field_set(peer, dbsecret, v->value);
09592          } else if (!strcasecmp(v->name, "trunk")) {
09593             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09594             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09595                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
09596                ast_clear_flag(peer, IAX_TRUNK);
09597             }
09598          } else if (!strcasecmp(v->name, "auth")) {
09599             peer->authmethods = get_auth_methods(v->value);
09600          } else if (!strcasecmp(v->name, "encryption")) {
09601             peer->encmethods = get_encrypt_methods(v->value);
09602          } else if (!strcasecmp(v->name, "notransfer")) {
09603             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09604             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09605             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09606          } else if (!strcasecmp(v->name, "transfer")) {
09607             if (!strcasecmp(v->value, "mediaonly")) {
09608                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09609             } else if (ast_true(v->value)) {
09610                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09611             } else 
09612                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09613          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09614             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09615          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09616             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09617          } else if (!strcasecmp(v->name, "host")) {
09618             if (!strcasecmp(v->value, "dynamic")) {
09619                /* They'll register with us */
09620                ast_set_flag(peer, IAX_DYNAMIC); 
09621                if (!found) {
09622                   /* Initialize stuff iff we're not found, otherwise
09623                      we keep going with what we had */
09624                   memset(&peer->addr.sin_addr, 0, 4);
09625                   if (peer->addr.sin_port) {
09626                      /* If we've already got a port, make it the default rather than absolute */
09627                      peer->defaddr.sin_port = peer->addr.sin_port;
09628                      peer->addr.sin_port = 0;
09629                   }
09630                }
09631             } else {
09632                /* Non-dynamic.  Make sure we become that way if we're not */
09633                AST_SCHED_DEL(sched, peer->expire);
09634                ast_clear_flag(peer, IAX_DYNAMIC);
09635                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09636                   return peer_unref(peer);
09637                if (!peer->addr.sin_port)
09638                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09639             }
09640             if (!maskfound)
09641                inet_aton("255.255.255.255", &peer->mask);
09642          } else if (!strcasecmp(v->name, "defaultip")) {
09643             if (ast_get_ip(&peer->defaddr, v->value))
09644                return peer_unref(peer);
09645          } else if (!strcasecmp(v->name, "sourceaddress")) {
09646             peer_set_srcaddr(peer, v->value);
09647          } else if (!strcasecmp(v->name, "permit") ||
09648                   !strcasecmp(v->name, "deny")) {
09649             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09650          } else if (!strcasecmp(v->name, "mask")) {
09651             maskfound++;
09652             inet_aton(v->value, &peer->mask);
09653          } else if (!strcasecmp(v->name, "context")) {
09654             ast_string_field_set(peer, context, v->value);
09655          } else if (!strcasecmp(v->name, "regexten")) {
09656             ast_string_field_set(peer, regexten, v->value);
09657          } else if (!strcasecmp(v->name, "peercontext")) {
09658             ast_string_field_set(peer, peercontext, v->value);
09659          } else if (!strcasecmp(v->name, "port")) {
09660             if (ast_test_flag(peer, IAX_DYNAMIC))
09661                peer->defaddr.sin_port = htons(atoi(v->value));
09662             else
09663                peer->addr.sin_port = htons(atoi(v->value));
09664          } else if (!strcasecmp(v->name, "username")) {
09665             ast_string_field_set(peer, username, v->value);
09666          } else if (!strcasecmp(v->name, "allow")) {
09667             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09668          } else if (!strcasecmp(v->name, "disallow")) {
09669             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09670          } else if (!strcasecmp(v->name, "callerid")) {
09671             if (!ast_strlen_zero(v->value)) {
09672                char name2[80];
09673                char num2[80];
09674                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09675                ast_string_field_set(peer, cid_name, name2);
09676                ast_string_field_set(peer, cid_num, num2);
09677             } else {
09678                ast_string_field_set(peer, cid_name, "");
09679                ast_string_field_set(peer, cid_num, "");
09680             }
09681             ast_set_flag(peer, IAX_HASCALLERID);
09682          } else if (!strcasecmp(v->name, "fullname")) {
09683             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
09684             ast_set_flag(peer, IAX_HASCALLERID);
09685          } else if (!strcasecmp(v->name, "cid_number")) {
09686             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
09687             ast_set_flag(peer, IAX_HASCALLERID);
09688          } else if (!strcasecmp(v->name, "sendani")) {
09689             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09690          } else if (!strcasecmp(v->name, "inkeys")) {
09691             ast_string_field_set(peer, inkeys, v->value);
09692          } else if (!strcasecmp(v->name, "outkey")) {
09693             ast_string_field_set(peer, outkey, v->value);
09694          } else if (!strcasecmp(v->name, "qualify")) {
09695             if (!strcasecmp(v->value, "no")) {
09696                peer->maxms = 0;
09697             } else if (!strcasecmp(v->value, "yes")) {
09698                peer->maxms = DEFAULT_MAXMS;
09699             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09700                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);
09701                peer->maxms = 0;
09702             }
09703          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09704             peer->smoothing = ast_true(v->value);
09705          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09706             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09707                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);
09708             }
09709          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09710             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09711                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);
09712             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09713          } else if (!strcasecmp(v->name, "timezone")) {
09714             ast_string_field_set(peer, zonetag, v->value);
09715          } else if (!strcasecmp(v->name, "adsi")) {
09716             peer->adsi = ast_true(v->value);
09717          }/* else if (strcasecmp(v->name,"type")) */
09718          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09719          v = v->next;
09720          if (!v) {
09721             v = alt;
09722             alt = NULL;
09723          }
09724       }
09725       if (!peer->authmethods)
09726          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09727       ast_clear_flag(peer, IAX_DELME); 
09728       /* Make sure these are IPv4 addresses */
09729       peer->addr.sin_family = AF_INET;
09730    }
09731    if (oldha)
09732       ast_free_ha(oldha);
09733    return peer;
09734 }
09735 
09736 static void user_destructor(void *obj)
09737 {
09738    struct iax2_user *user = obj;
09739 
09740    ast_free_ha(user->ha);
09741    free_context(user->contexts);
09742    if(user->vars) {
09743       ast_variables_destroy(user->vars);
09744       user->vars = NULL;
09745    }
09746    ast_string_field_free_memory(user);
09747 }
09748 
09749 /*! \brief Create in-memory user structure from configuration */
09750 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09751 {
09752    struct iax2_user *user = NULL;
09753    struct iax2_context *con, *conl = NULL;
09754    struct ast_ha *oldha = NULL;
09755    struct iax2_context *oldcon = NULL;
09756    int format;
09757    int firstpass=1;
09758    int oldcurauthreq = 0;
09759    char *varname = NULL, *varval = NULL;
09760    struct ast_variable *tmpvar = NULL;
09761    struct iax2_user tmp_user = {
09762       .name = name,
09763    };
09764 
09765    if (!temponly) {
09766       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09767       if (user && !ast_test_flag(user, IAX_DELME))
09768          firstpass = 0;
09769    }
09770 
09771    if (user) {
09772       if (firstpass) {
09773          oldcurauthreq = user->curauthreq;
09774          oldha = user->ha;
09775          oldcon = user->contexts;
09776          user->ha = NULL;
09777          user->contexts = NULL;
09778       }
09779       /* Already in the list, remove it and it will be added back (or FREE'd) */
09780       ao2_unlink(users, user);
09781    } else {
09782       user = ao2_alloc(sizeof(*user), user_destructor);
09783    }
09784    
09785    if (user) {
09786       if (firstpass) {
09787          ast_string_field_free_memory(user);
09788          memset(user, 0, sizeof(struct iax2_user));
09789          if (ast_string_field_init(user, 32)) {
09790             user = user_unref(user);
09791             goto cleanup;
09792          }
09793          user->maxauthreq = maxauthreq;
09794          user->curauthreq = oldcurauthreq;
09795          user->prefs = prefs;
09796          user->capability = iax2_capability;
09797          user->encmethods = iax2_encryption;
09798          user->adsi = adsi;
09799          ast_string_field_set(user, name, name);
09800          ast_string_field_set(user, language, language);
09801          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09802          ast_clear_flag(user, IAX_HASCALLERID);
09803          ast_string_field_set(user, cid_name, "");
09804          ast_string_field_set(user, cid_num, "");
09805       }
09806       if (!v) {
09807          v = alt;
09808          alt = NULL;
09809       }
09810       while(v) {
09811          if (!strcasecmp(v->name, "context")) {
09812             con = build_context(v->value);
09813             if (con) {
09814                if (conl)
09815                   conl->next = con;
09816                else
09817                   user->contexts = con;
09818                conl = con;
09819             }
09820          } else if (!strcasecmp(v->name, "permit") ||
09821                   !strcasecmp(v->name, "deny")) {
09822             user->ha = ast_append_ha(v->name, v->value, user->ha);
09823          } else if (!strcasecmp(v->name, "setvar")) {
09824             varname = ast_strdupa(v->value);
09825             if (varname && (varval = strchr(varname,'='))) {
09826                *varval = '\0';
09827                varval++;
09828                if((tmpvar = ast_variable_new(varname, varval))) {
09829                   tmpvar->next = user->vars; 
09830                   user->vars = tmpvar;
09831                }
09832             }
09833          } else if (!strcasecmp(v->name, "allow")) {
09834             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09835          } else if (!strcasecmp(v->name, "disallow")) {
09836             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09837          } else if (!strcasecmp(v->name, "trunk")) {
09838             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09839             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09840                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
09841                ast_clear_flag(user, IAX_TRUNK);
09842             }
09843          } else if (!strcasecmp(v->name, "auth")) {
09844             user->authmethods = get_auth_methods(v->value);
09845          } else if (!strcasecmp(v->name, "encryption")) {
09846             user->encmethods = get_encrypt_methods(v->value);
09847          } else if (!strcasecmp(v->name, "notransfer")) {
09848             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09849             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09850             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09851          } else if (!strcasecmp(v->name, "transfer")) {
09852             if (!strcasecmp(v->value, "mediaonly")) {
09853                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09854             } else if (ast_true(v->value)) {
09855                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09856             } else 
09857                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09858          } else if (!strcasecmp(v->name, "codecpriority")) {
09859             if(!strcasecmp(v->value, "caller"))
09860                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09861             else if(!strcasecmp(v->value, "disabled"))
09862                ast_set_flag(user, IAX_CODEC_NOPREFS);
09863             else if(!strcasecmp(v->value, "reqonly")) {
09864                ast_set_flag(user, IAX_CODEC_NOCAP);
09865                ast_set_flag(user, IAX_CODEC_NOPREFS);
09866             }
09867          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09868             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09869          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09870             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09871          } else if (!strcasecmp(v->name, "dbsecret")) {
09872             ast_string_field_set(user, dbsecret, v->value);
09873          } else if (!strcasecmp(v->name, "secret")) {
09874             if (!ast_strlen_zero(user->secret)) {
09875                char *old = ast_strdupa(user->secret);
09876 
09877                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09878             } else
09879                ast_string_field_set(user, secret, v->value);
09880          } else if (!strcasecmp(v->name, "callerid")) {
09881             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09882                char name2[80];
09883                char num2[80];
09884                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09885                ast_string_field_set(user, cid_name, name2);
09886                ast_string_field_set(user, cid_num, num2);
09887                ast_set_flag(user, IAX_HASCALLERID);
09888             } else {
09889                ast_clear_flag(user, IAX_HASCALLERID);
09890                ast_string_field_set(user, cid_name, "");
09891                ast_string_field_set(user, cid_num, "");
09892             }
09893          } else if (!strcasecmp(v->name, "fullname")) {
09894             if (!ast_strlen_zero(v->value)) {
09895                ast_string_field_set(user, cid_name, v->value);
09896                ast_set_flag(user, IAX_HASCALLERID);
09897             } else {
09898                ast_string_field_set(user, cid_name, "");
09899                if (ast_strlen_zero(user->cid_num))
09900                   ast_clear_flag(user, IAX_HASCALLERID);
09901             }
09902          } else if (!strcasecmp(v->name, "cid_number")) {
09903             if (!ast_strlen_zero(v->value)) {
09904                ast_string_field_set(user, cid_num, v->value);
09905                ast_set_flag(user, IAX_HASCALLERID);
09906             } else {
09907                ast_string_field_set(user, cid_num, "");
09908                if (ast_strlen_zero(user->cid_name))
09909                   ast_clear_flag(user, IAX_HASCALLERID);
09910             }
09911          } else if (!strcasecmp(v->name, "accountcode")) {
09912             ast_string_field_set(user, accountcode, v->value);
09913          } else if (!strcasecmp(v->name, "mohinterpret")) {
09914             ast_string_field_set(user, mohinterpret, v->value);
09915          } else if (!strcasecmp(v->name, "mohsuggest")) {
09916             ast_string_field_set(user, mohsuggest, v->value);
09917          } else if (!strcasecmp(v->name, "language")) {
09918             ast_string_field_set(user, language, v->value);
09919          } else if (!strcasecmp(v->name, "amaflags")) {
09920             format = ast_cdr_amaflags2int(v->value);
09921             if (format < 0) {
09922                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09923             } else {
09924                user->amaflags = format;
09925             }
09926          } else if (!strcasecmp(v->name, "inkeys")) {
09927             ast_string_field_set(user, inkeys, v->value);
09928          } else if (!strcasecmp(v->name, "maxauthreq")) {
09929             user->maxauthreq = atoi(v->value);
09930             if (user->maxauthreq < 0)
09931                user->maxauthreq = 0;
09932          } else if (!strcasecmp(v->name, "adsi")) {
09933             user->adsi = ast_true(v->value);
09934          }/* else if (strcasecmp(v->name,"type")) */
09935          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09936          v = v->next;
09937          if (!v) {
09938             v = alt;
09939             alt = NULL;
09940          }
09941       }
09942       if (!user->authmethods) {
09943          if (!ast_strlen_zero(user->secret)) {
09944             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09945             if (!ast_strlen_zero(user->inkeys))
09946                user->authmethods |= IAX_AUTH_RSA;
09947          } else if (!ast_strlen_zero(user->inkeys)) {
09948             user->authmethods = IAX_AUTH_RSA;
09949          } else {
09950             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09951          }
09952       }
09953       ast_clear_flag(user, IAX_DELME);
09954    }
09955 cleanup:
09956    if (oldha)
09957       ast_free_ha(oldha);
09958    if (oldcon)
09959       free_context(oldcon);
09960    return user;
09961 }
09962 
09963 static int peer_delme_cb(void *obj, void *arg, int flags)
09964 {
09965    struct iax2_peer *peer = obj;
09966 
09967    ast_set_flag(peer, IAX_DELME);
09968 
09969    return 0;
09970 }
09971 
09972 static int user_delme_cb(void *obj, void *arg, int flags)
09973 {
09974    struct iax2_user *user = obj;
09975 
09976    ast_set_flag(user, IAX_DELME);
09977 
09978    return 0;
09979 }
09980 
09981 static void delete_users(void)
09982 {
09983    struct iax2_registry *reg;
09984 
09985    ao2_callback(users, 0, user_delme_cb, NULL);
09986 
09987    AST_LIST_LOCK(&registrations);
09988    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09989       ast_sched_del(sched, reg->expire);
09990       if (reg->callno) {
09991          int callno = reg->callno;
09992          ast_mutex_lock(&iaxsl[callno]);
09993          if (iaxs[callno]) {
09994             iaxs[callno]->reg = NULL;
09995             iax2_destroy(callno);
09996          }
09997          ast_mutex_unlock(&iaxsl[callno]);
09998       }
09999       if (reg->dnsmgr)
10000          ast_dnsmgr_release(reg->dnsmgr);
10001       free(reg);
10002    }
10003    AST_LIST_UNLOCK(&registrations);
10004 
10005    ao2_callback(peers, 0, peer_delme_cb, NULL);
10006 }
10007 
10008 static void prune_users(void)
10009 {
10010    struct iax2_user *user;
10011    struct ao2_iterator i;
10012 
10013    i = ao2_iterator_init(users, 0);
10014    while ((user = ao2_iterator_next(&i))) {
10015       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
10016          ao2_unlink(users, user);
10017       }
10018       user_unref(user);
10019    }
10020 }
10021 
10022 /* Prune peers who still are supposed to be deleted */
10023 static void prune_peers(void)
10024 {
10025    struct iax2_peer *peer;
10026    struct ao2_iterator i;
10027 
10028    i = ao2_iterator_init(peers, 0);
10029    while ((peer = ao2_iterator_next(&i))) {
10030       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
10031          unlink_peer(peer);
10032       }
10033       peer_unref(peer);
10034    }
10035 }
10036 
10037 static void set_timing(void)
10038 {
10039 #ifdef HAVE_DAHDI
10040    int bs = trunkfreq * 8;
10041    if (timingfd > -1) {
10042       if (
10043 #ifdef DAHDI_TIMERACK
10044          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
10045 #endif         
10046          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
10047          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
10048    }
10049 #endif
10050 }
10051 
10052 static void set_config_destroy(void)
10053 {
10054    strcpy(accountcode, "");
10055    strcpy(language, "");
10056    strcpy(mohinterpret, "default");
10057    strcpy(mohsuggest, "");
10058    amaflags = 0;
10059    delayreject = 0;
10060    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
10061    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10062    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
10063    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
10064    delete_users();
10065 }
10066 
10067 /*! \brief Load configuration */
10068 static int set_config(char *config_file, int reload)
10069 {
10070    struct ast_config *cfg, *ucfg;
10071    int capability=iax2_capability;
10072    struct ast_variable *v;
10073    char *cat;
10074    const char *utype;
10075    const char *tosval;
10076    int format;
10077    int portno = IAX_DEFAULT_PORTNO;
10078    int  x;
10079    struct iax2_user *user;
10080    struct iax2_peer *peer;
10081    struct ast_netsock *ns;
10082 #if 0
10083    static unsigned short int last_port=0;
10084 #endif
10085 
10086    cfg = ast_config_load(config_file);
10087    
10088    if (!cfg) {
10089       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
10090       return -1;
10091    }
10092 
10093    if (reload) {
10094       set_config_destroy();
10095    }
10096 
10097    /* Reset global codec prefs */   
10098    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
10099    
10100    /* Reset Global Flags */
10101    memset(&globalflags, 0, sizeof(globalflags));
10102    ast_set_flag(&globalflags, IAX_RTUPDATE);
10103 
10104 #ifdef SO_NO_CHECK
10105    nochecksums = 0;
10106 #endif
10107 
10108    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10109    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10110 
10111    maxauthreq = 3;
10112 
10113    v = ast_variable_browse(cfg, "general");
10114 
10115    /* Seed initial tos value */
10116    tosval = ast_variable_retrieve(cfg, "general", "tos");
10117    if (tosval) {
10118       if (ast_str2tos(tosval, &tos))
10119          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
10120    }
10121    while(v) {
10122       if (!strcasecmp(v->name, "bindport")){ 
10123          if (reload)
10124             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
10125          else
10126             portno = atoi(v->value);
10127       } else if (!strcasecmp(v->name, "pingtime")) 
10128          ping_time = atoi(v->value);
10129       else if (!strcasecmp(v->name, "iaxthreadcount")) {
10130          if (reload) {
10131             if (atoi(v->value) != iaxthreadcount)
10132                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
10133          } else {
10134             iaxthreadcount = atoi(v->value);
10135             if (iaxthreadcount < 1) {
10136                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
10137                iaxthreadcount = 1;
10138             } else if (iaxthreadcount > 256) {
10139                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
10140                iaxthreadcount = 256;
10141             }
10142          }
10143       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
10144          if (reload) {
10145             AST_LIST_LOCK(&dynamic_list);
10146             iaxmaxthreadcount = atoi(v->value);
10147             AST_LIST_UNLOCK(&dynamic_list);
10148          } else {
10149             iaxmaxthreadcount = atoi(v->value);
10150             if (iaxmaxthreadcount < 0) {
10151                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
10152                iaxmaxthreadcount = 0;
10153             } else if (iaxmaxthreadcount > 256) {
10154                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
10155                iaxmaxthreadcount = 256;
10156             }
10157          }
10158       } else if (!strcasecmp(v->name, "nochecksums")) {
10159 #ifdef SO_NO_CHECK
10160          if (ast_true(v->value))
10161             nochecksums = 1;
10162          else
10163             nochecksums = 0;
10164 #else
10165          if (ast_true(v->value))
10166             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10167 #endif
10168       }
10169       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
10170          maxjitterbuffer = atoi(v->value);
10171       else if (!strcasecmp(v->name, "resyncthreshold")) 
10172          resyncthreshold = atoi(v->value);
10173       else if (!strcasecmp(v->name, "maxjitterinterps")) 
10174          maxjitterinterps = atoi(v->value);
10175       else if (!strcasecmp(v->name, "lagrqtime")) 
10176          lagrq_time = atoi(v->value);
10177       else if (!strcasecmp(v->name, "maxregexpire")) 
10178          max_reg_expire = atoi(v->value);
10179       else if (!strcasecmp(v->name, "minregexpire")) 
10180          min_reg_expire = atoi(v->value);
10181       else if (!strcasecmp(v->name, "bindaddr")) {
10182          if (reload) {
10183             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10184          } else {
10185             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10186                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10187             } else {
10188                if (option_verbose > 1) {
10189                   if (strchr(v->value, ':'))
10190                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10191                   else
10192                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10193                }
10194                if (defaultsockfd < 0) 
10195                   defaultsockfd = ast_netsock_sockfd(ns);
10196                ast_netsock_unref(ns);
10197             }
10198          }
10199       } else if (!strcasecmp(v->name, "authdebug"))
10200          authdebug = ast_true(v->value);
10201       else if (!strcasecmp(v->name, "encryption"))
10202          iax2_encryption = get_encrypt_methods(v->value);
10203       else if (!strcasecmp(v->name, "notransfer")) {
10204          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10205          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10206          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10207       } else if (!strcasecmp(v->name, "transfer")) {
10208          if (!strcasecmp(v->value, "mediaonly")) {
10209             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10210          } else if (ast_true(v->value)) {
10211             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10212          } else 
10213             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10214       } else if (!strcasecmp(v->name, "codecpriority")) {
10215          if(!strcasecmp(v->value, "caller"))
10216             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10217          else if(!strcasecmp(v->value, "disabled"))
10218             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10219          else if(!strcasecmp(v->value, "reqonly")) {
10220             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10221             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10222          }
10223       } else if (!strcasecmp(v->name, "jitterbuffer"))
10224          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10225       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10226          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10227       else if (!strcasecmp(v->name, "delayreject"))
10228          delayreject = ast_true(v->value);
10229       else if (!strcasecmp(v->name, "allowfwdownload"))
10230          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10231       else if (!strcasecmp(v->name, "rtcachefriends"))
10232          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10233       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10234          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10235       else if (!strcasecmp(v->name, "rtupdate"))
10236          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10237       else if (!strcasecmp(v->name, "trunktimestamps"))
10238          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10239       else if (!strcasecmp(v->name, "rtautoclear")) {
10240          int i = atoi(v->value);
10241          if(i > 0)
10242             global_rtautoclear = i;
10243          else
10244             i = 0;
10245          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10246       } else if (!strcasecmp(v->name, "trunkfreq")) {
10247          trunkfreq = atoi(v->value);
10248          if (trunkfreq < 10)
10249             trunkfreq = 10;
10250       } else if (!strcasecmp(v->name, "autokill")) {
10251          if (sscanf(v->value, "%d", &x) == 1) {
10252             if (x >= 0)
10253                autokill = x;
10254             else
10255                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10256          } else if (ast_true(v->value)) {
10257             autokill = DEFAULT_MAXMS;
10258          } else {
10259             autokill = 0;
10260          }
10261       } else if (!strcasecmp(v->name, "bandwidth")) {
10262          if (!strcasecmp(v->value, "low")) {
10263             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10264          } else if (!strcasecmp(v->value, "medium")) {
10265             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10266          } else if (!strcasecmp(v->value, "high")) {
10267             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10268          } else
10269             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10270       } else if (!strcasecmp(v->name, "allow")) {
10271          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10272       } else if (!strcasecmp(v->name, "disallow")) {
10273          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10274       } else if (!strcasecmp(v->name, "register")) {
10275          iax2_register(v->value, v->lineno);
10276       } else if (!strcasecmp(v->name, "iaxcompat")) {
10277          iaxcompat = ast_true(v->value);
10278       } else if (!strcasecmp(v->name, "regcontext")) {
10279          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10280          /* Create context if it doesn't exist already */
10281          if (!ast_context_find(regcontext))
10282             ast_context_create(NULL, regcontext, "IAX2");
10283       } else if (!strcasecmp(v->name, "tos")) {
10284          if (ast_str2tos(v->value, &tos))
10285             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10286       } else if (!strcasecmp(v->name, "accountcode")) {
10287          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10288       } else if (!strcasecmp(v->name, "mohinterpret")) {
10289          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
10290       } else if (!strcasecmp(v->name, "mohsuggest")) {
10291          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
10292       } else if (!strcasecmp(v->name, "amaflags")) {
10293          format = ast_cdr_amaflags2int(v->value);
10294          if (format < 0) {
10295             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10296          } else {
10297             amaflags = format;
10298          }
10299       } else if (!strcasecmp(v->name, "language")) {
10300          ast_copy_string(language, v->value, sizeof(language));
10301       } else if (!strcasecmp(v->name, "maxauthreq")) {
10302          maxauthreq = atoi(v->value);
10303          if (maxauthreq < 0)
10304             maxauthreq = 0;
10305       } else if (!strcasecmp(v->name, "adsi")) {
10306          adsi = ast_true(v->value);
10307       } /*else if (strcasecmp(v->name,"type")) */
10308       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10309       v = v->next;
10310    }
10311    
10312    if (defaultsockfd < 0) {
10313       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10314          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10315       } else {
10316          if (option_verbose > 1)
10317             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10318          defaultsockfd = ast_netsock_sockfd(ns);
10319          ast_netsock_unref(ns);
10320       }
10321    }
10322    if (reload) {
10323       ast_netsock_release(outsock);
10324       outsock = ast_netsock_list_alloc();
10325       if (!outsock) {
10326          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10327          return -1;
10328       }
10329       ast_netsock_init(outsock);
10330    }
10331 
10332    if (min_reg_expire > max_reg_expire) {
10333       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10334          min_reg_expire, max_reg_expire, max_reg_expire);
10335       min_reg_expire = max_reg_expire;
10336    }
10337    iax2_capability = capability;
10338    
10339    ucfg = ast_config_load("users.conf");
10340    if (ucfg) {
10341       struct ast_variable *gen;
10342       int genhasiax;
10343       int genregisteriax;
10344       const char *hasiax, *registeriax;
10345       
10346       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10347       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10348       gen = ast_variable_browse(ucfg, "general");
10349       cat = ast_category_browse(ucfg, NULL);
10350       while (cat) {
10351          if (strcasecmp(cat, "general")) {
10352             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10353             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10354             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10355                /* Start with general parameters, then specific parameters, user and peer */
10356                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10357                if (user) {
10358                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10359                   user = user_unref(user);
10360                }
10361                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10362                if (peer) {
10363                   if (ast_test_flag(peer, IAX_DYNAMIC))
10364                      reg_source_db(peer);
10365                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10366                   peer = peer_unref(peer);
10367                }
10368             }
10369             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10370                char tmp[256];
10371                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10372                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10373                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10374                if (!host)
10375                   host = ast_variable_retrieve(ucfg, "general", "host");
10376                if (!username)
10377                   username = ast_variable_retrieve(ucfg, "general", "username");
10378                if (!secret)
10379                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10380                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10381                   if (!ast_strlen_zero(secret))
10382                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10383                   else
10384                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10385                   iax2_register(tmp, 0);
10386                }
10387             }
10388          }
10389          cat = ast_category_browse(ucfg, cat);
10390       }
10391       ast_config_destroy(ucfg);
10392    }
10393    
10394    cat = ast_category_browse(cfg, NULL);
10395    while(cat) {
10396       if (strcasecmp(cat, "general")) {
10397          utype = ast_variable_retrieve(cfg, cat, "type");
10398          if (utype) {
10399             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10400                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10401                if (user) {
10402                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10403                   user = user_unref(user);
10404                }
10405             }
10406             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10407                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10408                if (peer) {
10409                   if (ast_test_flag(peer, IAX_DYNAMIC))
10410                      reg_source_db(peer);
10411                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10412                   peer = peer_unref(peer);
10413                }
10414             } else if (strcasecmp(utype, "user")) {
10415                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10416             }
10417          } else
10418             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10419       }
10420       cat = ast_category_browse(cfg, cat);
10421    }
10422    ast_config_destroy(cfg);
10423    set_timing();
10424    return 1;
10425 }
10426 
10427 static void poke_all_peers(void)
10428 {
10429    struct ao2_iterator i;
10430    struct iax2_peer *peer;
10431 
10432    i = ao2_iterator_init(peers, 0);
10433    while ((peer = ao2_iterator_next(&i))) {
10434       iax2_poke_peer(peer, 0);
10435       peer_unref(peer);
10436    }
10437 }
10438 static int reload_config(void)
10439 {
10440    char *config = "iax.conf";
10441    struct iax2_registry *reg;
10442 
10443    if (set_config(config, 1) > 0) {
10444       prune_peers();
10445       prune_users();
10446       AST_LIST_LOCK(&registrations);
10447       AST_LIST_TRAVERSE(&registrations, reg, entry)
10448          iax2_do_register(reg);
10449       AST_LIST_UNLOCK(&registrations);
10450       /* Qualify hosts, too */
10451       poke_all_peers();
10452    }
10453    reload_firmware(0);
10454    iax_provision_reload();
10455 
10456    return 0;
10457 }
10458 
10459 static int iax2_reload(int fd, int argc, char *argv[])
10460 {
10461    return reload_config();
10462 }
10463 
10464 static int reload(void)
10465 {
10466    return reload_config();
10467 }
10468 
10469 static int cache_get_callno_locked(const char *data)
10470 {
10471    struct sockaddr_in sin;
10472    int x;
10473    int callno;
10474    struct iax_ie_data ied;
10475    struct create_addr_info cai;
10476    struct parsed_dial_string pds;
10477    char *tmpstr;
10478 
10479    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10480       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10481          look up entries for a single context */
10482       if (!ast_mutex_trylock(&iaxsl[x])) {
10483          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10484             return x;
10485          ast_mutex_unlock(&iaxsl[x]);
10486       }
10487    }
10488 
10489    /* No match found, we need to create a new one */
10490 
10491    memset(&cai, 0, sizeof(cai));
10492    memset(&ied, 0, sizeof(ied));
10493    memset(&pds, 0, sizeof(pds));
10494 
10495    tmpstr = ast_strdupa(data);
10496    parse_dial_string(tmpstr, &pds);
10497 
10498    if (ast_strlen_zero(pds.peer)) {
10499       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10500       return -1;
10501    }
10502 
10503    /* Populate our address from the given */
10504    if (create_addr(pds.peer, NULL, &sin, &cai))
10505       return -1;
10506 
10507    if (option_debug)
10508       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10509          pds.peer, pds.username, pds.password, pds.context);
10510 
10511    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10512    if (callno < 1) {
10513       ast_log(LOG_WARNING, "Unable to create call\n");
10514       return -1;
10515    }
10516 
10517    ast_string_field_set(iaxs[callno], dproot, data);
10518    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10519 
10520    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10521    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10522    /* the string format is slightly different from a standard dial string,
10523       because the context appears in the 'exten' position
10524    */
10525    if (pds.exten)
10526       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10527    if (pds.username)
10528       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10529    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10530    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10531    /* Keep password handy */
10532    if (pds.password)
10533       ast_string_field_set(iaxs[callno], secret, pds.password);
10534    if (pds.key)
10535       ast_string_field_set(iaxs[callno], outkey, pds.key);
10536    /* Start the call going */
10537    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10538 
10539    return callno;
10540 }
10541 
10542 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10543 {
10544    struct iax2_dpcache *dp, *prev = NULL, *next;
10545    struct timeval tv;
10546    int x;
10547    int com[2];
10548    int timeout;
10549    int old=0;
10550    int outfd;
10551    int abort;
10552    int callno;
10553    struct ast_channel *c;
10554    struct ast_frame *f;
10555    gettimeofday(&tv, NULL);
10556    dp = dpcache;
10557    while(dp) {
10558       next = dp->next;
10559       /* Expire old caches */
10560       if (ast_tvcmp(tv, dp->expiry) > 0) {
10561             /* It's expired, let it disappear */
10562             if (prev)
10563                prev->next = dp->next;
10564             else
10565                dpcache = dp->next;
10566             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10567                /* Free memory and go again */
10568                free(dp);
10569             } else {
10570                ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
10571             }
10572             dp = next;
10573             continue;
10574       }
10575       /* We found an entry that matches us! */
10576       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10577          break;
10578       prev = dp;
10579       dp = next;
10580    }
10581    if (!dp) {
10582       /* No matching entry.  Create a new one. */
10583       /* First, can we make a callno? */
10584       callno = cache_get_callno_locked(data);
10585       if (callno < 0) {
10586          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10587          return NULL;
10588       }
10589       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10590          ast_mutex_unlock(&iaxsl[callno]);
10591          return NULL;
10592       }
10593       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10594       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10595       gettimeofday(&dp->expiry, NULL);
10596       dp->orig = dp->expiry;
10597       /* Expires in 30 mins by default */
10598       dp->expiry.tv_sec += iaxdefaultdpcache;
10599       dp->next = dpcache;
10600       dp->flags = CACHE_FLAG_PENDING;
10601       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10602          dp->waiters[x] = -1;
10603       dpcache = dp;
10604       dp->peer = iaxs[callno]->dpentries;
10605       iaxs[callno]->dpentries = dp;
10606       /* Send the request if we're already up */
10607       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10608          iax2_dprequest(dp, callno);
10609       ast_mutex_unlock(&iaxsl[callno]);
10610    }
10611    /* By here we must have a dp */
10612    if (dp->flags & CACHE_FLAG_PENDING) {
10613       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10614          for a reply to come back so long as it's pending */
10615       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10616          /* Find an empty slot */
10617          if (dp->waiters[x] < 0)
10618             break;
10619       }
10620       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10621          ast_log(LOG_WARNING, "No more waiter positions available\n");
10622          return NULL;
10623       }
10624       if (pipe(com)) {
10625          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10626          return NULL;
10627       }
10628       dp->waiters[x] = com[1];
10629       /* Okay, now we wait */
10630       timeout = iaxdefaulttimeout * 1000;
10631       /* Temporarily unlock */
10632       ast_mutex_unlock(&dpcache_lock);
10633       /* Defer any dtmf */
10634       if (chan)
10635          old = ast_channel_defer_dtmf(chan);
10636       abort = 0;
10637       while(timeout) {
10638          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10639          if (outfd > -1) {
10640             break;
10641          }
10642          if (c) {
10643             f = ast_read(c);
10644             if (f)
10645                ast_frfree(f);
10646             else {
10647                /* Got hung up on, abort! */
10648                break;
10649                abort = 1;
10650             }
10651          }
10652       }
10653       if (!timeout) {
10654          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10655       }
10656       ast_mutex_lock(&dpcache_lock);
10657       dp->waiters[x] = -1;
10658       close(com[1]);
10659       close(com[0]);
10660       if (abort) {
10661          /* Don't interpret anything, just abort.  Not sure what th epoint
10662            of undeferring dtmf on a hung up channel is but hey whatever */
10663          if (!old && chan)
10664             ast_channel_undefer_dtmf(chan);
10665          return NULL;
10666       }
10667       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10668          /* Now to do non-independent analysis the results of our wait */
10669          if (dp->flags & CACHE_FLAG_PENDING) {
10670             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10671                pending.  Don't let it take as long to timeout. */
10672             dp->flags &= ~CACHE_FLAG_PENDING;
10673             dp->flags |= CACHE_FLAG_TIMEOUT;
10674             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10675                systems without leaving it unavailable once the server comes back online */
10676             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10677             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
10678                if (dp->waiters[x] > -1) {
10679                   if (write(dp->waiters[x], "asdf", 4) < 0) {
10680                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10681                   }
10682                }
10683             }
10684          }
10685       }
10686       /* Our caller will obtain the rest */
10687       if (!old && chan)
10688          ast_channel_undefer_dtmf(chan);
10689    }
10690    return dp;  
10691 }
10692 
10693 /*! \brief Part of the IAX2 switch interface */
10694 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10695 {
10696    struct iax2_dpcache *dp;
10697    int res = 0;
10698 #if 0
10699    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10700 #endif
10701    if ((priority != 1) && (priority != 2))
10702       return 0;
10703    ast_mutex_lock(&dpcache_lock);
10704    dp = find_cache(chan, data, context, exten, priority);
10705    if (dp) {
10706       if (dp->flags & CACHE_FLAG_EXISTS)
10707          res= 1;
10708    }
10709    ast_mutex_unlock(&dpcache_lock);
10710    if (!dp) {
10711       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10712    }
10713    return res;
10714 }
10715 
10716 /*! \brief part of the IAX2 dial plan switch interface */
10717 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10718 {
10719    int res = 0;
10720    struct iax2_dpcache *dp;
10721 #if 0
10722    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10723 #endif
10724    if ((priority != 1) && (priority != 2))
10725       return 0;
10726    ast_mutex_lock(&dpcache_lock);
10727    dp = find_cache(chan, data, context, exten, priority);
10728    if (dp) {
10729       if (dp->flags & CACHE_FLAG_CANEXIST)
10730          res= 1;
10731    }
10732    ast_mutex_unlock(&dpcache_lock);
10733    if (!dp) {
10734       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10735    }
10736    return res;
10737 }
10738 
10739 /*! \brief Part of the IAX2 Switch interface */
10740 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10741 {
10742    int res = 0;
10743    struct iax2_dpcache *dp;
10744 #if 0
10745    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10746 #endif
10747    if ((priority != 1) && (priority != 2))
10748       return 0;
10749    ast_mutex_lock(&dpcache_lock);
10750    dp = find_cache(chan, data, context, exten, priority);
10751    if (dp) {
10752       if (dp->flags & CACHE_FLAG_MATCHMORE)
10753          res= 1;
10754    }
10755    ast_mutex_unlock(&dpcache_lock);
10756    if (!dp) {
10757       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10758    }
10759    return res;
10760 }
10761 
10762 /*! \brief Execute IAX2 dialplan switch */
10763 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10764 {
10765    char odata[256];
10766    char req[256];
10767    char *ncontext;
10768    struct iax2_dpcache *dp;
10769    struct ast_app *dial;
10770 #if 0
10771    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);
10772 #endif
10773    if (priority == 2) {
10774       /* Indicate status, can be overridden in dialplan */
10775       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10776       if (dialstatus) {
10777          dial = pbx_findapp(dialstatus);
10778          if (dial) 
10779             pbx_exec(chan, dial, "");
10780       }
10781       return -1;
10782    } else if (priority != 1)
10783       return -1;
10784    ast_mutex_lock(&dpcache_lock);
10785    dp = find_cache(chan, data, context, exten, priority);
10786    if (dp) {
10787       if (dp->flags & CACHE_FLAG_EXISTS) {
10788          ast_copy_string(odata, data, sizeof(odata));
10789          ncontext = strchr(odata, '/');
10790          if (ncontext) {
10791             *ncontext = '\0';
10792             ncontext++;
10793             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10794          } else {
10795             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10796          }
10797          if (option_verbose > 2)
10798             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10799       } else {
10800          ast_mutex_unlock(&dpcache_lock);
10801          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10802          return -1;
10803       }
10804    }
10805    ast_mutex_unlock(&dpcache_lock);
10806    dial = pbx_findapp("Dial");
10807    if (dial) {
10808       return pbx_exec(chan, dial, req);
10809    } else {
10810       ast_log(LOG_WARNING, "No dial application registered\n");
10811    }
10812    return -1;
10813 }
10814 
10815 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10816 {
10817    struct iax2_peer *peer;
10818    char *peername, *colname;
10819 
10820    peername = ast_strdupa(data);
10821 
10822    /* if our channel, return the IP address of the endpoint of current channel */
10823    if (!strcmp(peername,"CURRENTCHANNEL")) {
10824            unsigned short callno;
10825       if (chan->tech != &iax2_tech)
10826          return -1;
10827       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10828       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10829       return 0;
10830    }
10831 
10832    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10833       *colname++ = '\0';
10834    else if ((colname = strchr(peername, '|')))
10835       *colname++ = '\0';
10836    else
10837       colname = "ip";
10838 
10839    if (!(peer = find_peer(peername, 1)))
10840       return -1;
10841 
10842    if (!strcasecmp(colname, "ip")) {
10843       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10844    } else  if (!strcasecmp(colname, "status")) {
10845       peer_status(peer, buf, len); 
10846    } else  if (!strcasecmp(colname, "mailbox")) {
10847       ast_copy_string(buf, peer->mailbox, len);
10848    } else  if (!strcasecmp(colname, "context")) {
10849       ast_copy_string(buf, peer->context, len);
10850    } else  if (!strcasecmp(colname, "expire")) {
10851       snprintf(buf, len, "%d", peer->expire);
10852    } else  if (!strcasecmp(colname, "dynamic")) {
10853       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10854    } else  if (!strcasecmp(colname, "callerid_name")) {
10855       ast_copy_string(buf, peer->cid_name, len);
10856    } else  if (!strcasecmp(colname, "callerid_num")) {
10857       ast_copy_string(buf, peer->cid_num, len);
10858    } else  if (!strcasecmp(colname, "codecs")) {
10859       ast_getformatname_multiple(buf, len -1, peer->capability);
10860    } else  if (!strncasecmp(colname, "codec[", 6)) {
10861       char *codecnum, *ptr;
10862       int index = 0, codec = 0;
10863       
10864       codecnum = strchr(colname, '[');
10865       *codecnum = '\0';
10866       codecnum++;
10867       if ((ptr = strchr(codecnum, ']'))) {
10868          *ptr = '\0';
10869       }
10870       index = atoi(codecnum);
10871       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10872          ast_copy_string(buf, ast_getformatname(codec), len);
10873       } else {
10874          buf[0] = '\0';
10875       }
10876    } else {
10877       buf[0] = '\0';
10878    }
10879 
10880    peer_unref(peer);
10881 
10882    return 0;
10883 }
10884 
10885 struct ast_custom_function iaxpeer_function = {
10886    .name = "IAXPEER",
10887    .synopsis = "Gets IAX peer information",
10888    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10889    .read = function_iaxpeer,
10890    .desc = "If peername specified, valid items are:\n"
10891    "- ip (default)          The IP address.\n"
10892    "- status                The peer's status (if qualify=yes)\n"
10893    "- mailbox               The configured mailbox.\n"
10894    "- context               The configured context.\n"
10895    "- expire                The epoch time of the next expire.\n"
10896    "- dynamic               Is it dynamic? (yes/no).\n"
10897    "- callerid_name         The configured Caller ID name.\n"
10898    "- callerid_num          The configured Caller ID number.\n"
10899    "- codecs                The configured codecs.\n"
10900    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10901    "\n"
10902    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10903    "\n"
10904 };
10905 
10906 
10907 /*! \brief Part of the device state notification system ---*/
10908 static int iax2_devicestate(void *data) 
10909 {
10910    struct parsed_dial_string pds;
10911    char *tmp = ast_strdupa(data);
10912    struct iax2_peer *p;
10913    int res = AST_DEVICE_INVALID;
10914 
10915    memset(&pds, 0, sizeof(pds));
10916    parse_dial_string(tmp, &pds);
10917 
10918    if (ast_strlen_zero(pds.peer)) {
10919       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10920       return res;
10921    }
10922    
10923    if (option_debug > 2)
10924       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10925 
10926    /* SLD: FIXME: second call to find_peer during registration */
10927    if (!(p = find_peer(pds.peer, 1)))
10928       return res;
10929 
10930    res = AST_DEVICE_UNAVAILABLE;
10931    if (option_debug > 2) 
10932       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10933          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10934    
10935    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10936        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10937       /* Peer is registered, or have default IP address
10938          and a valid registration */
10939       if (p->historicms == 0 || p->historicms <= p->maxms)
10940          /* let the core figure out whether it is in use or not */
10941          res = AST_DEVICE_UNKNOWN;  
10942    }
10943 
10944    peer_unref(p);
10945 
10946    return res;
10947 }
10948 
10949 static struct ast_switch iax2_switch = 
10950 {
10951    name:          "IAX2",
10952    description:      "IAX Remote Dialplan Switch",
10953    exists:        iax2_exists,
10954    canmatch:      iax2_canmatch,
10955    exec:       iax2_exec,
10956    matchmore:     iax2_matchmore,
10957 };
10958 
10959 static char show_stats_usage[] =
10960 "Usage: iax2 show stats\n"
10961 "       Display statistics on IAX channel driver.\n";
10962 
10963 static char show_cache_usage[] =
10964 "Usage: iax2 show cache\n"
10965 "       Display currently cached IAX Dialplan results.\n";
10966 
10967 static char show_peer_usage[] =
10968 "Usage: iax2 show peer <name>\n"
10969 "       Display details on specific IAX peer\n";
10970 
10971 static char prune_realtime_usage[] =
10972 "Usage: iax2 prune realtime [<peername>|all]\n"
10973 "       Prunes object(s) from the cache\n";
10974 
10975 static char iax2_reload_usage[] =
10976 "Usage: iax2 reload\n"
10977 "       Reloads IAX configuration from iax.conf\n";
10978 
10979 static char show_prov_usage[] =
10980 "Usage: iax2 provision <host> <template> [forced]\n"
10981 "       Provisions the given peer or IP address using a template\n"
10982 "       matching either 'template' or '*' if the template is not\n"
10983 "       found.  If 'forced' is specified, even empty provisioning\n"
10984 "       fields will be provisioned as empty fields.\n";
10985 
10986 static char show_users_usage[] = 
10987 "Usage: iax2 show users [like <pattern>]\n"
10988 "       Lists all known IAX2 users.\n"
10989 "       Optional regular expression pattern is used to filter the user list.\n";
10990 
10991 static char show_channels_usage[] = 
10992 "Usage: iax2 show channels\n"
10993 "       Lists all currently active IAX channels.\n";
10994 
10995 static char show_netstats_usage[] = 
10996 "Usage: iax2 show netstats\n"
10997 "       Lists network status for all currently active IAX channels.\n";
10998 
10999 static char show_threads_usage[] = 
11000 "Usage: iax2 show threads\n"
11001 "       Lists status of IAX helper threads\n";
11002 
11003 static char show_peers_usage[] = 
11004 "Usage: iax2 show peers [registered] [like <pattern>]\n"
11005 "       Lists all known IAX2 peers.\n"
11006 "       Optional 'registered' argument lists only peers with known addresses.\n"
11007 "       Optional regular expression pattern is used to filter the peer list.\n";
11008 
11009 static char show_firmware_usage[] = 
11010 "Usage: iax2 show firmware\n"
11011 "       Lists all known IAX firmware images.\n";
11012 
11013 static char show_reg_usage[] =
11014 "Usage: iax2 show registry\n"
11015 "       Lists all registration requests and status.\n";
11016 
11017 static char debug_usage[] = 
11018 "Usage: iax2 set debug\n"
11019 "       Enables dumping of IAX packets for debugging purposes\n";
11020 
11021 static char no_debug_usage[] = 
11022 "Usage: iax2 set debug off\n"
11023 "       Disables dumping of IAX packets for debugging purposes\n";
11024 
11025 static char debug_trunk_usage[] =
11026 "Usage: iax2 set debug trunk\n"
11027 "       Requests current status of IAX trunking\n";
11028 
11029 static char no_debug_trunk_usage[] =
11030 "Usage: iax2 set debug trunk off\n"
11031 "       Requests current status of IAX trunking\n";
11032 
11033 static char debug_jb_usage[] =
11034 "Usage: iax2 set debug jb\n"
11035 "       Enables jitterbuffer debugging information\n";
11036 
11037 static char no_debug_jb_usage[] =
11038 "Usage: iax2 set debug jb off\n"
11039 "       Disables jitterbuffer debugging information\n";
11040 
11041 static char iax2_test_losspct_usage[] =
11042 "Usage: iax2 test losspct <percentage>\n"
11043 "       For testing, throws away <percentage> percent of incoming packets\n";
11044 
11045 #ifdef IAXTESTS
11046 static char iax2_test_late_usage[] =
11047 "Usage: iax2 test late <ms>\n"
11048 "       For testing, count the next frame as <ms> ms late\n";
11049 
11050 static char iax2_test_resync_usage[] =
11051 "Usage: iax2 test resync <ms>\n"
11052 "       For testing, adjust all future frames by <ms> ms\n";
11053 
11054 static char iax2_test_jitter_usage[] =
11055 "Usage: iax2 test jitter <ms> <pct>\n"
11056 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
11057 #endif /* IAXTESTS */
11058 
11059 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
11060    { "iax2", "trunk", "debug", NULL },
11061    iax2_do_trunk_debug, NULL,
11062    NULL };
11063 
11064 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
11065    { "iax2", "jb", "debug", NULL },
11066    iax2_do_jb_debug, NULL,
11067    NULL };
11068 
11069 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
11070    { "iax2", "no", "debug", NULL },
11071    iax2_no_debug, NULL,
11072    NULL };
11073 
11074 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
11075    { "iax2", "no", "trunk", "debug", NULL },
11076    iax2_no_trunk_debug, NULL,
11077    NULL };
11078 
11079 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
11080    { "iax2", "no", "jb", "debug", NULL },
11081    iax2_no_jb_debug, NULL,
11082    NULL };
11083 
11084 static struct ast_cli_entry cli_iax2[] = {
11085    { { "iax2", "show", "cache", NULL },
11086    iax2_show_cache, "Display IAX cached dialplan",
11087    show_cache_usage, NULL, },
11088 
11089    { { "iax2", "show", "channels", NULL },
11090    iax2_show_channels, "List active IAX channels",
11091    show_channels_usage, NULL, },
11092 
11093    { { "iax2", "show", "firmware", NULL },
11094    iax2_show_firmware, "List available IAX firmwares",
11095    show_firmware_usage, NULL, },
11096 
11097    { { "iax2", "show", "netstats", NULL },
11098    iax2_show_netstats, "List active IAX channel netstats",
11099    show_netstats_usage, NULL, },
11100 
11101    { { "iax2", "show", "peers", NULL },
11102    iax2_show_peers, "List defined IAX peers",
11103    show_peers_usage, NULL, },
11104 
11105    { { "iax2", "show", "registry", NULL },
11106    iax2_show_registry, "Display IAX registration status",
11107    show_reg_usage, NULL, },
11108 
11109    { { "iax2", "show", "stats", NULL },
11110    iax2_show_stats, "Display IAX statistics",
11111    show_stats_usage, NULL, },
11112 
11113    { { "iax2", "show", "threads", NULL },
11114    iax2_show_threads, "Display IAX helper thread info",
11115    show_threads_usage, NULL, },
11116 
11117    { { "iax2", "show", "users", NULL },
11118    iax2_show_users, "List defined IAX users",
11119    show_users_usage, NULL, },
11120 
11121    { { "iax2", "prune", "realtime", NULL },
11122    iax2_prune_realtime, "Prune a cached realtime lookup",
11123    prune_realtime_usage, complete_iax2_show_peer },
11124 
11125    { { "iax2", "reload", NULL },
11126    iax2_reload, "Reload IAX configuration",
11127    iax2_reload_usage },
11128 
11129    { { "iax2", "show", "peer", NULL },
11130    iax2_show_peer, "Show details on specific IAX peer",
11131    show_peer_usage, complete_iax2_show_peer },
11132 
11133    { { "iax2", "set", "debug", NULL },
11134    iax2_do_debug, "Enable IAX debugging",
11135    debug_usage },
11136 
11137    { { "iax2", "set", "debug", "trunk", NULL },
11138    iax2_do_trunk_debug, "Enable IAX trunk debugging",
11139    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
11140 
11141    { { "iax2", "set", "debug", "jb", NULL },
11142    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
11143    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
11144 
11145    { { "iax2", "set", "debug", "off", NULL },
11146    iax2_no_debug, "Disable IAX debugging",
11147    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
11148 
11149    { { "iax2", "set", "debug", "trunk", "off", NULL },
11150    iax2_no_trunk_debug, "Disable IAX trunk debugging",
11151    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
11152 
11153    { { "iax2", "set", "debug", "jb", "off", NULL },
11154    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
11155    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
11156 
11157    { { "iax2", "test", "losspct", NULL },
11158    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
11159    iax2_test_losspct_usage },
11160 
11161    { { "iax2", "provision", NULL },
11162    iax2_prov_cmd, "Provision an IAX device",
11163    show_prov_usage, iax2_prov_complete_template_3rd },
11164 
11165 #ifdef IAXTESTS
11166    { { "iax2", "test", "late", NULL },
11167    iax2_test_late, "Test the receipt of a late frame",
11168    iax2_test_late_usage },
11169 
11170    { { "iax2", "test", "resync", NULL },
11171    iax2_test_resync, "Test a resync in received timestamps",
11172    iax2_test_resync_usage },
11173 
11174    { { "iax2", "test", "jitter", NULL },
11175    iax2_test_jitter, "Simulates jitter for testing",
11176    iax2_test_jitter_usage },
11177 #endif /* IAXTESTS */
11178 };
11179 
11180 static int __unload_module(void)
11181 {
11182    struct iax2_thread *thread = NULL;
11183    int x;
11184 
11185    /* Make sure threads do not hold shared resources when they are canceled */
11186    
11187    /* Grab the sched lock resource to keep it away from threads about to die */
11188    /* Cancel the network thread, close the net socket */
11189    if (netthreadid != AST_PTHREADT_NULL) {
11190       AST_LIST_LOCK(&iaxq.queue);
11191       ast_mutex_lock(&sched_lock);
11192       pthread_cancel(netthreadid);
11193       ast_cond_signal(&sched_cond);
11194       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11195       AST_LIST_UNLOCK(&iaxq.queue);
11196       pthread_join(netthreadid, NULL);
11197    }
11198    if (schedthreadid != AST_PTHREADT_NULL) {
11199       ast_mutex_lock(&sched_lock);  
11200       pthread_cancel(schedthreadid);
11201       ast_cond_signal(&sched_cond);
11202       ast_mutex_unlock(&sched_lock);   
11203       pthread_join(schedthreadid, NULL);
11204    }
11205    
11206    /* Call for all threads to halt */
11207    AST_LIST_LOCK(&idle_list);
11208    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11209       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11210       pthread_cancel(thread->threadid);
11211    }
11212    AST_LIST_TRAVERSE_SAFE_END
11213    AST_LIST_UNLOCK(&idle_list);
11214 
11215    AST_LIST_LOCK(&active_list);
11216    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11217       AST_LIST_REMOVE_CURRENT(&active_list, list);
11218       pthread_cancel(thread->threadid);
11219    }
11220    AST_LIST_TRAVERSE_SAFE_END
11221    AST_LIST_UNLOCK(&active_list);
11222 
11223    AST_LIST_LOCK(&dynamic_list);
11224         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11225       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11226       pthread_cancel(thread->threadid);
11227         }
11228    AST_LIST_TRAVERSE_SAFE_END
11229         AST_LIST_UNLOCK(&dynamic_list);
11230 
11231    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11232 
11233    /* Wait for threads to exit */
11234    while(0 < iaxactivethreadcount)
11235       usleep(10000);
11236    
11237    ast_netsock_release(netsock);
11238    ast_netsock_release(outsock);
11239    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11240       if (iaxs[x]) {
11241          iax2_destroy(x);
11242       }
11243    }
11244    ast_manager_unregister( "IAXpeers" );
11245    ast_manager_unregister( "IAXnetstats" );
11246    ast_unregister_application(papp);
11247    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11248    ast_unregister_switch(&iax2_switch);
11249    ast_channel_unregister(&iax2_tech);
11250    delete_users();
11251    iax_provision_unload();
11252    sched_context_destroy(sched);
11253    reload_firmware(1);
11254 
11255    ast_mutex_destroy(&waresl.lock);
11256 
11257    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11258       ast_mutex_destroy(&iaxsl[x]);
11259    }
11260 
11261    ao2_ref(peers, -1);
11262    ao2_ref(users, -1);
11263    ao2_ref(iax_peercallno_pvts, -1);
11264    ao2_ref(iax_transfercallno_pvts, -1);  
11265 
11266    return 0;
11267 }
11268 
11269 static int unload_module(void)
11270 {
11271    ast_custom_function_unregister(&iaxpeer_function);
11272    return __unload_module();
11273 }
11274 
11275 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11276 {
11277    struct iax2_peer *peer = obj;
11278 
11279    if (peer->sockfd < 0)
11280       peer->sockfd = defaultsockfd;
11281 
11282    return 0;
11283 }
11284 
11285 static int pvt_hash_cb(const void *obj, const int flags)
11286 {
11287    const struct chan_iax2_pvt *pvt = obj;
11288 
11289    return pvt->peercallno;
11290 }
11291 
11292 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11293 {
11294    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11295 
11296    /* The frames_received field is used to hold whether we're matching
11297     * against a full frame or not ... */
11298 
11299    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11300       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11301 }
11302 
11303 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
11304 {
11305    const struct chan_iax2_pvt *pvt = obj;
11306 
11307    return pvt->transfercallno;
11308 }
11309 
11310 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
11311 {
11312    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11313 
11314    /* The frames_received field is used to hold whether we're matching
11315     * against a full frame or not ... */
11316 
11317    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
11318       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11319 }
11320 /*! \brief Load IAX2 module, load configuraiton ---*/
11321 static int load_module(void)
11322 {
11323    char *config = "iax.conf";
11324    int res = 0;
11325    int x;
11326    struct iax2_registry *reg = NULL;
11327 
11328    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11329    if (!peers)
11330       return AST_MODULE_LOAD_FAILURE;
11331    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11332    if (!users) {
11333       ao2_ref(peers, -1);
11334       return AST_MODULE_LOAD_FAILURE;
11335    }
11336    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11337    if (!iax_peercallno_pvts) {
11338       ao2_ref(peers, -1);
11339       ao2_ref(users, -1);
11340       return AST_MODULE_LOAD_FAILURE;
11341    }
11342    iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
11343    if (!iax_transfercallno_pvts) {
11344       ao2_ref(peers, -1);
11345       ao2_ref(users, -1);
11346       ao2_ref(iax_peercallno_pvts, -1);
11347       return AST_MODULE_LOAD_FAILURE;
11348    }
11349    ast_custom_function_register(&iaxpeer_function);
11350 
11351    iax_set_output(iax_debug_output);
11352    iax_set_error(iax_error_output);
11353    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11354    
11355 #ifdef HAVE_DAHDI
11356 #ifdef DAHDI_TIMERACK
11357    timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
11358    if (timingfd < 0)
11359 #endif
11360       timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
11361    if (timingfd < 0) 
11362       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11363 #endif
11364 
11365    memset(iaxs, 0, sizeof(iaxs));
11366 
11367    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11368       ast_mutex_init(&iaxsl[x]);
11369    }
11370    
11371    ast_cond_init(&sched_cond, NULL);
11372 
11373    io = io_context_create();
11374    sched = sched_context_create();
11375    
11376    if (!io || !sched) {
11377       ast_log(LOG_ERROR, "Out of memory\n");
11378       return -1;
11379    }
11380 
11381    netsock = ast_netsock_list_alloc();
11382    if (!netsock) {
11383       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11384       return -1;
11385    }
11386    ast_netsock_init(netsock);
11387 
11388    outsock = ast_netsock_list_alloc();
11389    if (!outsock) {
11390       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11391       return -1;
11392    }
11393    ast_netsock_init(outsock);
11394 
11395    ast_mutex_init(&waresl.lock);
11396 
11397    AST_LIST_HEAD_INIT(&iaxq.queue);
11398    
11399    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11400 
11401    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11402    
11403    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11404    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11405 
11406    if(set_config(config, 0) == -1)
11407       return AST_MODULE_LOAD_DECLINE;
11408 
11409    if (ast_channel_register(&iax2_tech)) {
11410       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11411       __unload_module();
11412       return -1;
11413    }
11414 
11415    if (ast_register_switch(&iax2_switch)) 
11416       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11417 
11418    res = start_network_thread();
11419    if (!res) {
11420       if (option_verbose > 1) 
11421          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11422    } else {
11423       ast_log(LOG_ERROR, "Unable to start network thread\n");
11424       ast_netsock_release(netsock);
11425       ast_netsock_release(outsock);
11426    }
11427 
11428    AST_LIST_LOCK(&registrations);
11429    AST_LIST_TRAVERSE(&registrations, reg, entry)
11430       iax2_do_register(reg);
11431    AST_LIST_UNLOCK(&registrations); 
11432 
11433    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11434    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11435 
11436    reload_firmware(0);
11437    iax_provision_reload();
11438    return res;
11439 }
11440 
11441 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11442       .load = load_module,
11443       .unload = unload_module,
11444       .reload = reload,
11445           );

Generated on Fri Apr 24 16:25:53 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7