Mon Apr 30 07:36:31 2007

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>zaptel</use>
00033  ***/
00034 
00035 #include "asterisk.h"
00036 
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <sys/types.h>
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <string.h>
00053 #include <strings.h>
00054 #include <errno.h>
00055 #include <unistd.h>
00056 #include <netdb.h>
00057 #include <fcntl.h>
00058 #include <sys/stat.h>
00059 #include <regex.h>
00060 
00061 #ifdef HAVE_ZAPTEL
00062 #include <sys/ioctl.h>
00063 #include <zaptel/zaptel.h>
00064 #endif
00065 
00066 #include "asterisk/lock.h"
00067 #include "asterisk/frame.h" 
00068 #include "asterisk/channel.h"
00069 #include "asterisk/logger.h"
00070 #include "asterisk/module.h"
00071 #include "asterisk/pbx.h"
00072 #include "asterisk/sched.h"
00073 #include "asterisk/io.h"
00074 #include "asterisk/config.h"
00075 #include "asterisk/options.h"
00076 #include "asterisk/cli.h"
00077 #include "asterisk/translate.h"
00078 #include "asterisk/md5.h"
00079 #include "asterisk/cdr.h"
00080 #include "asterisk/crypto.h"
00081 #include "asterisk/acl.h"
00082 #include "asterisk/manager.h"
00083 #include "asterisk/callerid.h"
00084 #include "asterisk/app.h"
00085 #include "asterisk/astdb.h"
00086 #include "asterisk/musiconhold.h"
00087 #include "asterisk/features.h"
00088 #include "asterisk/utils.h"
00089 #include "asterisk/causes.h"
00090 #include "asterisk/localtime.h"
00091 #include "asterisk/aes.h"
00092 #include "asterisk/dnsmgr.h"
00093 #include "asterisk/devicestate.h"
00094 #include "asterisk/netsock.h"
00095 #include "asterisk/stringfields.h"
00096 #include "asterisk/linkedlists.h"
00097 
00098 #include "iax2.h"
00099 #include "iax2-parser.h"
00100 #include "iax2-provision.h"
00101 #include "jitterbuf.h"
00102 
00103 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00104    multithreaded mode. */
00105 #define SCHED_MULTITHREADED
00106 
00107 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00108    thread is actually doing. */
00109 #define DEBUG_SCHED_MULTITHREAD
00110 
00111 #ifndef IPTOS_MINCOST
00112 #define IPTOS_MINCOST 0x02
00113 #endif
00114 
00115 #ifdef SO_NO_CHECK
00116 static int nochecksums = 0;
00117 #endif
00118 
00119 
00120 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00121 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00122 
00123 #define DEFAULT_THREAD_COUNT 10
00124 #define DEFAULT_MAX_THREAD_COUNT 100
00125 #define DEFAULT_RETRY_TIME 1000
00126 #define MEMORY_SIZE 100
00127 #define DEFAULT_DROP 3
00128 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00129    but keeps the division between trunked and non-trunked better. */
00130 #define TRUNK_CALL_START   0x4000
00131 
00132 #define DEBUG_SUPPORT
00133 
00134 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00135 
00136 /* Sample over last 100 units to determine historic jitter */
00137 #define GAMMA (0.01)
00138 
00139 static struct ast_codec_pref prefs;
00140 
00141 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00142 
00143 static char context[80] = "default";
00144 
00145 static char language[MAX_LANGUAGE] = "";
00146 static char regcontext[AST_MAX_CONTEXT] = "";
00147 
00148 static int maxauthreq = 3;
00149 static int max_retries = 4;
00150 static int ping_time = 20;
00151 static int lagrq_time = 10;
00152 static int maxtrunkcall = TRUNK_CALL_START;
00153 static int maxnontrunkcall = 1;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 
00162 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00163 
00164 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00165 
00166 static unsigned int tos = 0;
00167 
00168 static int min_reg_expire;
00169 static int max_reg_expire;
00170 
00171 static int timingfd = -1;           /* Timing file descriptor */
00172 
00173 static struct ast_netsock_list *netsock;
00174 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00175 static int defaultsockfd = -1;
00176 
00177 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00178 
00179 /* Ethernet, etc */
00180 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00181 /* T1, maybe ISDN */
00182 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00183                 ~AST_FORMAT_SLINEAR &        \
00184                 ~AST_FORMAT_ULAW &        \
00185                 ~AST_FORMAT_ALAW &        \
00186                 ~AST_FORMAT_G722) 
00187 /* A modem */
00188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00189                 ~AST_FORMAT_G726 &        \
00190                 ~AST_FORMAT_G726_AAL2 &      \
00191                 ~AST_FORMAT_ADPCM)
00192 
00193 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00194                 ~AST_FORMAT_G723_1)
00195 
00196 
00197 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00198 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00199 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00200 
00201 static   struct io_context *io;
00202 static   struct sched_context *sched;
00203 
00204 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00205 
00206 static int iaxdebug = 0;
00207 
00208 static int iaxtrunkdebug = 0;
00209 
00210 static int test_losspct = 0;
00211 #ifdef IAXTESTS
00212 static int test_late = 0;
00213 static int test_resync = 0;
00214 static int test_jit = 0;
00215 static int test_jitpct = 0;
00216 #endif /* IAXTESTS */
00217 
00218 static char accountcode[AST_MAX_ACCOUNT_CODE];
00219 static char mohinterpret[MAX_MUSICCLASS];
00220 static char mohsuggest[MAX_MUSICCLASS];
00221 static int amaflags = 0;
00222 static int adsi = 0;
00223 static int delayreject = 0;
00224 static int iax2_encryption = 0;
00225 
00226 static struct ast_flags globalflags = { 0 };
00227 
00228 static pthread_t netthreadid = AST_PTHREADT_NULL;
00229 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00230 AST_MUTEX_DEFINE_STATIC(sched_lock);
00231 static ast_cond_t sched_cond;
00232 
00233 enum {
00234    IAX_STATE_STARTED =     (1 << 0),
00235    IAX_STATE_AUTHENTICATED =  (1 << 1),
00236    IAX_STATE_TBD =      (1 << 2),
00237    IAX_STATE_UNCHANGED =      (1 << 3),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271 } iax2_flags;
00272 
00273 static int global_rtautoclear = 120;
00274 
00275 static int reload_config(void);
00276 static int iax2_reload(int fd, int argc, char *argv[]);
00277 
00278 
00279 struct iax2_user {
00280    AST_DECLARE_STRING_FIELDS(
00281       AST_STRING_FIELD(name);
00282       AST_STRING_FIELD(secret);
00283       AST_STRING_FIELD(dbsecret);
00284       AST_STRING_FIELD(accountcode);
00285       AST_STRING_FIELD(mohinterpret);
00286       AST_STRING_FIELD(mohsuggest);
00287       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00288       AST_STRING_FIELD(language);
00289       AST_STRING_FIELD(cid_num);
00290       AST_STRING_FIELD(cid_name);
00291    );
00292    
00293    int authmethods;
00294    int encmethods;
00295    int amaflags;
00296    int adsi;
00297    unsigned int flags;
00298    int capability;
00299    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00300    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00301    struct ast_codec_pref prefs;
00302    struct ast_ha *ha;
00303    struct iax2_context *contexts;
00304    struct ast_variable *vars;
00305    AST_LIST_ENTRY(iax2_user) entry;
00306 };
00307 
00308 struct iax2_peer {
00309    AST_DECLARE_STRING_FIELDS(
00310       AST_STRING_FIELD(name);
00311       AST_STRING_FIELD(username);
00312       AST_STRING_FIELD(secret);
00313       AST_STRING_FIELD(dbsecret);
00314       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00315 
00316       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00317       AST_STRING_FIELD(context);      /*!< For transfers only */
00318       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00319       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00320       AST_STRING_FIELD(mohinterpret);
00321       AST_STRING_FIELD(mohsuggest);
00322       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00323       /* Suggested caller id if registering */
00324       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00325       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00326       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00327    );
00328    struct ast_codec_pref prefs;
00329    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00330    struct sockaddr_in addr;
00331    int formats;
00332    int sockfd;             /*!< Socket to use for transmission */
00333    struct in_addr mask;
00334    int adsi;
00335    unsigned int flags;
00336 
00337    /* Dynamic Registration fields */
00338    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00339    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00340    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00341 
00342    int expire;             /*!< Schedule entry for expiry */
00343    int expiry;             /*!< How soon to expire */
00344    int capability;               /*!< Capability */
00345 
00346    /* Qualification */
00347    int callno;             /*!< Call number of POKE request */
00348    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00349    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00350    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00351 
00352    int pokefreqok;               /*!< How often to check if the host is up */
00353    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00354    int historicms;               /*!< How long recent average responses took */
00355    int smoothing;             /*!< Sample over how many units to determine historic ms */
00356    
00357    struct ast_ha *ha;
00358    AST_LIST_ENTRY(iax2_peer) entry;
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 iaxactivethreadcount = 0;
00452 
00453 struct iax_rr {
00454    int jitter;
00455    int losspct;
00456    int losscnt;
00457    int packets;
00458    int delay;
00459    int dropped;
00460    int ooo;
00461 };
00462 
00463 struct chan_iax2_pvt {
00464    /*! Socket to send/receive on for this call */
00465    int sockfd;
00466    /*! Last received voice format */
00467    int voiceformat;
00468    /*! Last received video format */
00469    int videoformat;
00470    /*! Last sent voice format */
00471    int svoiceformat;
00472    /*! Last sent video format */
00473    int svideoformat;
00474    /*! What we are capable of sending */
00475    int capability;
00476    /*! Last received timestamp */
00477    unsigned int last;
00478    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00479    unsigned int lastsent;
00480    /*! Next outgoing timestamp if everything is good */
00481    unsigned int nextpred;
00482    /*! True if the last voice we transmitted was not silence/CNG */
00483    int notsilenttx;
00484    /*! Ping time */
00485    unsigned int pingtime;
00486    /*! Max time for initial response */
00487    int maxtime;
00488    /*! Peer Address */
00489    struct sockaddr_in addr;
00490    /*! Actual used codec preferences */
00491    struct ast_codec_pref prefs;
00492    /*! Requested codec preferences */
00493    struct ast_codec_pref rprefs;
00494    /*! Our call number */
00495    unsigned short callno;
00496    /*! Peer callno */
00497    unsigned short peercallno;
00498    /*! Peer selected format */
00499    int peerformat;
00500    /*! Peer capability */
00501    int peercapability;
00502    /*! timeval that we base our transmission on */
00503    struct timeval offset;
00504    /*! timeval that we base our delivery on */
00505    struct timeval rxcore;
00506    /*! The jitterbuffer */
00507         jitterbuf *jb;
00508    /*! active jb read scheduler id */
00509         int jbid;                       
00510    /*! LAG */
00511    int lag;
00512    /*! Error, as discovered by the manager */
00513    int error;
00514    /*! Owner if we have one */
00515    struct ast_channel *owner;
00516    /*! What's our state? */
00517    struct ast_flags state;
00518    /*! Expiry (optional) */
00519    int expiry;
00520    /*! Next outgoing sequence number */
00521    unsigned char oseqno;
00522    /*! Next sequence number they have not yet acknowledged */
00523    unsigned char rseqno;
00524    /*! Next incoming sequence number */
00525    unsigned char iseqno;
00526    /*! Last incoming sequence number we have acknowledged */
00527    unsigned char aseqno;
00528 
00529    AST_DECLARE_STRING_FIELDS(
00530       /*! Peer name */
00531       AST_STRING_FIELD(peer);
00532       /*! Default Context */
00533       AST_STRING_FIELD(context);
00534       /*! Caller ID if available */
00535       AST_STRING_FIELD(cid_num);
00536       AST_STRING_FIELD(cid_name);
00537       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00538       AST_STRING_FIELD(ani);
00539       /*! DNID */
00540       AST_STRING_FIELD(dnid);
00541       /*! RDNIS */
00542       AST_STRING_FIELD(rdnis);
00543       /*! Requested Extension */
00544       AST_STRING_FIELD(exten);
00545       /*! Expected Username */
00546       AST_STRING_FIELD(username);
00547       /*! Expected Secret */
00548       AST_STRING_FIELD(secret);
00549       /*! MD5 challenge */
00550       AST_STRING_FIELD(challenge);
00551       /*! Public keys permitted keys for incoming authentication */
00552       AST_STRING_FIELD(inkeys);
00553       /*! Private key for outgoing authentication */
00554       AST_STRING_FIELD(outkey);
00555       /*! Preferred language */
00556       AST_STRING_FIELD(language);
00557       /*! Hostname/peername for naming purposes */
00558       AST_STRING_FIELD(host);
00559 
00560       AST_STRING_FIELD(dproot);
00561       AST_STRING_FIELD(accountcode);
00562       AST_STRING_FIELD(mohinterpret);
00563       AST_STRING_FIELD(mohsuggest);
00564    );
00565    
00566    /*! permitted authentication methods */
00567    int authmethods;
00568    /*! permitted encryption methods */
00569    int encmethods;
00570    /*! Encryption AES-128 Key */
00571    aes_encrypt_ctx ecx;
00572    /*! Decryption AES-128 Key */
00573    aes_decrypt_ctx dcx;
00574    /*! 32 bytes of semi-random data */
00575    unsigned char semirand[32];
00576    /*! Associated registry */
00577    struct iax2_registry *reg;
00578    /*! Associated peer for poking */
00579    struct iax2_peer *peerpoke;
00580    /*! IAX_ flags */
00581    unsigned int flags;
00582    int adsi;
00583 
00584    /*! Transferring status */
00585    enum iax_transfer_state transferring;
00586    /*! Transfer identifier */
00587    int transferid;
00588    /*! Who we are IAX transfering to */
00589    struct sockaddr_in transfer;
00590    /*! What's the new call number for the transfer */
00591    unsigned short transfercallno;
00592    /*! Transfer decrypt AES-128 Key */
00593    aes_encrypt_ctx tdcx;
00594 
00595    /*! Status of knowledge of peer ADSI capability */
00596    int peeradsicpe;
00597 
00598    /*! Who we are bridged to */
00599    unsigned short bridgecallno;
00600    
00601    int pingid;       /*!< Transmit PING request */
00602    int lagid;        /*!< Retransmit lag request */
00603    int autoid;       /*!< Auto hangup for Dialplan requestor */
00604    int authid;       /*!< Authentication rejection ID */
00605    int authfail;        /*!< Reason to report failure */
00606    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00607    int calling_ton;
00608    int calling_tns;
00609    int calling_pres;
00610    int amaflags;
00611    struct iax2_dpcache *dpentries;
00612    struct ast_variable *vars;
00613    /*! last received remote rr */
00614    struct iax_rr remote_rr;
00615    /*! Current base time: (just for stats) */
00616    int min;
00617    /*! Dropped frame count: (just for stats) */
00618    int frames_dropped;
00619    /*! received frame count: (just for stats) */
00620    int frames_received;
00621 };
00622 
00623 static struct ast_iax2_queue {
00624    AST_LIST_HEAD(, iax_frame) queue;
00625    int count;
00626 } iaxq;
00627 
00628 static AST_LIST_HEAD_STATIC(users, iax2_user);
00629 
00630 static AST_LIST_HEAD_STATIC(peers, iax2_peer);
00631 
00632 static struct ast_firmware_list {
00633    struct iax_firmware *wares;
00634    ast_mutex_t lock;
00635 } waresl;
00636 
00637 /*! Extension exists */
00638 #define CACHE_FLAG_EXISTS     (1 << 0)
00639 /*! Extension is nonexistent */
00640 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00641 /*! Extension can exist */
00642 #define CACHE_FLAG_CANEXIST      (1 << 2)
00643 /*! Waiting to hear back response */
00644 #define CACHE_FLAG_PENDING    (1 << 3)
00645 /*! Timed out */
00646 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00647 /*! Request transmitted */
00648 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00649 /*! Timeout */
00650 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00651 /*! Matchmore */
00652 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00653 
00654 static struct iax2_dpcache {
00655    char peercontext[AST_MAX_CONTEXT];
00656    char exten[AST_MAX_EXTENSION];
00657    struct timeval orig;
00658    struct timeval expiry;
00659    int flags;
00660    unsigned short callno;
00661    int waiters[256];
00662    struct iax2_dpcache *next;
00663    struct iax2_dpcache *peer; /*!< For linking in peers */
00664 } *dpcache;
00665 
00666 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00667 
00668 static void reg_source_db(struct iax2_peer *p);
00669 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00670 
00671 static void destroy_peer(struct iax2_peer *peer);
00672 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00673 
00674 #define IAX_IOSTATE_IDLE      0
00675 #define IAX_IOSTATE_READY     1
00676 #define IAX_IOSTATE_PROCESSING   2
00677 #define IAX_IOSTATE_SCHEDREADY   3
00678 
00679 #define IAX_TYPE_POOL    1
00680 #define IAX_TYPE_DYNAMIC 2
00681 
00682 struct iax2_thread {
00683    AST_LIST_ENTRY(iax2_thread) list;
00684    int type;
00685    int iostate;
00686 #ifdef SCHED_MULTITHREADED
00687    void (*schedfunc)(void *);
00688    void *scheddata;
00689 #endif
00690 #ifdef DEBUG_SCHED_MULTITHREAD
00691    char curfunc[80];
00692 #endif   
00693    int actions;
00694    pthread_t threadid;
00695    int threadnum;
00696    struct sockaddr_in iosin;
00697    unsigned char buf[4096]; 
00698    int iores;
00699    int iofd;
00700    time_t checktime;
00701    ast_mutex_t lock;
00702    ast_cond_t cond;
00703 };
00704 
00705 /* Thread lists */
00706 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00707 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00708 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00709 
00710 static void *iax2_process_thread(void *data);
00711 
00712 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00713 {
00714    ast_mutex_lock(lock);
00715    ast_cond_signal(cond);
00716    ast_mutex_unlock(lock);
00717 }
00718 
00719 static void iax_debug_output(const char *data)
00720 {
00721    if (iaxdebug)
00722       ast_verbose("%s", data);
00723 }
00724 
00725 static void iax_error_output(const char *data)
00726 {
00727    ast_log(LOG_WARNING, "%s", data);
00728 }
00729 
00730 static void jb_error_output(const char *fmt, ...)
00731 {
00732    va_list args;
00733    char buf[1024];
00734 
00735    va_start(args, fmt);
00736    vsnprintf(buf, 1024, fmt, args);
00737    va_end(args);
00738 
00739    ast_log(LOG_ERROR, buf);
00740 }
00741 
00742 static void jb_warning_output(const char *fmt, ...)
00743 {
00744    va_list args;
00745    char buf[1024];
00746 
00747    va_start(args, fmt);
00748    vsnprintf(buf, 1024, fmt, args);
00749    va_end(args);
00750 
00751    ast_log(LOG_WARNING, buf);
00752 }
00753 
00754 static void jb_debug_output(const char *fmt, ...)
00755 {
00756    va_list args;
00757    char buf[1024];
00758 
00759    va_start(args, fmt);
00760    vsnprintf(buf, 1024, fmt, args);
00761    va_end(args);
00762 
00763    ast_verbose(buf);
00764 }
00765 
00766 /* XXX We probably should use a mutex when working with this XXX */
00767 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00768 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
00769 static struct timeval lastused[IAX_MAX_CALLS];
00770 
00771 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);
00772 static int expire_registry(void *data);
00773 static int iax2_answer(struct ast_channel *c);
00774 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00775 static int iax2_devicestate(void *data);
00776 static int iax2_digit_begin(struct ast_channel *c, char digit);
00777 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00778 static int iax2_do_register(struct iax2_registry *reg);
00779 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00780 static int iax2_hangup(struct ast_channel *c);
00781 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00782 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00783 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00784 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00785 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00786 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00787 static int iax2_sendtext(struct ast_channel *c, const char *text);
00788 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00789 static int iax2_transfer(struct ast_channel *c, const char *dest);
00790 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00791 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00792 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00793 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00794 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00795 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00796 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00797 static struct ast_frame *iax2_read(struct ast_channel *c);
00798 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00799 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00800 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00801 static void destroy_user(struct iax2_user *user);
00802 static void prune_peers(void);
00803 
00804 static const struct ast_channel_tech iax2_tech = {
00805    .type = "IAX2",
00806    .description = tdesc,
00807    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00808    .properties = AST_CHAN_TP_WANTSJITTER,
00809    .requester = iax2_request,
00810    .devicestate = iax2_devicestate,
00811    .send_digit_begin = iax2_digit_begin,
00812    .send_digit_end = iax2_digit_end,
00813    .send_text = iax2_sendtext,
00814    .send_image = iax2_sendimage,
00815    .send_html = iax2_sendhtml,
00816    .call = iax2_call,
00817    .hangup = iax2_hangup,
00818    .answer = iax2_answer,
00819    .read = iax2_read,
00820    .write = iax2_write,
00821    .write_video = iax2_write,
00822    .indicate = iax2_indicate,
00823    .setoption = iax2_setoption,
00824    .bridge = iax2_bridge,
00825    .transfer = iax2_transfer,
00826    .fixup = iax2_fixup,
00827 };
00828 
00829 static void insert_idle_thread(struct iax2_thread *thread)
00830 {
00831    if (thread->type == IAX_TYPE_DYNAMIC) {
00832       AST_LIST_LOCK(&dynamic_list);
00833       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00834       AST_LIST_UNLOCK(&dynamic_list);
00835    } else {
00836       AST_LIST_LOCK(&idle_list);
00837       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00838       AST_LIST_UNLOCK(&idle_list);
00839    }
00840 
00841    return;
00842 }
00843 
00844 static struct iax2_thread *find_idle_thread(void)
00845 {
00846    pthread_attr_t attr;
00847    struct iax2_thread *thread = NULL;
00848 
00849    /* Pop the head of the list off */
00850    AST_LIST_LOCK(&idle_list);
00851    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00852    AST_LIST_UNLOCK(&idle_list);
00853 
00854    /* If no idle thread is available from the regular list, try dynamic */
00855    if (thread == NULL) {
00856       AST_LIST_LOCK(&dynamic_list);
00857       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00858       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00859       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00860          /* We need to MAKE a thread! */
00861          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00862             thread->threadnum = iaxdynamicthreadcount;
00863             thread->type = IAX_TYPE_DYNAMIC;
00864             ast_mutex_init(&thread->lock);
00865             ast_cond_init(&thread->cond, NULL);
00866             pthread_attr_init(&attr);
00867             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00868             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00869                free(thread);
00870                thread = NULL;
00871             } else {
00872                /* All went well and the thread is up, so increment our count */
00873                iaxdynamicthreadcount++;
00874             }
00875          }
00876       }
00877       AST_LIST_UNLOCK(&dynamic_list);
00878    }
00879 
00880    return thread;
00881 }
00882 
00883 #ifdef SCHED_MULTITHREADED
00884 static int __schedule_action(void (*func)(void *data), void *data, const char *funcname)
00885 {
00886    struct iax2_thread *thread = NULL;
00887    static time_t lasterror;
00888    static time_t t;
00889 
00890    thread = find_idle_thread();
00891 
00892    if (thread != NULL) {
00893       thread->schedfunc = func;
00894       thread->scheddata = data;
00895       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00896 #ifdef DEBUG_SCHED_MULTITHREAD
00897       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00898 #endif
00899       signal_condition(&thread->lock, &thread->cond);
00900       return 0;
00901    }
00902    time(&t);
00903    if (t != lasterror) 
00904       ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
00905    lasterror = t;
00906 
00907    return -1;
00908 }
00909 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00910 #endif
00911 
00912 static int send_ping(void *data);
00913 
00914 static void __send_ping(void *data)
00915 {
00916    int callno = (long)data;
00917    ast_mutex_lock(&iaxsl[callno]);
00918    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00919       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00920       iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data);
00921    }
00922    ast_mutex_unlock(&iaxsl[callno]);
00923 }
00924 
00925 static int send_ping(void *data)
00926 {
00927 #ifdef SCHED_MULTITHREADED
00928    if (schedule_action(__send_ping, data))
00929 #endif      
00930       __send_ping(data);
00931    return 0;
00932 }
00933 
00934 static int get_encrypt_methods(const char *s)
00935 {
00936    int e;
00937    if (!strcasecmp(s, "aes128"))
00938       e = IAX_ENCRYPT_AES128;
00939    else if (ast_true(s))
00940       e = IAX_ENCRYPT_AES128;
00941    else
00942       e = 0;
00943    return e;
00944 }
00945 
00946 static int send_lagrq(void *data);
00947 
00948 static void __send_lagrq(void *data)
00949 {
00950    int callno = (long)data;
00951    /* Ping only if it's real not if it's bridged */
00952    ast_mutex_lock(&iaxsl[callno]);
00953    if (iaxs[callno] && iaxs[callno]->lagid != -1) {
00954       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
00955       iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
00956    }
00957    ast_mutex_unlock(&iaxsl[callno]);
00958 }
00959 
00960 static int send_lagrq(void *data)
00961 {
00962 #ifdef SCHED_MULTITHREADED
00963    if (schedule_action(__send_lagrq, data))
00964 #endif      
00965       __send_lagrq(data);
00966    return 0;
00967 }
00968 
00969 static unsigned char compress_subclass(int subclass)
00970 {
00971    int x;
00972    int power=-1;
00973    /* If it's 128 or smaller, just return it */
00974    if (subclass < IAX_FLAG_SC_LOG)
00975       return subclass;
00976    /* Otherwise find its power */
00977    for (x = 0; x < IAX_MAX_SHIFT; x++) {
00978       if (subclass & (1 << x)) {
00979          if (power > -1) {
00980             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
00981             return 0;
00982          } else
00983             power = x;
00984       }
00985    }
00986    return power | IAX_FLAG_SC_LOG;
00987 }
00988 
00989 static int uncompress_subclass(unsigned char csub)
00990 {
00991    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
00992    if (csub & IAX_FLAG_SC_LOG) {
00993       /* special case for 'compressed' -1 */
00994       if (csub == 0xff)
00995          return -1;
00996       else
00997          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
00998    }
00999    else
01000       return csub;
01001 }
01002 
01003 static struct iax2_peer *find_peer(const char *name, int realtime) 
01004 {
01005    struct iax2_peer *peer = NULL;
01006 
01007    /* Grab peer from linked list */
01008    AST_LIST_LOCK(&peers);
01009    AST_LIST_TRAVERSE(&peers, peer, entry) {
01010       if (!strcasecmp(peer->name, name)) {
01011          break;
01012       }
01013    }
01014    AST_LIST_UNLOCK(&peers);
01015 
01016    /* Now go for realtime if applicable */
01017    if(!peer && realtime)
01018       peer = realtime_peer(name, NULL);
01019    return peer;
01020 }
01021 
01022 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len, int lockpeer)
01023 {
01024    struct iax2_peer *peer = NULL;
01025    int res = 0;
01026 
01027    if (lockpeer)
01028       AST_LIST_LOCK(&peers);
01029    AST_LIST_TRAVERSE(&peers, peer, entry) {
01030       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01031           (peer->addr.sin_port == sin.sin_port)) {
01032          ast_copy_string(host, peer->name, len);
01033          res = 1;
01034          break;
01035       }
01036    }
01037    if (lockpeer)
01038       AST_LIST_UNLOCK(&peers);
01039    if (!peer) {
01040       peer = realtime_peer(NULL, &sin);
01041       if (peer) {
01042          ast_copy_string(host, peer->name, len);
01043          if (ast_test_flag(peer, IAX_TEMPONLY))
01044             destroy_peer(peer);
01045          res = 1;
01046       }
01047    }
01048 
01049    return res;
01050 }
01051 
01052 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, const char *host)
01053 {
01054    struct chan_iax2_pvt *tmp;
01055    jb_conf jbconf;
01056 
01057    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01058       return NULL;
01059 
01060    if (ast_string_field_init(tmp, 32)) {
01061       free(tmp);
01062       tmp = NULL;
01063       return NULL;
01064    }
01065       
01066    tmp->prefs = prefs;
01067    tmp->callno = 0;
01068    tmp->peercallno = 0;
01069    tmp->transfercallno = 0;
01070    tmp->bridgecallno = 0;
01071    tmp->pingid = -1;
01072    tmp->lagid = -1;
01073    tmp->autoid = -1;
01074    tmp->authid = -1;
01075    tmp->initid = -1;
01076 
01077    ast_string_field_set(tmp,exten, "s");
01078    ast_string_field_set(tmp,host, host);
01079 
01080    tmp->jb = jb_new();
01081    tmp->jbid = -1;
01082    jbconf.max_jitterbuf = maxjitterbuffer;
01083    jbconf.resync_threshold = resyncthreshold;
01084    jbconf.max_contig_interp = maxjitterinterps;
01085    jb_setconf(tmp->jb,&jbconf);
01086 
01087    return tmp;
01088 }
01089 
01090 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01091 {
01092    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01093    if (new) {
01094       size_t mallocd_datalen = new->mallocd_datalen;
01095       memcpy(new, fr, sizeof(*new));
01096       iax_frame_wrap(new, &fr->af);
01097       new->mallocd_datalen = mallocd_datalen;
01098       new->data = NULL;
01099       new->datalen = 0;
01100       new->direction = DIRECTION_INGRESS;
01101       new->retrans = -1;
01102    }
01103    return new;
01104 }
01105 
01106 #define NEW_PREVENT  0
01107 #define NEW_ALLOW    1
01108 #define NEW_FORCE    2
01109 
01110 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
01111 {
01112    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01113       (cur->addr.sin_port == sin->sin_port)) {
01114       /* This is the main host */
01115       if ((cur->peercallno == callno) ||
01116          ((dcallno == cur->callno) && !cur->peercallno)) {
01117          /* That's us.  Be sure we keep track of the peer call number */
01118          return 1;
01119       }
01120    }
01121    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01122        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01123       /* We're transferring */
01124       if (dcallno == cur->callno)
01125          return 1;
01126    }
01127    return 0;
01128 }
01129 
01130 static void update_max_trunk(void)
01131 {
01132    int max = TRUNK_CALL_START;
01133    int x;
01134    /* XXX Prolly don't need locks here XXX */
01135    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01136       if (iaxs[x])
01137          max = x + 1;
01138    }
01139    maxtrunkcall = max;
01140    if (option_debug && iaxdebug)
01141       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01142 }
01143 
01144 static void update_max_nontrunk(void)
01145 {
01146    int max = 1;
01147    int x;
01148    /* XXX Prolly don't need locks here XXX */
01149    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01150       if (iaxs[x])
01151          max = x + 1;
01152    }
01153    maxnontrunkcall = max;
01154    if (option_debug && iaxdebug)
01155       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01156 }
01157 
01158 static int make_trunk(unsigned short callno, int locked)
01159 {
01160    int x;
01161    int res= 0;
01162    struct timeval now;
01163    if (iaxs[callno]->oseqno) {
01164       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01165       return -1;
01166    }
01167    if (callno & TRUNK_CALL_START) {
01168       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01169       return -1;
01170    }
01171    gettimeofday(&now, NULL);
01172    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01173       ast_mutex_lock(&iaxsl[x]);
01174       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01175          iaxs[x] = iaxs[callno];
01176          iaxs[x]->callno = x;
01177          iaxs[callno] = NULL;
01178          /* Update the two timers that should have been started */
01179          if (iaxs[x]->pingid > -1)
01180             ast_sched_del(sched, iaxs[x]->pingid);
01181          if (iaxs[x]->lagid > -1)
01182             ast_sched_del(sched, iaxs[x]->lagid);
01183          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01184          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01185          if (locked)
01186             ast_mutex_unlock(&iaxsl[callno]);
01187          res = x;
01188          if (!locked)
01189             ast_mutex_unlock(&iaxsl[x]);
01190          break;
01191       }
01192       ast_mutex_unlock(&iaxsl[x]);
01193    }
01194    if (x >= IAX_MAX_CALLS - 1) {
01195       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01196       return -1;
01197    }
01198    ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01199    /* We move this call from a non-trunked to a trunked call */
01200    update_max_trunk();
01201    update_max_nontrunk();
01202    return res;
01203 }
01204 
01205 /*!
01206  * \todo XXX Note that this function contains a very expensive operation that
01207  * happens for *every* incoming media frame.  It iterates through every
01208  * possible call number, locking and unlocking each one, to try to match the
01209  * incoming frame to an active call.  Call numbers can be up to 2^15, 32768.
01210  * So, for an call with a local call number of 20000, every incoming audio
01211  * frame would require 20000 mutex lock and unlock operations.  Ouch.
01212  *
01213  * It's a shame that IAX2 media frames carry the source call number instead of
01214  * the destination call number.  If they did, this lookup wouldn't be needed.
01215  * However, it's too late to change that now.  Instead, we need to come up with
01216  * a better way of indexing active calls so that these frequent lookups are not
01217  * so expensive.
01218  */
01219 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
01220 {
01221    int res = 0;
01222    int x;
01223    struct timeval now;
01224    char host[80];
01225    if (new <= NEW_ALLOW) {
01226       /* Look for an existing connection first */
01227       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01228          ast_mutex_lock(&iaxsl[x]);
01229          if (iaxs[x]) {
01230             /* Look for an exact match */
01231             if (match(sin, callno, dcallno, iaxs[x])) {
01232                res = x;
01233             }
01234          }
01235          ast_mutex_unlock(&iaxsl[x]);
01236       }
01237       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01238          ast_mutex_lock(&iaxsl[x]);
01239          if (iaxs[x]) {
01240             /* Look for an exact match */
01241             if (match(sin, callno, dcallno, iaxs[x])) {
01242                res = x;
01243             }
01244          }
01245          ast_mutex_unlock(&iaxsl[x]);
01246       }
01247    }
01248    if ((res < 1) && (new >= NEW_ALLOW)) {
01249       /* It may seem odd that we look through the peer list for a name for
01250        * this *incoming* call.  Well, it is weird.  However, users don't
01251        * have an IP address/port number that we can match against.  So,
01252        * this is just checking for a peer that has that IP/port and
01253        * assuming that we have a user of the same name.  This isn't always
01254        * correct, but it will be changed if needed after authentication. */
01255       if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer))
01256          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01257       gettimeofday(&now, NULL);
01258       for (x=1;x<TRUNK_CALL_START;x++) {
01259          /* Find first unused call number that hasn't been used in a while */
01260          ast_mutex_lock(&iaxsl[x]);
01261          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01262          ast_mutex_unlock(&iaxsl[x]);
01263       }
01264       /* We've still got lock held if we found a spot */
01265       if (x >= TRUNK_CALL_START) {
01266          ast_log(LOG_WARNING, "No more space\n");
01267          return 0;
01268       }
01269       iaxs[x] = new_iax(sin, lockpeer, host);
01270       update_max_nontrunk();
01271       if (iaxs[x]) {
01272          if (option_debug && iaxdebug)
01273             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01274          iaxs[x]->sockfd = sockfd;
01275          iaxs[x]->addr.sin_port = sin->sin_port;
01276          iaxs[x]->addr.sin_family = sin->sin_family;
01277          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01278          iaxs[x]->peercallno = callno;
01279          iaxs[x]->callno = x;
01280          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01281          iaxs[x]->expiry = min_reg_expire;
01282          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01283          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01284          iaxs[x]->amaflags = amaflags;
01285          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01286          
01287          ast_string_field_set(iaxs[x], accountcode, accountcode);
01288          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01289          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01290       } else {
01291          ast_log(LOG_WARNING, "Out of resources\n");
01292          ast_mutex_unlock(&iaxsl[x]);
01293          return 0;
01294       }
01295       ast_mutex_unlock(&iaxsl[x]);
01296       res = x;
01297    }
01298    return res;
01299 }
01300 
01301 static void iax2_frame_free(struct iax_frame *fr)
01302 {
01303    if (fr->retrans > -1)
01304       ast_sched_del(sched, fr->retrans);
01305    iax_frame_free(fr);
01306 }
01307 
01308 static int iax2_queue_frame(int callno, struct ast_frame *f)
01309 {
01310    /* Assumes lock for callno is already held... */
01311    for (;;) {
01312       if (iaxs[callno] && iaxs[callno]->owner) {
01313          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01314             /* Avoid deadlock by pausing and trying again */
01315             ast_mutex_unlock(&iaxsl[callno]);
01316             usleep(1);
01317             ast_mutex_lock(&iaxsl[callno]);
01318          } else {
01319             ast_queue_frame(iaxs[callno]->owner, f);
01320             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01321             break;
01322          }
01323       } else
01324          break;
01325    }
01326    return 0;
01327 }
01328 
01329 static void destroy_firmware(struct iax_firmware *cur)
01330 {
01331    /* Close firmware */
01332    if (cur->fwh) {
01333       munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01334    }
01335    close(cur->fd);
01336    free(cur);
01337 }
01338 
01339 static int try_firmware(char *s)
01340 {
01341    struct stat stbuf;
01342    struct iax_firmware *cur;
01343    int ifd;
01344    int fd;
01345    int res;
01346    
01347    struct ast_iax2_firmware_header *fwh, fwh2;
01348    struct MD5Context md5;
01349    unsigned char sum[16];
01350    unsigned char buf[1024];
01351    int len, chunk;
01352    char *s2;
01353    char *last;
01354    s2 = alloca(strlen(s) + 100);
01355    if (!s2) {
01356       ast_log(LOG_WARNING, "Alloca failed!\n");
01357       return -1;
01358    }
01359    last = strrchr(s, '/');
01360    if (last)
01361       last++;
01362    else
01363       last = s;
01364    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01365    res = stat(s, &stbuf);
01366    if (res < 0) {
01367       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01368       return -1;
01369    }
01370    /* Make sure it's not a directory */
01371    if (S_ISDIR(stbuf.st_mode))
01372       return -1;
01373    ifd = open(s, O_RDONLY);
01374    if (ifd < 0) {
01375       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01376       return -1;
01377    }
01378    fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
01379    if (fd < 0) {
01380       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01381       close(ifd);
01382       return -1;
01383    }
01384    /* Unlink our newly created file */
01385    unlink(s2);
01386    
01387    /* Now copy the firmware into it */
01388    len = stbuf.st_size;
01389    while(len) {
01390       chunk = len;
01391       if (chunk > sizeof(buf))
01392          chunk = sizeof(buf);
01393       res = read(ifd, buf, chunk);
01394       if (res != chunk) {
01395          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01396          close(ifd);
01397          close(fd);
01398          return -1;
01399       }
01400       res = write(fd, buf, chunk);
01401       if (res != chunk) {
01402          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01403          close(ifd);
01404          close(fd);
01405          return -1;
01406       }
01407       len -= chunk;
01408    }
01409    close(ifd);
01410    /* Return to the beginning */
01411    lseek(fd, 0, SEEK_SET);
01412    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01413       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01414       close(fd);
01415       return -1;
01416    }
01417    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01418       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01419       close(fd);
01420       return -1;
01421    }
01422    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01423       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01424       close(fd);
01425       return -1;
01426    }
01427    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01428       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01429       close(fd);
01430       return -1;
01431    }
01432    fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01433    if (fwh == (void *) -1) {
01434       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01435       close(fd);
01436       return -1;
01437    }
01438    MD5Init(&md5);
01439    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01440    MD5Final(sum, &md5);
01441    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01442       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01443       munmap(fwh, stbuf.st_size);
01444       close(fd);
01445       return -1;
01446    }
01447    cur = waresl.wares;
01448    while(cur) {
01449       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01450          /* Found a candidate */
01451          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01452             /* The version we have on loaded is older, load this one instead */
01453             break;
01454          /* This version is no newer than what we have.  Don't worry about it.
01455             We'll consider it a proper load anyhow though */
01456          munmap(fwh, stbuf.st_size);
01457          close(fd);
01458          return 0;
01459       }
01460       cur = cur->next;
01461    }
01462    if (!cur) {
01463       /* Allocate a new one and link it */
01464       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01465          cur->fd = -1;
01466          cur->next = waresl.wares;
01467          waresl.wares = cur;
01468       }
01469    }
01470    if (cur) {
01471       if (cur->fwh) {
01472          munmap(cur->fwh, cur->mmaplen);
01473       }
01474       if (cur->fd > -1)
01475          close(cur->fd);
01476       cur->fwh = fwh;
01477       cur->fd = fd;
01478       cur->mmaplen = stbuf.st_size;
01479       cur->dead = 0;
01480    }
01481    return 0;
01482 }
01483 
01484 static int iax_check_version(char *dev)
01485 {
01486    int res = 0;
01487    struct iax_firmware *cur;
01488    if (!ast_strlen_zero(dev)) {
01489       ast_mutex_lock(&waresl.lock);
01490       cur = waresl.wares;
01491       while(cur) {
01492          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01493             res = ntohs(cur->fwh->version);
01494             break;
01495          }
01496          cur = cur->next;
01497       }
01498       ast_mutex_unlock(&waresl.lock);
01499    }
01500    return res;
01501 }
01502 
01503 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01504 {
01505    int res = -1;
01506    unsigned int bs = desc & 0xff;
01507    unsigned int start = (desc >> 8) & 0xffffff;
01508    unsigned int bytes;
01509    struct iax_firmware *cur;
01510    if (!ast_strlen_zero((char *)dev) && bs) {
01511       start *= bs;
01512       ast_mutex_lock(&waresl.lock);
01513       cur = waresl.wares;
01514       while(cur) {
01515          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01516             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01517             if (start < ntohl(cur->fwh->datalen)) {
01518                bytes = ntohl(cur->fwh->datalen) - start;
01519                if (bytes > bs)
01520                   bytes = bs;
01521                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01522             } else {
01523                bytes = 0;
01524                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01525             }
01526             if (bytes == bs)
01527                res = 0;
01528             else
01529                res = 1;
01530             break;
01531          }
01532          cur = cur->next;
01533       }
01534       ast_mutex_unlock(&waresl.lock);
01535    }
01536    return res;
01537 }
01538 
01539 
01540 static void reload_firmware(void)
01541 {
01542    struct iax_firmware *cur, *curl, *curp;
01543    DIR *fwd;
01544    struct dirent *de;
01545    char dir[256];
01546    char fn[256];
01547    /* Mark all as dead */
01548    ast_mutex_lock(&waresl.lock);
01549    cur = waresl.wares;
01550    while(cur) {
01551       cur->dead = 1;
01552       cur = cur->next;
01553    }
01554    /* Now that we've freed them, load the new ones */
01555    snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01556    fwd = opendir(dir);
01557    if (fwd) {
01558       while((de = readdir(fwd))) {
01559          if (de->d_name[0] != '.') {
01560             snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01561             if (!try_firmware(fn)) {
01562                if (option_verbose > 1)
01563                   ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01564             }
01565          }
01566       }
01567       closedir(fwd);
01568    } else 
01569       ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01570 
01571    /* Clean up leftovers */
01572    cur = waresl.wares;
01573    curp = NULL;
01574    while(cur) {
01575       curl = cur;
01576       cur = cur->next;
01577       if (curl->dead) {
01578          if (curp) {
01579             curp->next = cur;
01580          } else {
01581             waresl.wares = cur;
01582          }
01583          destroy_firmware(curl);
01584       } else {
01585          curp = cur;
01586       }
01587    }
01588    ast_mutex_unlock(&waresl.lock);
01589 }
01590 
01591 static int __do_deliver(void *data)
01592 {
01593    /* Just deliver the packet by using queueing.  This is called by
01594      the IAX thread with the iaxsl lock held. */
01595    struct iax_frame *fr = data;
01596    fr->retrans = -1;
01597    fr->af.has_timing_info = 0;
01598    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01599       iax2_queue_frame(fr->callno, &fr->af);
01600    /* Free our iax frame */
01601    iax2_frame_free(fr);
01602    /* And don't run again */
01603    return 0;
01604 }
01605 
01606 static int handle_error(void)
01607 {
01608    /* XXX Ideally we should figure out why an error occured and then abort those
01609       rather than continuing to try.  Unfortunately, the published interface does
01610       not seem to work XXX */
01611 #if 0
01612    struct sockaddr_in *sin;
01613    int res;
01614    struct msghdr m;
01615    struct sock_extended_err e;
01616    m.msg_name = NULL;
01617    m.msg_namelen = 0;
01618    m.msg_iov = NULL;
01619    m.msg_control = &e;
01620    m.msg_controllen = sizeof(e);
01621    m.msg_flags = 0;
01622    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01623    if (res < 0)
01624       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01625    else {
01626       if (m.msg_controllen) {
01627          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01628          if (sin) 
01629             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
01630          else
01631             ast_log(LOG_WARNING, "No address detected??\n");
01632       } else {
01633          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01634       }
01635    }
01636 #endif
01637    return 0;
01638 }
01639 
01640 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
01641 {
01642    int res;
01643    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01644                sizeof(*sin));
01645    if (res < 0) {
01646       if (option_debug)
01647          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01648       handle_error();
01649    } else
01650       res = 0;
01651    return res;
01652 }
01653 
01654 static int send_packet(struct iax_frame *f)
01655 {
01656    int res;
01657    int callno;
01658 
01659    if( f == NULL ) {
01660        ast_log(LOG_ERROR, "send_packet( NULL )\n");
01661        ast_backtrace();
01662        return -1;
01663    }
01664    
01665    callno = f->callno;
01666 
01667    /* Don't send if there was an error, but return error instead */
01668    if (!callno || !iaxs[callno] || iaxs[callno]->error)
01669        return -1;
01670    
01671    /* Called with iaxsl held */
01672    if (option_debug > 2 && iaxdebug)
01673       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));
01674    if (f->transfer) {
01675       if (iaxdebug)
01676          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01677       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
01678                sizeof(iaxs[callno]->transfer));
01679    } else {
01680       if (iaxdebug)
01681          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01682       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
01683                sizeof(iaxs[callno]->addr));
01684    }
01685    if (res < 0) {
01686       if (option_debug && iaxdebug)
01687          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01688       handle_error();
01689    } else
01690       res = 0;
01691    return res;
01692 }
01693 
01694 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01695 {
01696    struct iax2_user *user = NULL;
01697 
01698    /* Decrement AUTHREQ count if needed */
01699    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01700       AST_LIST_LOCK(&users);
01701       AST_LIST_TRAVERSE(&users, user, entry) {
01702          if (!strcmp(user->name, pvt->username)) {
01703             user->curauthreq--;
01704             break;
01705          }
01706       }
01707       AST_LIST_UNLOCK(&users);
01708       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01709    }
01710    /* No more pings or lagrq's */
01711    if (pvt->pingid > -1)
01712       ast_sched_del(sched, pvt->pingid);
01713    pvt->pingid = -1;
01714    if (pvt->lagid > -1)
01715       ast_sched_del(sched, pvt->lagid);
01716    pvt->lagid = -1;
01717    if (pvt->autoid > -1)
01718       ast_sched_del(sched, pvt->autoid);
01719    pvt->autoid = -1;
01720    if (pvt->authid > -1)
01721       ast_sched_del(sched, pvt->authid);
01722    pvt->authid = -1;
01723    if (pvt->initid > -1)
01724       ast_sched_del(sched, pvt->initid);
01725    pvt->initid = -1;
01726    if (pvt->jbid > -1)
01727       ast_sched_del(sched, pvt->jbid);
01728    pvt->jbid = -1;
01729 }
01730 
01731 static int iax2_predestroy(int callno)
01732 {
01733    struct ast_channel *c;
01734    struct chan_iax2_pvt *pvt = iaxs[callno];
01735 
01736    if (!pvt)
01737       return -1;
01738    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01739       iax2_destroy_helper(pvt);
01740       ast_set_flag(pvt, IAX_ALREADYGONE); 
01741    }
01742    c = pvt->owner;
01743    if (c) {
01744       c->_softhangup |= AST_SOFTHANGUP_DEV;
01745       c->tech_pvt = NULL;
01746       ast_queue_hangup(c);
01747       pvt->owner = NULL;
01748       ast_module_unref(ast_module_info->self);
01749    }
01750    return 0;
01751 }
01752 
01753 static void iax2_destroy(int callno)
01754 {
01755    struct chan_iax2_pvt *pvt;
01756    struct iax_frame *cur;
01757    struct ast_channel *owner;
01758 
01759 retry:
01760    pvt = iaxs[callno];
01761    gettimeofday(&lastused[callno], NULL);
01762    
01763    owner = pvt ? pvt->owner : NULL;
01764 
01765    if (owner) {
01766       if (ast_mutex_trylock(&owner->lock)) {
01767          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01768          ast_mutex_unlock(&iaxsl[callno]);
01769          usleep(1);
01770          ast_mutex_lock(&iaxsl[callno]);
01771          goto retry;
01772       }
01773    }
01774    if (!owner)
01775       iaxs[callno] = NULL;
01776    if (pvt) {
01777       if (!owner)
01778          pvt->owner = NULL;
01779       iax2_destroy_helper(pvt);
01780 
01781       /* Already gone */
01782       ast_set_flag(pvt, IAX_ALREADYGONE); 
01783 
01784       if (owner) {
01785          /* If there's an owner, prod it to give up */
01786          owner->_softhangup |= AST_SOFTHANGUP_DEV;
01787          ast_queue_hangup(owner);
01788       }
01789 
01790       AST_LIST_LOCK(&iaxq.queue);
01791       AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01792          /* Cancel any pending transmissions */
01793          if (cur->callno == pvt->callno) 
01794             cur->retries = -1;
01795       }
01796       AST_LIST_UNLOCK(&iaxq.queue);
01797 
01798       if (pvt->reg)
01799          pvt->reg->callno = 0;
01800       if (!owner) {
01801          jb_frame frame;
01802          if (pvt->vars) {
01803              ast_variables_destroy(pvt->vars);
01804              pvt->vars = NULL;
01805          }
01806 
01807          while (jb_getall(pvt->jb, &frame) == JB_OK)
01808             iax2_frame_free(frame.data);
01809          jb_destroy(pvt->jb);
01810          /* gotta free up the stringfields */
01811          ast_string_field_free_pools(pvt);
01812          free(pvt);
01813       }
01814    }
01815    if (owner) {
01816       ast_mutex_unlock(&owner->lock);
01817    }
01818    if (callno & 0x4000)
01819       update_max_trunk();
01820 }
01821 
01822 static int update_packet(struct iax_frame *f)
01823 {
01824    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
01825    struct ast_iax2_full_hdr *fh = f->data;
01826    /* Mark this as a retransmission */
01827    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
01828    /* Update iseqno */
01829    f->iseqno = iaxs[f->callno]->iseqno;
01830    fh->iseqno = f->iseqno;
01831    return 0;
01832 }
01833 
01834 static int attempt_transmit(void *data);
01835 static void __attempt_transmit(void *data)
01836 {
01837    /* Attempt to transmit the frame to the remote peer...
01838       Called without iaxsl held. */
01839    struct iax_frame *f = data;
01840    int freeme=0;
01841    int callno = f->callno;
01842    /* Make sure this call is still active */
01843    if (callno) 
01844       ast_mutex_lock(&iaxsl[callno]);
01845    if (callno && iaxs[callno]) {
01846       if ((f->retries < 0) /* Already ACK'd */ ||
01847           (f->retries >= max_retries) /* Too many attempts */) {
01848             /* Record an error if we've transmitted too many times */
01849             if (f->retries >= max_retries) {
01850                if (f->transfer) {
01851                   /* Transfer timeout */
01852                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
01853                } else if (f->final) {
01854                   if (f->final) 
01855                      iax2_destroy(callno);
01856                } else {
01857                   if (iaxs[callno]->owner)
01858                      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);
01859                   iaxs[callno]->error = ETIMEDOUT;
01860                   if (iaxs[callno]->owner) {
01861                      struct ast_frame fr = { 0, };
01862                      /* Hangup the fd */
01863                      fr.frametype = AST_FRAME_CONTROL;
01864                      fr.subclass = AST_CONTROL_HANGUP;
01865                      iax2_queue_frame(callno, &fr);
01866                      /* Remember, owner could disappear */
01867                      if (iaxs[callno]->owner)
01868                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01869                   } else {
01870                      if (iaxs[callno]->reg) {
01871                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
01872                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
01873                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
01874                      }
01875                      iax2_destroy(callno);
01876                   }
01877                }
01878 
01879             }
01880             freeme++;
01881       } else {
01882          /* Update it if it needs it */
01883          update_packet(f);
01884          /* Attempt transmission */
01885          send_packet(f);
01886          f->retries++;
01887          /* Try again later after 10 times as long */
01888          f->retrytime *= 10;
01889          if (f->retrytime > MAX_RETRY_TIME)
01890             f->retrytime = MAX_RETRY_TIME;
01891          /* Transfer messages max out at one second */
01892          if (f->transfer && (f->retrytime > 1000))
01893             f->retrytime = 1000;
01894          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
01895       }
01896    } else {
01897       /* Make sure it gets freed */
01898       f->retries = -1;
01899       freeme++;
01900    }
01901    if (callno)
01902       ast_mutex_unlock(&iaxsl[callno]);
01903    /* Do not try again */
01904    if (freeme) {
01905       /* Don't attempt delivery, just remove it from the queue */
01906       AST_LIST_LOCK(&iaxq.queue);
01907       AST_LIST_REMOVE(&iaxq.queue, f, list);
01908       iaxq.count--;
01909       AST_LIST_UNLOCK(&iaxq.queue);
01910       f->retrans = -1;
01911       /* Free the IAX frame */
01912       iax2_frame_free(f);
01913    }
01914 }
01915 
01916 static int attempt_transmit(void *data)
01917 {
01918 #ifdef SCHED_MULTITHREADED
01919    if (schedule_action(__attempt_transmit, data))
01920 #endif      
01921       __attempt_transmit(data);
01922    return 0;
01923 }
01924 
01925 static int iax2_prune_realtime(int fd, int argc, char *argv[])
01926 {
01927    struct iax2_peer *peer;
01928 
01929    if (argc != 4)
01930         return RESULT_SHOWUSAGE;
01931    if (!strcmp(argv[3],"all")) {
01932       reload_config();
01933       ast_cli(fd, "OK cache is flushed.\n");
01934    } else if ((peer = find_peer(argv[3], 0))) {
01935       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
01936          ast_set_flag(peer, IAX_RTAUTOCLEAR);
01937          expire_registry((void*)peer->name);
01938          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
01939       } else {
01940          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
01941       }
01942    } else {
01943       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
01944    }
01945    
01946    return RESULT_SUCCESS;
01947 }
01948 
01949 static int iax2_test_losspct(int fd, int argc, char *argv[])
01950 {
01951        if (argc != 4)
01952                return RESULT_SHOWUSAGE;
01953 
01954        test_losspct = atoi(argv[3]);
01955 
01956        return RESULT_SUCCESS;
01957 }
01958 
01959 #ifdef IAXTESTS
01960 static int iax2_test_late(int fd, int argc, char *argv[])
01961 {
01962    if (argc != 4)
01963       return RESULT_SHOWUSAGE;
01964 
01965    test_late = atoi(argv[3]);
01966 
01967    return RESULT_SUCCESS;
01968 }
01969 
01970 static int iax2_test_resync(int fd, int argc, char *argv[])
01971 {
01972    if (argc != 4)
01973       return RESULT_SHOWUSAGE;
01974 
01975    test_resync = atoi(argv[3]);
01976 
01977    return RESULT_SUCCESS;
01978 }
01979 
01980 static int iax2_test_jitter(int fd, int argc, char *argv[])
01981 {
01982    if (argc < 4 || argc > 5)
01983       return RESULT_SHOWUSAGE;
01984 
01985    test_jit = atoi(argv[3]);
01986    if (argc == 5) 
01987       test_jitpct = atoi(argv[4]);
01988 
01989    return RESULT_SUCCESS;
01990 }
01991 #endif /* IAXTESTS */
01992 
01993 /*! \brief  peer_status: Report Peer status in character string */
01994 /*    returns 1 if peer is online, -1 if unmonitored */
01995 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
01996 {
01997    int res = 0;
01998    if (peer->maxms) {
01999       if (peer->lastms < 0) {
02000          ast_copy_string(status, "UNREACHABLE", statuslen);
02001       } else if (peer->lastms > peer->maxms) {
02002          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02003          res = 1;
02004       } else if (peer->lastms) {
02005          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02006          res = 1;
02007       } else {
02008          ast_copy_string(status, "UNKNOWN", statuslen);
02009       }
02010    } else { 
02011       ast_copy_string(status, "Unmonitored", statuslen);
02012       res = -1;
02013    }
02014    return res;
02015 }
02016 
02017 /*! \brief Show one peer in detail */
02018 static int iax2_show_peer(int fd, int argc, char *argv[])
02019 {
02020    char status[30];
02021    char cbuf[256];
02022    struct iax2_peer *peer;
02023    char codec_buf[512];
02024    int x = 0, codec = 0, load_realtime = 0;
02025 
02026    if (argc < 4)
02027       return RESULT_SHOWUSAGE;
02028 
02029    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02030 
02031    peer = find_peer(argv[3], load_realtime);
02032    if (peer) {
02033       ast_cli(fd,"\n\n");
02034       ast_cli(fd, "  * Name       : %s\n", peer->name);
02035       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02036       ast_cli(fd, "  Context      : %s\n", peer->context);
02037       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02038       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02039       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02040       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02041       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02042       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));
02043       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02044       ast_cli(fd, "  Username     : %s\n", peer->username);
02045       ast_cli(fd, "  Codecs       : ");
02046       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02047       ast_cli(fd, "%s\n", codec_buf);
02048 
02049       ast_cli(fd, "  Codec Order  : (");
02050       for(x = 0; x < 32 ; x++) {
02051          codec = ast_codec_pref_index(&peer->prefs,x);
02052          if(!codec)
02053             break;
02054          ast_cli(fd, "%s", ast_getformatname(codec));
02055          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02056             ast_cli(fd, "|");
02057       }
02058 
02059       if (!x)
02060          ast_cli(fd, "none");
02061       ast_cli(fd, ")\n");
02062 
02063       ast_cli(fd, "  Status       : ");
02064       peer_status(peer, status, sizeof(status));   
02065       ast_cli(fd, "%s\n",status);
02066       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02067       ast_cli(fd,"\n");
02068       if (ast_test_flag(peer, IAX_TEMPONLY))
02069          destroy_peer(peer);
02070    } else {
02071       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02072       ast_cli(fd,"\n");
02073    }
02074 
02075    return RESULT_SUCCESS;
02076 }
02077 
02078 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02079 {
02080    int which = 0;
02081    struct iax2_peer *p = NULL;
02082    char *res = NULL;
02083    int wordlen = strlen(word);
02084 
02085    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02086    if (pos == 3) {
02087       AST_LIST_LOCK(&peers);
02088       AST_LIST_TRAVERSE(&peers, p, entry) {
02089          if (!strncasecmp(p->name, word, wordlen) && ++which > state) {
02090             res = ast_strdup(p->name);
02091             break;
02092          }
02093       }
02094       AST_LIST_UNLOCK(&peers);
02095    }
02096 
02097    return res;
02098 }
02099 
02100 static int iax2_show_stats(int fd, int argc, char *argv[])
02101 {
02102    struct iax_frame *cur;
02103    int cnt = 0, dead=0, final=0;
02104 
02105    if (argc != 3)
02106       return RESULT_SHOWUSAGE;
02107 
02108    AST_LIST_LOCK(&iaxq.queue);
02109    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02110       if (cur->retries < 0)
02111          dead++;
02112       if (cur->final)
02113          final++;
02114       cnt++;
02115    }
02116    AST_LIST_UNLOCK(&iaxq.queue);
02117 
02118    ast_cli(fd, "    IAX Statistics\n");
02119    ast_cli(fd, "---------------------\n");
02120    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02121    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02122    
02123    return RESULT_SUCCESS;
02124 }
02125 
02126 static int iax2_show_cache(int fd, int argc, char *argv[])
02127 {
02128    struct iax2_dpcache *dp;
02129    char tmp[1024], *pc;
02130    int s;
02131    int x,y;
02132    struct timeval tv;
02133    gettimeofday(&tv, NULL);
02134    ast_mutex_lock(&dpcache_lock);
02135    dp = dpcache;
02136    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02137    while(dp) {
02138       s = dp->expiry.tv_sec - tv.tv_sec;
02139       tmp[0] = '\0';
02140       if (dp->flags & CACHE_FLAG_EXISTS)
02141          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02142       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02143          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02144       if (dp->flags & CACHE_FLAG_CANEXIST)
02145          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02146       if (dp->flags & CACHE_FLAG_PENDING)
02147          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02148       if (dp->flags & CACHE_FLAG_TIMEOUT)
02149          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02150       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02151          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02152       if (dp->flags & CACHE_FLAG_MATCHMORE)
02153          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02154       if (dp->flags & CACHE_FLAG_UNKNOWN)
02155          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02156       /* Trim trailing pipe */
02157       if (!ast_strlen_zero(tmp))
02158          tmp[strlen(tmp) - 1] = '\0';
02159       else
02160          ast_copy_string(tmp, "(none)", sizeof(tmp));
02161       y=0;
02162       pc = strchr(dp->peercontext, '@');
02163       if (!pc)
02164          pc = dp->peercontext;
02165       else
02166          pc++;
02167       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02168          if (dp->waiters[x] > -1)
02169             y++;
02170       if (s > 0)
02171          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02172       else
02173          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02174       dp = dp->next;
02175    }
02176    ast_mutex_unlock(&dpcache_lock);
02177    return RESULT_SUCCESS;
02178 }
02179 
02180 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02181 
02182 static void unwrap_timestamp(struct iax_frame *fr)
02183 {
02184    int x;
02185 
02186    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02187       x = fr->ts - iaxs[fr->callno]->last;
02188       if (x < -50000) {
02189          /* Sudden big jump backwards in timestamp:
02190             What likely happened here is that miniframe timestamp has circled but we haven't
02191             gotten the update from the main packet.  We'll just pretend that we did, and
02192             update the timestamp appropriately. */
02193          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02194          if (option_debug && iaxdebug)
02195             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02196       }
02197       if (x > 50000) {
02198          /* Sudden apparent big jump forwards in timestamp:
02199             What's likely happened is this is an old miniframe belonging to the previous
02200             top-16-bit timestamp that has turned up out of order.
02201             Adjust the timestamp appropriately. */
02202          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02203          if (option_debug && iaxdebug)
02204             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02205       }
02206    }
02207 }
02208 
02209 static int get_from_jb(void *p);
02210 
02211 static void update_jbsched(struct chan_iax2_pvt *pvt)
02212 {
02213    int when;
02214    
02215    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02216    
02217    when = jb_next(pvt->jb) - when;
02218    
02219    if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02220    
02221    if(when <= 0) {
02222       /* XXX should really just empty until when > 0.. */
02223       when = 1;
02224    }
02225    
02226    pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02227    
02228    /* Signal scheduler thread */
02229    signal_condition(&sched_lock, &sched_cond);
02230 }
02231 
02232 static void __get_from_jb(void *p) 
02233 {
02234    int callno = PTR_TO_CALLNO(p);
02235    struct chan_iax2_pvt *pvt = NULL;
02236    struct iax_frame *fr;
02237    jb_frame frame;
02238    int ret;
02239    long now;
02240    long next;
02241    struct timeval tv;
02242    
02243    /* Make sure we have a valid private structure before going on */
02244    ast_mutex_lock(&iaxsl[callno]);
02245    pvt = iaxs[callno];
02246    if (!pvt) {
02247       /* No go! */
02248       ast_mutex_unlock(&iaxsl[callno]);
02249       return;
02250    }
02251     
02252     if( pvt->jb == NULL ) {
02253    ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" );
02254    ast_backtrace();
02255    return;
02256     }
02257 
02258    pvt->jbid = -1;
02259    
02260    gettimeofday(&tv,NULL);
02261    /* round up a millisecond since ast_sched_runq does; */
02262    /* prevents us from spinning while waiting for our now */
02263    /* to catch up with runq's now */
02264    tv.tv_usec += 1000;
02265    
02266    now = ast_tvdiff_ms(tv, pvt->rxcore);
02267    
02268    if(now >= (next = jb_next(pvt->jb))) {
02269       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02270       switch(ret) {
02271       case JB_OK:
02272          fr = frame.data;
02273          __do_deliver(fr);
02274          break;
02275       case JB_INTERP:
02276       {
02277          struct ast_frame af = { 0, };
02278          
02279          /* create an interpolation frame */
02280          af.frametype = AST_FRAME_VOICE;
02281          af.subclass = pvt->voiceformat;
02282          af.samples  = frame.ms * 8;
02283          af.src  = "IAX2 JB interpolation";
02284          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02285          af.offset = AST_FRIENDLY_OFFSET;
02286          
02287          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02288           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02289          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
02290             iax2_queue_frame(callno, &af);
02291       }
02292       break;
02293       case JB_DROP:
02294          iax2_frame_free(frame.data);
02295          break;
02296       case JB_NOFRAME:
02297       case JB_EMPTY:
02298          /* do nothing */
02299          break;
02300       default:
02301          /* shouldn't happen */
02302          break;
02303       }
02304    }
02305    update_jbsched(pvt);
02306    ast_mutex_unlock(&iaxsl[callno]);
02307 }
02308 
02309 static int get_from_jb(void *data)
02310 {
02311 #ifdef SCHED_MULTITHREADED
02312    if (schedule_action(__get_from_jb, data))
02313 #endif      
02314       __get_from_jb(data);
02315    return 0;
02316 }
02317 
02318 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02319 {
02320    int type, len;
02321    int ret;
02322    int needfree = 0;
02323 
02324    /* Attempt to recover wrapped timestamps */
02325    unwrap_timestamp(fr);
02326    
02327 
02328    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02329    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02330       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02331    else {
02332 #if 0
02333       ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02334 #endif
02335       fr->af.delivery = ast_tv(0,0);
02336    }
02337 
02338    type = JB_TYPE_CONTROL;
02339    len = 0;
02340 
02341    if(fr->af.frametype == AST_FRAME_VOICE) {
02342       type = JB_TYPE_VOICE;
02343       len = ast_codec_get_samples(&fr->af) / 8;
02344    } else if(fr->af.frametype == AST_FRAME_CNG) {
02345       type = JB_TYPE_SILENCE;
02346    }
02347 
02348    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02349       if (tsout)
02350          *tsout = fr->ts;
02351       __do_deliver(fr);
02352       return -1;
02353    }
02354 
02355    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02356     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02357    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
02358        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
02359        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
02360                 jb_frame frame;
02361 
02362                 /* deliver any frames in the jb */
02363                 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK)
02364                         __do_deliver(frame.data);
02365 
02366       jb_reset(iaxs[fr->callno]->jb);
02367 
02368       if (iaxs[fr->callno]->jbid > -1)
02369                         ast_sched_del(sched, iaxs[fr->callno]->jbid);
02370 
02371       iaxs[fr->callno]->jbid = -1;
02372 
02373       /* deliver this frame now */
02374       if (tsout)
02375          *tsout = fr->ts;
02376       __do_deliver(fr);
02377       return -1;
02378    }
02379 
02380    /* insert into jitterbuffer */
02381    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02382    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02383          calc_rxstamp(iaxs[fr->callno],fr->ts));
02384    if (ret == JB_DROP) {
02385       needfree++;
02386    } else if (ret == JB_SCHED) {
02387       update_jbsched(iaxs[fr->callno]);
02388    }
02389    if (tsout)
02390       *tsout = fr->ts;
02391    if (needfree) {
02392       /* Free our iax frame */
02393       iax2_frame_free(fr);
02394       return -1;
02395    }
02396    return 0;
02397 }
02398 
02399 static int iax2_transmit(struct iax_frame *fr)
02400 {
02401    /* Lock the queue and place this packet at the end */
02402    /* By setting this to 0, the network thread will send it for us, and
02403       queue retransmission if necessary */
02404    fr->sentyet = 0;
02405    AST_LIST_LOCK(&iaxq.queue);
02406    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02407    iaxq.count++;
02408    AST_LIST_UNLOCK(&iaxq.queue);
02409    /* Wake up the network and scheduler thread */
02410    pthread_kill(netthreadid, SIGURG);
02411    signal_condition(&sched_lock, &sched_cond);
02412    return 0;
02413 }
02414 
02415 
02416 
02417 static int iax2_digit_begin(struct ast_channel *c, char digit)
02418 {
02419    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02420 }
02421 
02422 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02423 {
02424    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02425 }
02426 
02427 static int iax2_sendtext(struct ast_channel *c, const char *text)
02428 {
02429    
02430    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02431       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02432 }
02433 
02434 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02435 {
02436    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02437 }
02438 
02439 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02440 {
02441    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02442 }
02443 
02444 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02445 {
02446    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02447    ast_mutex_lock(&iaxsl[callno]);
02448    if (iaxs[callno])
02449       iaxs[callno]->owner = newchan;
02450    else
02451       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02452    ast_mutex_unlock(&iaxsl[callno]);
02453    return 0;
02454 }
02455 
02456 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02457 {
02458    struct ast_variable *var;
02459    struct ast_variable *tmp;
02460    struct iax2_peer *peer=NULL;
02461    time_t regseconds = 0, nowtime;
02462    int dynamic=0;
02463 
02464    if (peername)
02465       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02466    else {
02467       char porta[25];
02468       sprintf(porta, "%d", ntohs(sin->sin_port));
02469       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02470       if (var) {
02471          /* We'll need the peer name in order to build the structure! */
02472          for (tmp = var; tmp; tmp = tmp->next) {
02473             if (!strcasecmp(tmp->name, "name"))
02474                peername = tmp->value;
02475          }
02476       }
02477    }
02478    if (!var)
02479       return NULL;
02480 
02481    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02482    
02483    if (!peer) {
02484       ast_variables_destroy(var);
02485       return NULL;
02486    }
02487 
02488    for (tmp = var; tmp; tmp = tmp->next) {
02489       /* Make sure it's not a user only... */
02490       if (!strcasecmp(tmp->name, "type")) {
02491          if (strcasecmp(tmp->value, "friend") &&
02492              strcasecmp(tmp->value, "peer")) {
02493             /* Whoops, we weren't supposed to exist! */
02494             destroy_peer(peer);
02495             peer = NULL;
02496             break;
02497          } 
02498       } else if (!strcasecmp(tmp->name, "regseconds")) {
02499          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02500       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02501          inet_aton(tmp->value, &(peer->addr.sin_addr));
02502       } else if (!strcasecmp(tmp->name, "port")) {
02503          peer->addr.sin_port = htons(atoi(tmp->value));
02504       } else if (!strcasecmp(tmp->name, "host")) {
02505          if (!strcasecmp(tmp->value, "dynamic"))
02506             dynamic = 1;
02507       }
02508    }
02509 
02510    ast_variables_destroy(var);
02511 
02512    if (!peer)
02513       return NULL;
02514 
02515    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02516       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02517       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02518          if (peer->expire > -1)
02519             ast_sched_del(sched, peer->expire);
02520          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
02521       }
02522       AST_LIST_LOCK(&peers);
02523       AST_LIST_INSERT_HEAD(&peers, peer, entry);
02524       AST_LIST_UNLOCK(&peers);
02525       if (ast_test_flag(peer, IAX_DYNAMIC))
02526          reg_source_db(peer);
02527    } else {
02528       ast_set_flag(peer, IAX_TEMPONLY);   
02529    }
02530 
02531    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02532       time(&nowtime);
02533       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02534          memset(&peer->addr, 0, sizeof(peer->addr));
02535          realtime_update_peer(peer->name, &peer->addr, 0);
02536          if (option_debug)
02537             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02538                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02539       }
02540       else {
02541          if (option_debug)
02542             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02543                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02544       }
02545    }
02546 
02547    return peer;
02548 }
02549 
02550 static struct iax2_user *realtime_user(const char *username)
02551 {
02552    struct ast_variable *var;
02553    struct ast_variable *tmp;
02554    struct iax2_user *user=NULL;
02555 
02556    var = ast_load_realtime("iaxusers", "name", username, NULL);
02557    if (!var)
02558       return NULL;
02559 
02560    tmp = var;
02561    while(tmp) {
02562       /* Make sure it's not a peer only... */
02563       if (!strcasecmp(tmp->name, "type")) {
02564          if (strcasecmp(tmp->value, "friend") &&
02565              strcasecmp(tmp->value, "user")) {
02566             return NULL;
02567          } 
02568       }
02569       tmp = tmp->next;
02570    }
02571 
02572    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02573 
02574    ast_variables_destroy(var);
02575 
02576    if (!user)
02577       return NULL;
02578 
02579    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02580       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02581       AST_LIST_LOCK(&users);
02582       AST_LIST_INSERT_HEAD(&users, user, entry);
02583       AST_LIST_UNLOCK(&users);
02584    } else {
02585       ast_set_flag(user, IAX_TEMPONLY);   
02586    }
02587 
02588    return user;
02589 }
02590 
02591 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02592 {
02593    char port[10];
02594    char regseconds[20];
02595    
02596    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02597    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02598    ast_update_realtime("iaxpeers", "name", peername, 
02599       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02600       "regseconds", regseconds, NULL);
02601 }
02602 
02603 struct create_addr_info {
02604    int capability;
02605    unsigned int flags;
02606    int maxtime;
02607    int encmethods;
02608    int found;
02609    int sockfd;
02610    int adsi;
02611    char username[80];
02612    char secret[80];
02613    char outkey[80];
02614    char timezone[80];
02615    char prefs[32];
02616    char context[AST_MAX_CONTEXT];
02617    char peercontext[AST_MAX_CONTEXT];
02618    char mohinterpret[MAX_MUSICCLASS];
02619    char mohsuggest[MAX_MUSICCLASS];
02620 };
02621 
02622 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02623 {
02624    struct ast_hostent ahp;
02625    struct hostent *hp;
02626    struct iax2_peer *peer;
02627 
02628    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02629    cai->sockfd = defaultsockfd;
02630    cai->maxtime = 0;
02631    sin->sin_family = AF_INET;
02632 
02633    if (!(peer = find_peer(peername, 1))) {
02634       cai->found = 0;
02635 
02636       hp = ast_gethostbyname(peername, &ahp);
02637       if (hp) {
02638          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02639          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02640          /* use global iax prefs for unknown peer/user */
02641          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02642          return 0;
02643       } else {
02644          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02645          return -1;
02646       }
02647    }
02648 
02649    cai->found = 1;
02650    
02651    /* if the peer has no address (current or default), return failure */
02652    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02653       if (ast_test_flag(peer, IAX_TEMPONLY))
02654          destroy_peer(peer);
02655       return -1;
02656    }
02657 
02658    /* if the peer is being monitored and is currently unreachable, return failure */
02659    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02660       if (ast_test_flag(peer, IAX_TEMPONLY))
02661          destroy_peer(peer);
02662       return -1;
02663    }
02664 
02665    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02666    cai->maxtime = peer->maxms;
02667    cai->capability = peer->capability;
02668    cai->encmethods = peer->encmethods;
02669    cai->sockfd = peer->sockfd;
02670    cai->adsi = peer->adsi;
02671    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02672    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02673    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02674    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02675    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02676    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02677    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02678    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02679    if (ast_strlen_zero(peer->dbsecret)) {
02680       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02681    } else {
02682       char *family;
02683       char *key = NULL;
02684 
02685       family = ast_strdupa(peer->dbsecret);
02686       key = strchr(family, '/');
02687       if (key)
02688          *key++ = '\0';
02689       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02690          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02691          if (ast_test_flag(peer, IAX_TEMPONLY))
02692             destroy_peer(peer);
02693          return -1;
02694       }
02695    }
02696 
02697    if (peer->addr.sin_addr.s_addr) {
02698       sin->sin_addr = peer->addr.sin_addr;
02699       sin->sin_port = peer->addr.sin_port;
02700    } else {
02701       sin->sin_addr = peer->defaddr.sin_addr;
02702       sin->sin_port = peer->defaddr.sin_port;
02703    }
02704 
02705    if (ast_test_flag(peer, IAX_TEMPONLY))
02706       destroy_peer(peer);
02707 
02708    return 0;
02709 }
02710 
02711 static void __auto_congest(void *nothing)
02712 {
02713    int callno = PTR_TO_CALLNO(nothing);
02714    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02715    ast_mutex_lock(&iaxsl[callno]);
02716    if (iaxs[callno]) {
02717       iaxs[callno]->initid = -1;
02718       iax2_queue_frame(callno, &f);
02719       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02720    }
02721    ast_mutex_unlock(&iaxsl[callno]);
02722 }
02723 
02724 static int auto_congest(void *data)
02725 {
02726 #ifdef SCHED_MULTITHREADED
02727    if (schedule_action(__auto_congest, data))
02728 #endif      
02729       __auto_congest(data);
02730    return 0;
02731 }
02732 
02733 static unsigned int iax2_datetime(const char *tz)
02734 {
02735    time_t t;
02736    struct tm tm;
02737    unsigned int tmp;
02738    time(&t);
02739    localtime_r(&t, &tm);
02740    if (!ast_strlen_zero(tz))
02741       ast_localtime(&t, &tm, tz);
02742    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02743    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02744    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02745    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02746    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02747    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02748    return tmp;
02749 }
02750 
02751 struct parsed_dial_string {
02752    char *username;
02753    char *password;
02754    char *key;
02755    char *peer;
02756    char *port;
02757    char *exten;
02758    char *context;
02759    char *options;
02760 };
02761 
02762 /*!
02763  * \brief Parses an IAX dial string into its component parts.
02764  * \param data the string to be parsed
02765  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
02766  * \return nothing
02767  *
02768  * This function parses the string and fills the structure
02769  * with pointers to its component parts. The input string
02770  * will be modified.
02771  *
02772  * \note This function supports both plaintext passwords and RSA
02773  * key names; if the password string is formatted as '[keyname]',
02774  * then the keyname will be placed into the key field, and the
02775  * password field will be set to NULL.
02776  *
02777  * \note The dial string format is:
02778  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
02779  */
02780 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
02781 {
02782    if (ast_strlen_zero(data))
02783       return;
02784 
02785    pds->peer = strsep(&data, "/");
02786    pds->exten = strsep(&data, "/");
02787    pds->options = data;
02788 
02789    if (pds->exten) {
02790       data = pds->exten;
02791       pds->exten = strsep(&data, "@");
02792       pds->context = data;
02793    }
02794 
02795    if (strchr(pds->peer, '@')) {
02796       data = pds->peer;
02797       pds->username = strsep(&data, "@");
02798       pds->peer = data;
02799    }
02800 
02801    if (pds->username) {
02802       data = pds->username;
02803       pds->username = strsep(&data, ":");
02804       pds->password = data;
02805    }
02806 
02807    data = pds->peer;
02808    pds->peer = strsep(&data, ":");
02809    pds->port = data;
02810 
02811    /* check for a key name wrapped in [] in the secret position, if found,
02812       move it to the key field instead
02813    */
02814    if (pds->password && (pds->password[0] == '[')) {
02815       pds->key = ast_strip_quoted(pds->password, "[", "]");
02816       pds->password = NULL;
02817    }
02818 }
02819 
02820 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
02821 {
02822    struct sockaddr_in sin;
02823    char *l=NULL, *n=NULL, *tmpstr;
02824    struct iax_ie_data ied;
02825    char *defaultrdest = "s";
02826    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02827    struct parsed_dial_string pds;
02828    struct create_addr_info cai;
02829    struct ast_var_t *var;
02830 
02831    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
02832       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
02833       return -1;
02834    }
02835 
02836    memset(&cai, 0, sizeof(cai));
02837    cai.encmethods = iax2_encryption;
02838 
02839    memset(&pds, 0, sizeof(pds));
02840    tmpstr = ast_strdupa(dest);
02841    parse_dial_string(tmpstr, &pds);
02842 
02843    if (!pds.exten)
02844       pds.exten = defaultrdest;
02845 
02846    if (create_addr(pds.peer, &sin, &cai)) {
02847       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
02848       return -1;
02849    }
02850 
02851    if (!pds.username && !ast_strlen_zero(cai.username))
02852       pds.username = cai.username;
02853    if (!pds.password && !ast_strlen_zero(cai.secret))
02854       pds.password = cai.secret;
02855    if (!pds.key && !ast_strlen_zero(cai.outkey))
02856       pds.key = cai.outkey;
02857    if (!pds.context && !ast_strlen_zero(cai.peercontext))
02858       pds.context = cai.peercontext;
02859 
02860    /* Keep track of the context for outgoing calls too */
02861    ast_copy_string(c->context, cai.context, sizeof(c->context));
02862 
02863    if (pds.port)
02864       sin.sin_port = htons(atoi(pds.port));
02865 
02866    l = c->cid.cid_num;
02867    n = c->cid.cid_name;
02868 
02869    /* Now build request */ 
02870    memset(&ied, 0, sizeof(ied));
02871 
02872    /* On new call, first IE MUST be IAX version of caller */
02873    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
02874    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
02875    if (pds.options && strchr(pds.options, 'a')) {
02876       /* Request auto answer */
02877       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
02878    }
02879 
02880    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
02881 
02882    if (l) {
02883       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
02884       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02885    } else {
02886       if (n)
02887          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02888       else
02889          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
02890    }
02891 
02892    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
02893    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
02894 
02895    if (n)
02896       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
02897    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
02898       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
02899 
02900    if (!ast_strlen_zero(c->language))
02901       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
02902    if (!ast_strlen_zero(c->cid.cid_dnid))
02903       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
02904    if (!ast_strlen_zero(c->cid.cid_rdnis))
02905       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
02906 
02907    if (pds.context)
02908       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
02909 
02910    if (pds.username)
02911       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
02912 
02913    if (cai.encmethods)
02914       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
02915 
02916    ast_mutex_lock(&iaxsl[callno]);
02917 
02918    if (!ast_strlen_zero(c->context))
02919       ast_string_field_set(iaxs[callno], context, c->context);
02920 
02921    if (pds.username)
02922       ast_string_field_set(iaxs[callno], username, pds.username);
02923 
02924    iaxs[callno]->encmethods = cai.encmethods;
02925 
02926    iaxs[callno]->adsi = cai.adsi;
02927    
02928    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
02929    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
02930 
02931    if (pds.key)
02932       ast_string_field_set(iaxs[callno], outkey, pds.key);
02933    if (pds.password)
02934       ast_string_field_set(iaxs[callno], secret, pds.password);
02935 
02936    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
02937    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
02938    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
02939    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
02940 
02941    if (iaxs[callno]->maxtime) {
02942       /* Initialize pingtime and auto-congest time */
02943       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
02944       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
02945    } else if (autokill) {
02946       iaxs[callno]->pingtime = autokill / 2;
02947       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
02948    }
02949 
02950    /* Add remote vars */
02951    AST_LIST_TRAVERSE(&c->varshead, var, entries) {
02952       if (!strncmp(ast_var_name(var), "~IAX2~", strlen("~IAX2~"))) {
02953          char tmp[256];
02954          snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var) + strlen("~IAX2~"), ast_var_value(var));
02955          iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
02956       }
02957    }
02958 
02959    /* send the command using the appropriate socket for this peer */
02960    iaxs[callno]->sockfd = cai.sockfd;
02961 
02962    /* Transmit the string in a "NEW" request */
02963    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
02964 
02965    ast_mutex_unlock(&iaxsl[callno]);
02966    ast_setstate(c, AST_STATE_RINGING);
02967    
02968    return 0;
02969 }
02970 
02971 static int iax2_hangup(struct ast_channel *c) 
02972 {
02973    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02974    int alreadygone;
02975    struct iax_ie_data ied;
02976    memset(&ied, 0, sizeof(ied));
02977    ast_mutex_lock(&iaxsl[callno]);
02978    if (callno && iaxs[callno]) {
02979       ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
02980       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
02981       /* Send the hangup unless we have had a transmission error or are already gone */
02982       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
02983       if (!iaxs[callno]->error && !alreadygone) 
02984          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
02985       /* Explicitly predestroy it */
02986       iax2_predestroy(callno);
02987       /* If we were already gone to begin with, destroy us now */
02988       if (alreadygone) {
02989          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
02990          iax2_destroy(callno);
02991       }
02992    }
02993    ast_mutex_unlock(&iaxsl[callno]);
02994    if (option_verbose > 2) 
02995       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
02996    return 0;
02997 }
02998 
02999 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03000 {
03001    struct ast_option_header *h;
03002    int res;
03003 
03004    switch (option) {
03005    case AST_OPTION_TXGAIN:
03006    case AST_OPTION_RXGAIN:
03007       /* these two cannot be sent, because they require a result */
03008       errno = ENOSYS;
03009       return -1;
03010    default:
03011       if (!(h = ast_malloc(datalen + sizeof(*h))))
03012          return -1;
03013 
03014       h->flag = AST_OPTION_FLAG_REQUEST;
03015       h->option = htons(option);
03016       memcpy(h->data, data, datalen);
03017       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03018                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03019                  datalen + sizeof(*h), -1);
03020       free(h);
03021       return res;
03022    }
03023 }
03024 
03025 static struct ast_frame *iax2_read(struct ast_channel *c) 
03026 {
03027    ast_log(LOG_NOTICE, "I should never be called!\n");
03028    return &ast_null_frame;
03029 }
03030 
03031 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03032 {
03033    int res;
03034    struct iax_ie_data ied0;
03035    struct iax_ie_data ied1;
03036    unsigned int transferid = (unsigned int)ast_random();
03037    memset(&ied0, 0, sizeof(ied0));
03038    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03039    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03040    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03041 
03042    memset(&ied1, 0, sizeof(ied1));
03043    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03044    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03045    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03046    
03047    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03048    if (res)
03049       return -1;
03050    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03051    if (res)
03052       return -1;
03053    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03054    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03055    return 0;
03056 }
03057 
03058 static void lock_both(unsigned short callno0, unsigned short callno1)
03059 {
03060    ast_mutex_lock(&iaxsl[callno0]);
03061    while (ast_mutex_trylock(&iaxsl[callno1])) {
03062       ast_mutex_unlock(&iaxsl[callno0]);
03063       usleep(10);
03064       ast_mutex_lock(&iaxsl[callno0]);
03065    }
03066 }
03067 
03068 static void unlock_both(unsigned short callno0, unsigned short callno1)
03069 {
03070    ast_mutex_unlock(&iaxsl[callno1]);
03071    ast_mutex_unlock(&iaxsl[callno0]);
03072 }
03073 
03074 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)
03075 {
03076    struct ast_channel *cs[3];
03077    struct ast_channel *who, *other;
03078    int to = -1;
03079    int res = -1;
03080    int transferstarted=0;
03081    struct ast_frame *f;
03082    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03083    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03084    struct timeval waittimer = {0, 0}, tv;
03085 
03086    lock_both(callno0, callno1);
03087    /* Put them in native bridge mode */
03088    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03089       iaxs[callno0]->bridgecallno = callno1;
03090       iaxs[callno1]->bridgecallno = callno0;
03091    }
03092    unlock_both(callno0, callno1);
03093 
03094    /* If not, try to bridge until we can execute a transfer, if we can */
03095    cs[0] = c0;
03096    cs[1] = c1;
03097    for (/* ever */;;) {
03098       /* Check in case we got masqueraded into */
03099       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03100          if (option_verbose > 2)
03101             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03102          /* Remove from native mode */
03103          if (c0->tech == &iax2_tech) {
03104             ast_mutex_lock(&iaxsl[callno0]);
03105             iaxs[callno0]->bridgecallno = 0;
03106             ast_mutex_unlock(&iaxsl[callno0]);
03107          }
03108          if (c1->tech == &iax2_tech) {
03109             ast_mutex_lock(&iaxsl[callno1]);
03110             iaxs[callno1]->bridgecallno = 0;
03111             ast_mutex_unlock(&iaxsl[callno1]);
03112          }
03113          return AST_BRIDGE_FAILED_NOWARN;
03114       }
03115       if (c0->nativeformats != c1->nativeformats) {
03116          if (option_verbose > 2) {
03117             char buf0[255];
03118             char buf1[255];
03119             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03120             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03121             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03122          }
03123          /* Remove from native mode */
03124          lock_both(callno0, callno1);
03125          iaxs[callno0]->bridgecallno = 0;
03126          iaxs[callno1]->bridgecallno = 0;
03127          unlock_both(callno0, callno1);
03128          return AST_BRIDGE_FAILED_NOWARN;
03129       }
03130       /* check if transfered and if we really want native bridging */
03131       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03132          /* Try the transfer */
03133          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03134                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03135             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03136          transferstarted = 1;
03137       }
03138       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03139          /* Call has been transferred.  We're no longer involved */
03140          gettimeofday(&tv, NULL);
03141          if (ast_tvzero(waittimer)) {
03142             waittimer = tv;
03143          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03144             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03145             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03146             *fo = NULL;
03147             *rc = c0;
03148             res = AST_BRIDGE_COMPLETE;
03149             break;
03150          }
03151       }
03152       to = 1000;
03153       who = ast_waitfor_n(cs, 2, &to);
03154       if (timeoutms > -1) {
03155          timeoutms -= (1000 - to);
03156          if (timeoutms < 0)
03157             timeoutms = 0;
03158       }
03159       if (!who) {
03160          if (!timeoutms) {
03161             res = AST_BRIDGE_RETRY;
03162             break;
03163          }
03164          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03165             res = AST_BRIDGE_FAILED;
03166             break;
03167          }
03168          continue;
03169       }
03170       f = ast_read(who);
03171       if (!f) {
03172          *fo = NULL;
03173          *rc = who;
03174          res = AST_BRIDGE_COMPLETE;
03175          break;
03176       }
03177       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03178          *fo = f;
03179          *rc = who;
03180          res =  AST_BRIDGE_COMPLETE;
03181          break;
03182       }
03183       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03184       if ((f->frametype == AST_FRAME_VOICE) ||
03185           (f->frametype == AST_FRAME_TEXT) ||
03186           (f->frametype == AST_FRAME_VIDEO) || 
03187           (f->frametype == AST_FRAME_IMAGE) ||
03188           (f->frametype == AST_FRAME_DTMF)) {
03189          /* monitored dtmf take out of the bridge.
03190           * check if we monitor the specific source.
03191           */
03192          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03193          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03194             *rc = who;
03195             *fo = f;
03196             res = AST_BRIDGE_COMPLETE;
03197             /* Remove from native mode */
03198             break;
03199          }
03200          /* everything else goes to the other side */
03201          ast_write(other, f);
03202       }
03203       ast_frfree(f);
03204       /* Swap who gets priority */
03205       cs[2] = cs[0];
03206       cs[0] = cs[1];
03207       cs[1] = cs[2];
03208    }
03209    lock_both(callno0, callno1);
03210    if(iaxs[callno0])
03211       iaxs[callno0]->bridgecallno = 0;
03212    if(iaxs[callno1])
03213       iaxs[callno1]->bridgecallno = 0;
03214    unlock_both(callno0, callno1);
03215    return res;
03216 }
03217 
03218 static int iax2_answer(struct ast_channel *c)
03219 {
03220    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03221    if (option_debug)
03222       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03223    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03224 }
03225 
03226 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03227 {
03228    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03229    struct chan_iax2_pvt *pvt;
03230    int res = 0;
03231 
03232    if (option_debug && iaxdebug)
03233       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03234 
03235    ast_mutex_lock(&iaxsl[callno]);
03236    pvt = iaxs[callno];
03237    if (!strcasecmp(pvt->mohinterpret, "passthrough")) {
03238       res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03239       ast_mutex_unlock(&iaxsl[callno]);
03240       return res;
03241    }
03242 
03243    switch (condition) {
03244    case AST_CONTROL_HOLD:
03245       ast_moh_start(c, data, pvt->mohinterpret);
03246       break;
03247    case AST_CONTROL_UNHOLD:
03248       ast_moh_stop(c);
03249       break;
03250    default:
03251       res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03252    }
03253 
03254    ast_mutex_unlock(&iaxsl[callno]);
03255 
03256    return res;
03257 }
03258    
03259 static int iax2_transfer(struct ast_channel *c, const char *dest)
03260 {
03261    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03262    struct iax_ie_data ied;
03263    char tmp[256], *context;
03264    ast_copy_string(tmp, dest, sizeof(tmp));
03265    context = strchr(tmp, '@');
03266    if (context) {
03267       *context = '\0';
03268       context++;
03269    }
03270    memset(&ied, 0, sizeof(ied));
03271    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03272    if (context)
03273       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03274    if (option_debug)
03275       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03276    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03277 }
03278    
03279 static int iax2_getpeertrunk(struct sockaddr_in sin)
03280 {
03281    struct iax2_peer *peer = NULL;
03282    int res = 0;
03283 
03284    AST_LIST_LOCK(&peers);
03285    AST_LIST_TRAVERSE(&peers, peer, entry) {
03286       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03287           (peer->addr.sin_port == sin.sin_port)) {
03288          res = ast_test_flag(peer, IAX_TRUNK);
03289          break;
03290       }
03291    }
03292    AST_LIST_UNLOCK(&peers);
03293 
03294    return res;
03295 }
03296 
03297 /*! \brief  Create new call, interface with the PBX core */
03298 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03299 {
03300    struct ast_channel *tmp;
03301    struct chan_iax2_pvt *i;
03302    struct ast_variable *v = NULL;
03303 
03304    if (!(i = iaxs[callno])) {
03305       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03306       return NULL;
03307    }
03308 
03309    /* Don't hold call lock */
03310    ast_mutex_unlock(&iaxsl[callno]);
03311    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);
03312    ast_mutex_lock(&iaxsl[callno]);
03313    if (!tmp)
03314       return NULL;
03315    tmp->tech = &iax2_tech;
03316    /* We can support any format by default, until we get restricted */
03317    tmp->nativeformats = capability;
03318    tmp->readformat = ast_best_codec(capability);
03319    tmp->writeformat = ast_best_codec(capability);
03320    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03321 
03322    /* Don't use ast_set_callerid() here because it will
03323     * generate a NewCallerID event before the NewChannel event */
03324    tmp->cid.cid_num = ast_strdup(i->cid_num);
03325    tmp->cid.cid_name = ast_strdup(i->cid_name);
03326    if (!ast_strlen_zero(i->ani))
03327       tmp->cid.cid_ani = ast_strdup(i->ani);
03328    else
03329       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03330    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03331    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03332    tmp->cid.cid_pres = i->calling_pres;
03333    tmp->cid.cid_ton = i->calling_ton;
03334    tmp->cid.cid_tns = i->calling_tns;
03335    if (!ast_strlen_zero(i->language))
03336       ast_string_field_set(tmp, language, i->language);
03337    if (!ast_strlen_zero(i->accountcode))
03338       ast_string_field_set(tmp, accountcode, i->accountcode);
03339    if (i->amaflags)
03340       tmp->amaflags = i->amaflags;
03341    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03342    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03343    if (i->adsi)
03344       tmp->adsicpe = i->peeradsicpe;
03345    else
03346       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03347    i->owner = tmp;
03348    i->capability = capability;
03349    if (state != AST_STATE_DOWN) {
03350       if (ast_pbx_start(tmp)) {
03351          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03352          ast_hangup(tmp);
03353          i->owner = NULL;
03354          return NULL;
03355       }
03356    }
03357 
03358    for (v = i->vars ; v ; v = v->next)
03359       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03360 
03361    ast_module_ref(ast_module_info->self);
03362    
03363    return tmp;
03364 }
03365 
03366 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03367 {
03368    unsigned long int mssincetx; /* unsigned to handle overflows */
03369    long int ms, pred;
03370 
03371    tpeer->trunkact = *tv;
03372    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03373    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03374       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03375       tpeer->txtrunktime = *tv;
03376       tpeer->lastsent = 999999;
03377    }
03378    /* Update last transmit time now */
03379    tpeer->lasttxtime = *tv;
03380    
03381    /* Calculate ms offset */
03382    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03383    /* Predict from last value */
03384    pred = tpeer->lastsent + sampms;
03385    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03386       ms = pred;
03387    
03388    /* We never send the same timestamp twice, so fudge a little if we must */
03389    if (ms == tpeer->lastsent)
03390       ms = tpeer->lastsent + 1;
03391    tpeer->lastsent = ms;
03392    return ms;
03393 }
03394 
03395 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03396 {
03397    long ms; /* NOT unsigned */
03398    if (ast_tvzero(iaxs[callno]->rxcore)) {
03399       /* Initialize rxcore time if appropriate */
03400       gettimeofday(&iaxs[callno]->rxcore, NULL);
03401       /* Round to nearest 20ms so traces look pretty */
03402       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03403    }
03404    /* Calculate difference between trunk and channel */
03405    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03406    /* Return as the sum of trunk time and the difference between trunk and real time */
03407    return ms + ts;
03408 }
03409 
03410 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03411 {
03412    int ms;
03413    int voice = 0;
03414    int genuine = 0;
03415    int adjust;
03416    struct timeval *delivery = NULL;
03417 
03418 
03419    /* What sort of frame do we have?: voice is self-explanatory
03420       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03421       non-genuine frames are CONTROL frames [ringing etc], DTMF
03422       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03423       the others need a timestamp slaved to the voice frames so that they go in sequence
03424    */
03425    if (f) {
03426       if (f->frametype == AST_FRAME_VOICE) {
03427          voice = 1;
03428          delivery = &f->delivery;
03429       } else if (f->frametype == AST_FRAME_IAX) {
03430          genuine = 1;
03431       } else if (f->frametype == AST_FRAME_CNG) {
03432          p->notsilenttx = 0;  
03433       }
03434    }
03435    if (ast_tvzero(p->offset)) {
03436       gettimeofday(&p->offset, NULL);
03437       /* Round to nearest 20ms for nice looking traces */
03438       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03439    }
03440    /* If the timestamp is specified, just send it as is */
03441    if (ts)
03442       return ts;
03443    /* If we have a time that the frame arrived, always use it to make our timestamp */
03444    if (delivery && !ast_tvzero(*delivery)) {
03445       ms = ast_tvdiff_ms(*delivery, p->offset);
03446       if (option_debug > 2 && iaxdebug)
03447          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03448    } else {
03449       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03450       if (ms < 0)
03451          ms = 0;
03452       if (voice) {
03453          /* On a voice frame, use predicted values if appropriate */
03454          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03455             /* Adjust our txcore, keeping voice and non-voice synchronized */
03456             /* AN EXPLANATION:
03457                When we send voice, we usually send "calculated" timestamps worked out
03458                on the basis of the number of samples sent. When we send other frames,
03459                we usually send timestamps worked out from the real clock.
03460                The problem is that they can tend to drift out of step because the 
03461                   source channel's clock and our clock may not be exactly at the same rate.
03462                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03463                for this call.  Moving it adjusts timestamps for non-voice frames.
03464                We make the adjustment in the style of a moving average.  Each time we
03465                adjust p->offset by 10% of the difference between our clock-derived
03466                timestamp and the predicted timestamp.  That's why you see "10000"
03467                below even though IAX2 timestamps are in milliseconds.
03468                The use of a moving average avoids offset moving too radically.
03469                Generally, "adjust" roams back and forth around 0, with offset hardly
03470                changing at all.  But if a consistent different starts to develop it
03471                will be eliminated over the course of 10 frames (200-300msecs) 
03472             */
03473             adjust = (ms - p->nextpred);
03474             if (adjust < 0)
03475                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03476             else if (adjust > 0)
03477                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03478 
03479             if (!p->nextpred) {
03480                p->nextpred = ms; /*f->samples / 8;*/
03481                if (p->nextpred <= p->lastsent)
03482                   p->nextpred = p->lastsent + 3;
03483             }
03484             ms = p->nextpred;
03485          } else {
03486                 /* in this case, just use the actual
03487             * time, since we're either way off
03488             * (shouldn't happen), or we're  ending a
03489             * silent period -- and seed the next
03490             * predicted time.  Also, round ms to the
03491             * next multiple of frame size (so our
03492             * silent periods are multiples of
03493             * frame size too) */
03494 
03495             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03496                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03497                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03498 
03499             if (f->samples >= 8) /* check to make sure we dont core dump */
03500             {
03501                int diff = ms % (f->samples / 8);
03502                if (diff)
03503                    ms += f->samples/8 - diff;
03504             }
03505 
03506             p->nextpred = ms;
03507             p->notsilenttx = 1;
03508          }
03509       } else {
03510          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03511             it's a genuine frame */
03512          if (genuine) {
03513             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03514             if (ms <= p->lastsent)
03515                ms = p->lastsent + 3;
03516          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03517             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03518             ms = p->lastsent + 3;
03519          }
03520       }
03521    }
03522    p->lastsent = ms;
03523    if (voice)
03524       p->nextpred = p->nextpred + f->samples / 8;
03525    return ms;
03526 }
03527 
03528 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03529 {
03530    /* Returns where in "receive time" we are.  That is, how many ms
03531       since we received (or would have received) the frame with timestamp 0 */
03532    int ms;
03533 #ifdef IAXTESTS
03534    int jit;
03535 #endif /* IAXTESTS */
03536    /* Setup rxcore if necessary */
03537    if (ast_tvzero(p->rxcore)) {
03538       p->rxcore = ast_tvnow();
03539       if (option_debug && iaxdebug)
03540          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03541                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03542       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03543 #if 1
03544       if (option_debug && iaxdebug)
03545          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03546                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03547 #endif
03548    }
03549 
03550    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03551 #ifdef IAXTESTS
03552    if (test_jit) {
03553       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03554          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03555          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03556             jit = -jit;
03557          ms += jit;
03558       }
03559    }
03560    if (test_late) {
03561       ms += test_late;
03562       test_late = 0;
03563    }
03564 #endif /* IAXTESTS */
03565    return ms;
03566 }
03567 
03568 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03569 {
03570    struct iax2_trunk_peer *tpeer;
03571    
03572    /* Finds and locks trunk peer */
03573    ast_mutex_lock(&tpeerlock);
03574    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03575       /* We don't lock here because tpeer->addr *never* changes */
03576       if (!inaddrcmp(&tpeer->addr, sin)) {
03577          ast_mutex_lock(&tpeer->lock);
03578          break;
03579       }
03580    }
03581    if (!tpeer) {
03582       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03583          ast_mutex_init(&tpeer->lock);
03584          tpeer->lastsent = 9999;
03585          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03586          tpeer->trunkact = ast_tvnow();
03587          ast_mutex_lock(&tpeer->lock);
03588          tpeer->next = tpeers;
03589          tpeer->sockfd = fd;
03590          tpeers = tpeer;
03591 #ifdef SO_NO_CHECK
03592          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03593 #endif
03594          ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03595       }
03596    }
03597    ast_mutex_unlock(&tpeerlock);
03598    return tpeer;
03599 }
03600 
03601 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03602 {
03603    struct ast_frame *f;
03604    struct iax2_trunk_peer *tpeer;
03605    void *tmp, *ptr;
03606    struct ast_iax2_meta_trunk_entry *met;
03607    struct ast_iax2_meta_trunk_mini *mtm;
03608 
03609    f = &fr->af;
03610    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03611    if (tpeer) {
03612       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03613          /* Need to reallocate space */
03614          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03615             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03616                ast_mutex_unlock(&tpeer->lock);
03617                return -1;
03618             }
03619             
03620             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03621             tpeer->trunkdata = tmp;
03622             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);
03623          } else {
03624             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));
03625             ast_mutex_unlock(&tpeer->lock);
03626             return -1;
03627          }
03628       }
03629 
03630       /* Append to meta frame */
03631       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03632       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03633          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03634          mtm->len = htons(f->datalen);
03635          mtm->mini.callno = htons(pvt->callno);
03636          mtm->mini.ts = htons(0xffff & fr->ts);
03637          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03638          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03639       } else {
03640          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03641          /* Store call number and length in meta header */
03642          met->callno = htons(pvt->callno);
03643          met->len = htons(f->datalen);
03644          /* Advance pointers/decrease length past trunk entry header */
03645          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03646          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03647       }
03648       /* Copy actual trunk data */
03649       memcpy(ptr, f->data, f->datalen);
03650       tpeer->trunkdatalen += f->datalen;
03651 
03652       tpeer->calls++;
03653       ast_mutex_unlock(&tpeer->lock);
03654    }
03655    return 0;
03656 }
03657 
03658 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03659 {
03660    aes_encrypt_key128(digest, ecx);
03661    aes_decrypt_key128(digest, dcx);
03662 }
03663 
03664 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03665 {
03666 #if 0
03667    /* Debug with "fake encryption" */
03668    int x;
03669    if (len % 16)
03670       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03671    for (x=0;x<len;x++)
03672       dst[x] = src[x] ^ 0xff;
03673 #else 
03674    unsigned char lastblock[16] = { 0 };
03675    int x;
03676    while(len > 0) {
03677       aes_decrypt(src, dst, dcx);
03678       for (x=0;x<16;x++)
03679          dst[x] ^= lastblock[x];
03680       memcpy(lastblock, src, sizeof(lastblock));
03681       dst += 16;
03682       src += 16;
03683       len -= 16;
03684    }
03685 #endif
03686 }
03687 
03688 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03689 {
03690 #if 0
03691    /* Debug with "fake encryption" */
03692    int x;
03693    if (len % 16)
03694       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03695    for (x=0;x<len;x++)
03696       dst[x] = src[x] ^ 0xff;
03697 #else
03698    unsigned char curblock[16] = { 0 };
03699    int x;
03700    while(len > 0) {
03701       for (x=0;x<16;x++)
03702          curblock[x] ^= src[x];
03703       aes_encrypt(curblock, dst, ecx);
03704       memcpy(curblock, dst, sizeof(curblock)); 
03705       dst += 16;
03706       src += 16;
03707       len -= 16;
03708    }
03709 #endif
03710 }
03711 
03712 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03713 {
03714    int padding;
03715    unsigned char *workspace;
03716 
03717    workspace = alloca(*datalen);
03718    memset(f, 0, sizeof(*f));
03719    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03720       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03721       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03722          return -1;
03723       /* Decrypt */
03724       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03725 
03726       padding = 16 + (workspace[15] & 0xf);
03727       if (option_debug && iaxdebug)
03728          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03729       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03730          return -1;
03731 
03732       *datalen -= padding;
03733       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03734       f->frametype = fh->type;
03735       if (f->frametype == AST_FRAME_VIDEO) {
03736          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03737       } else {
03738          f->subclass = uncompress_subclass(fh->csub);
03739       }
03740    } else {
03741       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03742       if (option_debug && iaxdebug)
03743          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03744       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03745          return -1;
03746       /* Decrypt */
03747       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03748       padding = 16 + (workspace[15] & 0x0f);
03749       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03750          return -1;
03751       *datalen -= padding;
03752       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03753    }
03754    return 0;
03755 }
03756 
03757 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
03758 {
03759    int padding;
03760    unsigned char *workspace;
03761    workspace = alloca(*datalen + 32);
03762    if (!workspace)
03763       return -1;
03764    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03765       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03766       if (option_debug && iaxdebug)
03767          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03768       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03769       padding = 16 + (padding & 0xf);
03770       memcpy(workspace, poo, padding);
03771       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03772       workspace[15] &= 0xf0;
03773       workspace[15] |= (padding & 0xf);
03774       if (option_debug && iaxdebug)
03775          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]);
03776       *datalen += padding;
03777       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03778       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03779          memcpy(poo, workspace + *datalen - 32, 32);
03780    } else {
03781       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03782       if (option_debug && iaxdebug)
03783          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03784       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03785       padding = 16 + (padding & 0xf);
03786       memcpy(workspace, poo, padding);
03787       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03788       workspace[15] &= 0xf0;
03789       workspace[15] |= (padding & 0x0f);
03790       *datalen += padding;
03791       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03792       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03793          memcpy(poo, workspace + *datalen - 32, 32);
03794    }
03795    return 0;
03796 }
03797 
03798 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03799 {
03800    int res=-1;
03801    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03802       /* Search for possible keys, given secrets */
03803       struct MD5Context md5;
03804       unsigned char digest[16];
03805       char *tmppw, *stringp;
03806       
03807       tmppw = ast_strdupa(iaxs[callno]->secret);
03808       stringp = tmppw;
03809       while ((tmppw = strsep(&stringp, ";"))) {
03810          MD5Init(&md5);
03811          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03812          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03813          MD5Final(digest, &md5);
03814          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03815          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03816          if (!res) {
03817             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03818             break;
03819          }
03820       }
03821    } else 
03822       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03823    return res;
03824 }
03825 
03826 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
03827 {
03828    /* Queue a packet for delivery on a given private structure.  Use "ts" for
03829       timestamp, or calculate if ts is 0.  Send immediately without retransmission
03830       or delayed, with retransmission */
03831    struct ast_iax2_full_hdr *fh;
03832    struct ast_iax2_mini_hdr *mh;
03833    struct ast_iax2_video_hdr *vh;
03834    struct {
03835       struct iax_frame fr2;
03836       unsigned char buffer[4096];
03837    } frb;
03838    struct iax_frame *fr;
03839    int res;
03840    int sendmini=0;
03841    unsigned int lastsent;
03842    unsigned int fts;
03843       
03844    if (!pvt) {
03845       ast_log(LOG_WARNING, "No private structure for packet?\n");
03846       return -1;
03847    }
03848    
03849    lastsent = pvt->lastsent;
03850 
03851    /* Calculate actual timestamp */
03852    fts = calc_timestamp(pvt, ts, f);
03853 
03854    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
03855     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
03856     * increment the "predicted timestamps" for voice, if we're predecting */
03857    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
03858        return 0;
03859 
03860 
03861    if ((ast_test_flag(pvt, IAX_TRUNK) || 
03862          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
03863          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
03864       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
03865        (f->frametype == AST_FRAME_VOICE) 
03866       /* is a voice frame */ &&
03867       (f->subclass == pvt->svoiceformat) 
03868       /* is the same type */ ) {
03869          /* Force immediate rather than delayed transmission */
03870          now = 1;
03871          /* Mark that mini-style frame is appropriate */
03872          sendmini = 1;
03873    }
03874    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
03875       (f->frametype == AST_FRAME_VIDEO) &&
03876       ((f->subclass & ~0x1) == pvt->svideoformat)) {
03877          now = 1;
03878          sendmini = 1;
03879    }
03880    /* Allocate an iax_frame */
03881    if (now) {
03882       fr = &frb.fr2;
03883    } else
03884       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));
03885    if (!fr) {
03886       ast_log(LOG_WARNING, "Out of memory\n");
03887       return -1;
03888    }
03889    /* Copy our prospective frame into our immediate or retransmitted wrapper */
03890    iax_frame_wrap(fr, f);
03891 
03892    fr->ts = fts;
03893    fr->callno = pvt->callno;
03894    fr->transfer = transfer;
03895    fr->final = final;
03896    if (!sendmini) {
03897       /* We need a full frame */
03898       if (seqno > -1)
03899          fr->oseqno = seqno;
03900       else
03901          fr->oseqno = pvt->oseqno++;
03902       fr->iseqno = pvt->iseqno;
03903       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
03904       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
03905       fh->ts = htonl(fr->ts);
03906       fh->oseqno = fr->oseqno;
03907       if (transfer) {
03908          fh->iseqno = 0;
03909       } else
03910          fh->iseqno = fr->iseqno;
03911       /* Keep track of the last thing we've acknowledged */
03912       if (!transfer)
03913          pvt->aseqno = fr->iseqno;
03914       fh->type = fr->af.frametype & 0xFF;
03915       if (fr->af.frametype == AST_FRAME_VIDEO)
03916          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
03917       else
03918          fh->csub = compress_subclass(fr->af.subclass);
03919       if (transfer) {
03920          fr->dcallno = pvt->transfercallno;
03921       } else
03922          fr->dcallno = pvt->peercallno;
03923       fh->dcallno = htons(fr->dcallno);
03924       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
03925       fr->data = fh;
03926       fr->retries = 0;
03927       /* Retry after 2x the ping time has passed */
03928       fr->retrytime = pvt->pingtime * 2;
03929       if (fr->retrytime < MIN_RETRY_TIME)
03930          fr->retrytime = MIN_RETRY_TIME;
03931       if (fr->retrytime > MAX_RETRY_TIME)
03932          fr->retrytime = MAX_RETRY_TIME;
03933       /* Acks' don't get retried */
03934       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
03935          fr->retries = -1;
03936       else if (f->frametype == AST_FRAME_VOICE)
03937          pvt->svoiceformat = f->subclass;
03938       else if (f->frametype == AST_FRAME_VIDEO)
03939          pvt->svideoformat = f->subclass & ~0x1;
03940       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
03941          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
03942             if (iaxdebug) {
03943                if (fr->transfer)
03944                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03945                else
03946                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03947             }
03948             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
03949          } else
03950             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
03951       }
03952    
03953       if (now) {
03954          res = send_packet(fr);
03955       } else
03956          res = iax2_transmit(fr);
03957    } else {
03958       if (ast_test_flag(pvt, IAX_TRUNK)) {
03959          iax2_trunk_queue(pvt, fr);
03960          res = 0;
03961       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
03962          /* Video frame have no sequence number */
03963          fr->oseqno = -1;
03964          fr->iseqno = -1;
03965          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
03966          vh->zeros = 0;
03967          vh->callno = htons(0x8000 | fr->callno);
03968          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
03969          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
03970          fr->data = vh;
03971          fr->retries = -1;
03972          res = send_packet(fr);        
03973       } else {
03974          /* Mini-frames have no sequence number */
03975          fr->oseqno = -1;
03976          fr->iseqno = -1;
03977          /* Mini frame will do */
03978          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
03979          mh->callno = htons(fr->callno);
03980          mh->ts = htons(fr->ts & 0xFFFF);
03981          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
03982          fr->data = mh;
03983          fr->retries = -1;
03984          if (pvt->transferring == TRANSFER_MEDIAPASS)
03985             fr->transfer = 1;
03986          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
03987             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
03988                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
03989             } else
03990                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
03991          }
03992          res = send_packet(fr);
03993       }
03994    }
03995    return res;
03996 }
03997 
03998 static int iax2_show_users(int fd, int argc, char *argv[])
03999 {
04000    regex_t regexbuf;
04001    int havepattern = 0;
04002 
04003 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04004 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04005 
04006    struct iax2_user *user = NULL;
04007    char auth[90];
04008    char *pstr = "";
04009 
04010    switch (argc) {
04011    case 5:
04012       if (!strcasecmp(argv[3], "like")) {
04013          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04014             return RESULT_SHOWUSAGE;
04015          havepattern = 1;
04016       } else
04017          return RESULT_SHOWUSAGE;
04018    case 3:
04019       break;
04020    default:
04021       return RESULT_SHOWUSAGE;
04022    }
04023 
04024    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04025    AST_LIST_LOCK(&users);
04026    AST_LIST_TRAVERSE(&users, user, entry) {
04027       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04028          continue;
04029       
04030       if (!ast_strlen_zero(user->secret)) {
04031          ast_copy_string(auth,user->secret,sizeof(auth));
04032       } else if (!ast_strlen_zero(user->inkeys)) {
04033          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04034       } else
04035          ast_copy_string(auth, "-no secret-", sizeof(auth));
04036       
04037       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04038          pstr = "REQ Only";
04039       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04040          pstr = "Disabled";
04041       else
04042          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04043       
04044       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04045          user->contexts ? user->contexts->context : context,
04046          user->ha ? "Yes" : "No", pstr);
04047       
04048    }
04049    AST_LIST_UNLOCK(&users);
04050 
04051    if (havepattern)
04052       regfree(&regexbuf);
04053 
04054    return RESULT_SUCCESS;
04055 #undef FORMAT
04056 #undef FORMAT2
04057 }
04058 
04059 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04060 {
04061    regex_t regexbuf;
04062    int havepattern = 0;
04063    int total_peers = 0;
04064    int online_peers = 0;
04065    int offline_peers = 0;
04066    int unmonitored_peers = 0;
04067 
04068 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04069 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04070 
04071    struct iax2_peer *peer = NULL;
04072    char name[256];
04073    int registeredonly=0;
04074    char *term = manager ? "\r\n" : "\n";
04075 
04076    switch (argc) {
04077    case 6:
04078       if (!strcasecmp(argv[3], "registered"))
04079          registeredonly = 1;
04080       else
04081          return RESULT_SHOWUSAGE;
04082       if (!strcasecmp(argv[4], "like")) {
04083          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04084             return RESULT_SHOWUSAGE;
04085          havepattern = 1;
04086       } else
04087          return RESULT_SHOWUSAGE;
04088       break;
04089    case 5:
04090       if (!strcasecmp(argv[3], "like")) {
04091          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04092             return RESULT_SHOWUSAGE;
04093          havepattern = 1;
04094       } else
04095          return RESULT_SHOWUSAGE;
04096       break;
04097    case 4:
04098       if (!strcasecmp(argv[3], "registered"))
04099          registeredonly = 1;
04100       else
04101          return RESULT_SHOWUSAGE;
04102       break;
04103    case 3:
04104       break;
04105    default:
04106       return RESULT_SHOWUSAGE;
04107    }
04108 
04109 
04110    if (s)
04111       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04112    else
04113       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04114 
04115    AST_LIST_LOCK(&peers);
04116    AST_LIST_TRAVERSE(&peers, peer, entry) {
04117       char nm[20];
04118       char status[20];
04119       char srch[2000];
04120       int retstatus;
04121 
04122       if (registeredonly && !peer->addr.sin_addr.s_addr)
04123          continue;
04124       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04125          continue;
04126 
04127       if (!ast_strlen_zero(peer->username))
04128          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04129       else
04130          ast_copy_string(name, peer->name, sizeof(name));
04131       
04132       retstatus = peer_status(peer, status, sizeof(status));
04133       if (retstatus > 0)
04134          online_peers++;
04135       else if (!retstatus)
04136          offline_peers++;
04137       else
04138          unmonitored_peers++;
04139       
04140       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04141       
04142       snprintf(srch, sizeof(srch), FORMAT, name, 
04143           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04144           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04145           nm,
04146           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04147           peer->encmethods ? "(E)" : "   ", status, term);
04148       
04149       if (s)
04150          astman_append(s, FORMAT, name, 
04151                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04152                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04153                   nm,
04154                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04155                   peer->encmethods ? "(E)" : "   ", status, term);
04156       else
04157          ast_cli(fd, FORMAT, name, 
04158             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04159             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04160             nm,
04161             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04162             peer->encmethods ? "(E)" : "   ", status, term);
04163       total_peers++;
04164    }
04165    AST_LIST_UNLOCK(&peers);
04166 
04167    if (s)
04168       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04169    else
04170       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04171 
04172    if (havepattern)
04173       regfree(&regexbuf);
04174 
04175    return RESULT_SUCCESS;
04176 #undef FORMAT
04177 #undef FORMAT2
04178 }
04179 
04180 static int iax2_show_threads(int fd, int argc, char *argv[])
04181 {
04182    struct iax2_thread *thread = NULL;
04183    time_t t;
04184    int threadcount = 0, dynamiccount = 0;
04185    char type;
04186 
04187    if (argc != 3)
04188       return RESULT_SHOWUSAGE;
04189       
04190    ast_cli(fd, "IAX2 Thread Information\n");
04191    time(&t);
04192    ast_cli(fd, "Idle Threads:\n");
04193    AST_LIST_LOCK(&idle_list);
04194    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04195 #ifdef DEBUG_SCHED_MULTITHREAD
04196       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04197          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04198 #else
04199       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04200          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04201 #endif
04202       threadcount++;
04203    }
04204    AST_LIST_UNLOCK(&idle_list);
04205    ast_cli(fd, "Active Threads:\n");
04206    AST_LIST_LOCK(&active_list);
04207    AST_LIST_TRAVERSE(&active_list, thread, list) {
04208       if (thread->type == IAX_TYPE_DYNAMIC)
04209          type = 'D';
04210       else
04211          type = 'P';
04212 #ifdef DEBUG_SCHED_MULTITHREAD
04213       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04214          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04215 #else
04216       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04217          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04218 #endif
04219       threadcount++;
04220    }
04221    AST_LIST_UNLOCK(&active_list);
04222    ast_cli(fd, "Dynamic Threads:\n");
04223         AST_LIST_LOCK(&dynamic_list);
04224         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04225 #ifdef DEBUG_SCHED_MULTITHREAD
04226                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04227                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04228 #else
04229                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04230                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04231 #endif
04232       dynamiccount++;
04233         }
04234         AST_LIST_UNLOCK(&dynamic_list);
04235    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04236    return RESULT_SUCCESS;
04237 }
04238 
04239 static int iax2_show_peers(int fd, int argc, char *argv[])
04240 {
04241    return __iax2_show_peers(0, fd, NULL, argc, argv);
04242 }
04243 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04244 {
04245    ast_cli_netstats(s, -1, 0);
04246    astman_append(s, "\r\n");
04247    return RESULT_SUCCESS;
04248 }
04249 
04250 static int iax2_show_firmware(int fd, int argc, char *argv[])
04251 {
04252 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04253 #if !defined(__FreeBSD__)
04254 #define FORMAT "%-15.15s  %-15d %-15d\n"
04255 #else /* __FreeBSD__ */
04256 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04257 #endif /* __FreeBSD__ */
04258    struct iax_firmware *cur;
04259    if ((argc != 3) && (argc != 4))
04260       return RESULT_SHOWUSAGE;
04261    ast_mutex_lock(&waresl.lock);
04262    
04263    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04264    for (cur = waresl.wares;cur;cur = cur->next) {
04265       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04266          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04267             (int)ntohl(cur->fwh->datalen));
04268    }
04269    ast_mutex_unlock(&waresl.lock);
04270    return RESULT_SUCCESS;
04271 #undef FORMAT
04272 #undef FORMAT2
04273 }
04274 
04275 /* JDG: callback to display iax peers in manager */
04276 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04277 {
04278    char *a[] = { "iax2", "show", "users" };
04279    int ret;
04280    const char *id = astman_get_header(m,"ActionID");
04281 
04282    if (!ast_strlen_zero(id))
04283       astman_append(s, "ActionID: %s\r\n",id);
04284    ret = __iax2_show_peers(1, -1, s, 3, a );
04285    astman_append(s, "\r\n\r\n" );
04286    return ret;
04287 } /* /JDG */
04288 
04289 static char *regstate2str(int regstate)
04290 {
04291    switch(regstate) {
04292    case REG_STATE_UNREGISTERED:
04293       return "Unregistered";
04294    case REG_STATE_REGSENT:
04295       return "Request Sent";
04296    case REG_STATE_AUTHSENT:
04297       return "Auth. Sent";
04298    case REG_STATE_REGISTERED:
04299       return "Registered";
04300    case REG_STATE_REJECTED:
04301       return "Rejected";
04302    case REG_STATE_TIMEOUT:
04303       return "Timeout";
04304    case REG_STATE_NOAUTH:
04305       return "No Authentication";
04306    default:
04307       return "Unknown";
04308    }
04309 }
04310 
04311 static int iax2_show_registry(int fd, int argc, char *argv[])
04312 {
04313 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04314 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04315    struct iax2_registry *reg = NULL;
04316 
04317    char host[80];
04318    char perceived[80];
04319    if (argc != 3)
04320       return RESULT_SHOWUSAGE;
04321    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04322    AST_LIST_LOCK(&registrations);
04323    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04324       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04325       if (reg->us.sin_addr.s_addr) 
04326          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04327       else
04328          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04329       ast_cli(fd, FORMAT, host, 
04330                (reg->dnsmgr) ? "Y" : "N", 
04331                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04332    }
04333    AST_LIST_UNLOCK(&registrations);
04334    return RESULT_SUCCESS;
04335 #undef FORMAT
04336 #undef FORMAT2
04337 }
04338 
04339 static int iax2_show_channels(int fd, int argc, char *argv[])
04340 {
04341 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04342 #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"
04343 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04344    int x;
04345    int numchans = 0;
04346 
04347    if (argc != 3)
04348       return RESULT_SHOWUSAGE;
04349    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04350    for (x=0;x<IAX_MAX_CALLS;x++) {
04351       ast_mutex_lock(&iaxsl[x]);
04352       if (iaxs[x]) {
04353          int lag, jitter, localdelay;
04354          jb_info jbinfo;
04355          
04356          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04357             jb_getinfo(iaxs[x]->jb, &jbinfo);
04358             jitter = jbinfo.jitter;
04359             localdelay = jbinfo.current - jbinfo.min;
04360          } else {
04361             jitter = -1;
04362             localdelay = 0;
04363          }
04364          lag = iaxs[x]->remote_rr.delay;
04365          ast_cli(fd, FORMAT,
04366             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04367             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04368             S_OR(iaxs[x]->username, "(None)"),
04369             iaxs[x]->callno, iaxs[x]->peercallno,
04370             iaxs[x]->oseqno, iaxs[x]->iseqno,
04371             lag,
04372             jitter,
04373             localdelay,
04374             ast_getformatname(iaxs[x]->voiceformat) );
04375          numchans++;
04376       }
04377       ast_mutex_unlock(&iaxsl[x]);
04378    }
04379    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04380    return RESULT_SUCCESS;
04381 #undef FORMAT
04382 #undef FORMAT2
04383 #undef FORMATB
04384 }
04385 
04386 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04387 {
04388    int x;
04389    int numchans = 0;
04390    for (x=0;x<IAX_MAX_CALLS;x++) {
04391       ast_mutex_lock(&iaxsl[x]);
04392       if (iaxs[x]) {
04393          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04394          char *fmt;
04395          jb_info jbinfo;
04396          
04397          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04398             jb_getinfo(iaxs[x]->jb, &jbinfo);
04399             localjitter = jbinfo.jitter;
04400             localdelay = jbinfo.current - jbinfo.min;
04401             locallost = jbinfo.frames_lost;
04402             locallosspct = jbinfo.losspct/1000;
04403             localdropped = jbinfo.frames_dropped;
04404             localooo = jbinfo.frames_ooo;
04405          } else {
04406             localjitter = -1;
04407             localdelay = 0;
04408             locallost = -1;
04409             locallosspct = -1;
04410             localdropped = 0;
04411             localooo = -1;
04412          }
04413          if (limit_fmt)
04414             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04415          else
04416             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04417          if (s)
04418             
04419             astman_append(s, fmt,
04420                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04421                      iaxs[x]->pingtime,
04422                      localjitter, 
04423                      localdelay,
04424                      locallost,
04425                      locallosspct,
04426                      localdropped,
04427                      localooo,
04428                      iaxs[x]->frames_received/1000,
04429                      iaxs[x]->remote_rr.jitter,
04430                      iaxs[x]->remote_rr.delay,
04431                      iaxs[x]->remote_rr.losscnt,
04432                      iaxs[x]->remote_rr.losspct,
04433                      iaxs[x]->remote_rr.dropped,
04434                      iaxs[x]->remote_rr.ooo,
04435                      iaxs[x]->remote_rr.packets/1000);
04436          else
04437             ast_cli(fd, fmt,
04438                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04439                iaxs[x]->pingtime,
04440                localjitter, 
04441                localdelay,
04442                locallost,
04443                locallosspct,
04444                localdropped,
04445                localooo,
04446                iaxs[x]->frames_received/1000,
04447                iaxs[x]->remote_rr.jitter,
04448                iaxs[x]->remote_rr.delay,
04449                iaxs[x]->remote_rr.losscnt,
04450                iaxs[x]->remote_rr.losspct,
04451                iaxs[x]->remote_rr.dropped,
04452                iaxs[x]->remote_rr.ooo,
04453                iaxs[x]->remote_rr.packets/1000
04454                );
04455          numchans++;
04456       }
04457       ast_mutex_unlock(&iaxsl[x]);
04458    }
04459    return numchans;
04460 }
04461 
04462 static int iax2_show_netstats(int fd, int argc, char *argv[])
04463 {
04464    int numchans = 0;
04465    if (argc != 3)
04466       return RESULT_SHOWUSAGE;
04467    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04468    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04469    numchans = ast_cli_netstats(NULL, fd, 1);
04470    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04471    return RESULT_SUCCESS;
04472 }
04473 
04474 static int iax2_do_debug(int fd, int argc, char *argv[])
04475 {
04476    if (argc < 2 || argc > 3)
04477       return RESULT_SHOWUSAGE;
04478    iaxdebug = 1;
04479    ast_cli(fd, "IAX2 Debugging Enabled\n");
04480    return RESULT_SUCCESS;
04481 }
04482 
04483 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04484 {
04485    if (argc < 3 || argc > 4)
04486       return RESULT_SHOWUSAGE;
04487    iaxtrunkdebug = 1;
04488    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04489    return RESULT_SUCCESS;
04490 }
04491 
04492 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04493 {
04494    if (argc < 3 || argc > 4)
04495       return RESULT_SHOWUSAGE;
04496    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04497    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04498    return RESULT_SUCCESS;
04499 }
04500 
04501 static int iax2_no_debug(int fd, int argc, char *argv[])
04502 {
04503    if (argc < 3 || argc > 4)
04504       return RESULT_SHOWUSAGE;
04505    iaxdebug = 0;
04506    ast_cli(fd, "IAX2 Debugging Disabled\n");
04507    return RESULT_SUCCESS;
04508 }
04509 
04510 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04511 {
04512    if (argc < 4 || argc > 5)
04513       return RESULT_SHOWUSAGE;
04514    iaxtrunkdebug = 0;
04515    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04516    return RESULT_SUCCESS;
04517 }
04518 
04519 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04520 {
04521    if (argc < 4 || argc > 5)
04522       return RESULT_SHOWUSAGE;
04523    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04524    jb_debug_output("\n");
04525    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04526    return RESULT_SUCCESS;
04527 }
04528 
04529 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04530 {
04531    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04532    int res = -1;
04533    ast_mutex_lock(&iaxsl[callno]);
04534    if (iaxs[callno]) {
04535    /* If there's an outstanding error, return failure now */
04536       if (!iaxs[callno]->error) {
04537          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04538             res = 0;
04539             /* Don't waste bandwidth sending null frames */
04540          else if (f->frametype == AST_FRAME_NULL)
04541             res = 0;
04542          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04543             res = 0;
04544          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04545             res = 0;
04546          else
04547          /* Simple, just queue for transmission */
04548             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04549       } else {
04550          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04551       }
04552    }
04553    /* If it's already gone, just return */
04554    ast_mutex_unlock(&iaxsl[callno]);
04555    return res;
04556 }
04557 
04558 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04559       int now, int transfer, int final)
04560 {
04561    struct ast_frame f = { 0, };
04562 
04563    f.frametype = type;
04564    f.subclass = command;
04565    f.datalen = datalen;
04566    f.src = __FUNCTION__;
04567    f.data = (void *) data;
04568 
04569    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04570 }
04571 
04572 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04573 {
04574    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04575 }
04576 
04577 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04578 {
04579    int res;
04580    ast_mutex_lock(&iaxsl[callno]);
04581    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04582    ast_mutex_unlock(&iaxsl[callno]);
04583    return res;
04584 }
04585 
04586 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)
04587 {
04588    /* It is assumed that the callno has already been locked */
04589    iax2_predestroy(i->callno);
04590    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04591 }
04592 
04593 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)
04594 {
04595    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04596 }
04597 
04598 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04599 {
04600    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04601 }
04602 
04603 static int apply_context(struct iax2_context *con, const char *context)
04604 {
04605    while(con) {
04606       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04607          return -1;
04608       con = con->next;
04609    }
04610    return 0;
04611 }
04612 
04613 
04614 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04615 {
04616    /* Start pessimistic */
04617    int res = -1;
04618    int version = 2;
04619    struct iax2_user *user = NULL, *best = NULL;
04620    int bestscore = 0;
04621    int gotcapability = 0;
04622    struct ast_variable *v = NULL, *tmpvar = NULL;
04623 
04624    if (!iaxs[callno])
04625       return res;
04626    if (ies->called_number)
04627       ast_string_field_set(iaxs[callno], exten, ies->called_number);
04628    if (ies->calling_number) {
04629       ast_shrink_phone_number(ies->calling_number);
04630       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04631    }
04632    if (ies->calling_name)
04633       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04634    if (ies->calling_ani)
04635       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04636    if (ies->dnid)
04637       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04638    if (ies->rdnis)
04639       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04640    if (ies->called_context)
04641       ast_string_field_set(iaxs[callno], context, ies->called_context);
04642    if (ies->language)
04643       ast_string_field_set(iaxs[callno], language, ies->language);
04644    if (ies->username)
04645       ast_string_field_set(iaxs[callno], username, ies->username);
04646    if (ies->calling_ton > -1)
04647       iaxs[callno]->calling_ton = ies->calling_ton;
04648    if (ies->calling_tns > -1)
04649       iaxs[callno]->calling_tns = ies->calling_tns;
04650    if (ies->calling_pres > -1)
04651       iaxs[callno]->calling_pres = ies->calling_pres;
04652    if (ies->format)
04653       iaxs[callno]->peerformat = ies->format;
04654    if (ies->adsicpe)
04655       iaxs[callno]->peeradsicpe = ies->adsicpe;
04656    if (ies->capability) {
04657       gotcapability = 1;
04658       iaxs[callno]->peercapability = ies->capability;
04659    } 
04660    if (ies->version)
04661       version = ies->version;
04662 
04663    /* Use provided preferences until told otherwise for actual preferences */
04664    if(ies->codec_prefs) {
04665       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04666       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04667    }
04668 
04669    if (!gotcapability) 
04670       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04671    if (version > IAX_PROTO_VERSION) {
04672       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04673          ast_inet_ntoa(sin->sin_addr), version);
04674       return res;
04675    }
04676    /* Search the userlist for a compatible entry, and fill in the rest */
04677    AST_LIST_LOCK(&users);
04678    AST_LIST_TRAVERSE(&users, user, entry) {
04679       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04680          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04681          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04682          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04683               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04684          if (!ast_strlen_zero(iaxs[callno]->username)) {
04685             /* Exact match, stop right now. */
04686             best = user;
04687             break;
04688          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04689             /* No required authentication */
04690             if (user->ha) {
04691                /* There was host authentication and we passed, bonus! */
04692                if (bestscore < 4) {
04693                   bestscore = 4;
04694                   best = user;
04695                }
04696             } else {
04697                /* No host access, but no secret, either, not bad */
04698                if (bestscore < 3) {
04699                   bestscore = 3;
04700                   best = user;
04701                }
04702             }
04703          } else {
04704             if (user->ha) {
04705                /* Authentication, but host access too, eh, it's something.. */
04706                if (bestscore < 2) {
04707                   bestscore = 2;
04708                   best = user;
04709                }
04710             } else {
04711                /* Authentication and no host access...  This is our baseline */
04712                if (bestscore < 1) {
04713                   bestscore = 1;
04714                   best = user;
04715                }
04716             }
04717          }
04718       }
04719    }
04720    AST_LIST_UNLOCK(&users);
04721    user = best;
04722    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04723       user = realtime_user(iaxs[callno]->username);
04724       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
04725           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
04726          destroy_user(user);
04727          user = NULL;
04728       }
04729    }
04730    if (user) {
04731       /* We found our match (use the first) */
04732       /* copy vars */
04733       for (v = user->vars ; v ; v = v->next) {
04734          if((tmpvar = ast_variable_new(v->name, v->value))) {
04735             tmpvar->next = iaxs[callno]->vars; 
04736             iaxs[callno]->vars = tmpvar;
04737          }
04738       }
04739       /* If a max AUTHREQ restriction is in place, activate it */
04740       if (user->maxauthreq > 0)
04741          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04742       iaxs[callno]->prefs = user->prefs;
04743       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04744       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04745       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04746       iaxs[callno]->encmethods = user->encmethods;
04747       /* Store the requested username if not specified */
04748       if (ast_strlen_zero(iaxs[callno]->username))
04749          ast_string_field_set(iaxs[callno], username, user->name);
04750       /* Store whether this is a trunked call, too, of course, and move if appropriate */
04751       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04752       iaxs[callno]->capability = user->capability;
04753       /* And use the default context */
04754       if (ast_strlen_zero(iaxs[callno]->context)) {
04755          if (user->contexts)
04756             ast_string_field_set(iaxs[callno], context, user->contexts->context);
04757          else
04758             ast_string_field_set(iaxs[callno], context, context);
04759       }
04760       /* And any input keys */
04761       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
04762       /* And the permitted authentication methods */
04763       iaxs[callno]->authmethods = user->authmethods;
04764       iaxs[callno]->adsi = user->adsi;
04765       /* If they have callerid, override the given caller id.  Always store the ANI */
04766       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
04767          if (ast_test_flag(user, IAX_HASCALLERID)) {
04768             iaxs[callno]->calling_tns = 0;
04769             iaxs[callno]->calling_ton = 0;
04770             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
04771             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
04772             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
04773          }
04774          if (ast_strlen_zero(iaxs[callno]->ani))
04775             ast_string_field_set(iaxs[callno], ani, user->cid_num);
04776       } else {
04777          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
04778       }
04779       if (!ast_strlen_zero(user->accountcode))
04780          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
04781       if (!ast_strlen_zero(user->mohinterpret))
04782          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
04783       if (!ast_strlen_zero(user->mohsuggest))
04784          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
04785       if (user->amaflags)
04786          iaxs[callno]->amaflags = user->amaflags;
04787       if (!ast_strlen_zero(user->language))
04788          ast_string_field_set(iaxs[callno], language, user->language);
04789       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
04790       /* Keep this check last */
04791       if (!ast_strlen_zero(user->dbsecret)) {
04792          char *family, *key=NULL;
04793          char buf[80];
04794          family = ast_strdupa(user->dbsecret);
04795          key = strchr(family, '/');
04796          if (key) {
04797             *key = '\0';
04798             key++;
04799          }
04800          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
04801             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
04802          else
04803             ast_string_field_set(iaxs[callno], secret, buf);
04804       } else
04805          ast_string_field_set(iaxs[callno], secret, user->secret);
04806       if (ast_test_flag(user, IAX_TEMPONLY))
04807          destroy_user(user);
04808       res = 0;
04809    }
04810    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
04811    return res;
04812 }
04813 
04814 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
04815 {
04816    struct ast_iax2_full_hdr fh;
04817    fh.scallno = htons(src | IAX_FLAG_FULL);
04818    fh.dcallno = htons(dst);
04819    fh.ts = 0;
04820    fh.oseqno = 0;
04821    fh.iseqno = 0;
04822    fh.type = AST_FRAME_IAX;
04823    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04824    if (iaxdebug)
04825        iax_showframe(NULL, &fh, 0, sin, 0);
04826 #if 0
04827    if (option_debug)
04828 #endif   
04829       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04830          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
04831    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04832 }
04833 
04834 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
04835 {
04836    /* Select exactly one common encryption if there are any */
04837    p->encmethods &= enc;
04838    if (p->encmethods) {
04839       if (p->encmethods & IAX_ENCRYPT_AES128)
04840          p->encmethods = IAX_ENCRYPT_AES128;
04841       else
04842          p->encmethods = 0;
04843    }
04844 }
04845 
04846 static int authenticate_request(struct chan_iax2_pvt *p)
04847 {
04848    struct iax2_user *user = NULL;
04849    struct iax_ie_data ied;
04850    int res = -1, authreq_restrict = 0;
04851    char challenge[10];
04852 
04853    memset(&ied, 0, sizeof(ied));
04854 
04855    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04856    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04857       AST_LIST_LOCK(&users);
04858       AST_LIST_TRAVERSE(&users, user, entry) {
04859          if (!strcmp(user->name, p->username)) {
04860             if (user->curauthreq == user->maxauthreq)
04861                authreq_restrict = 1;
04862             else
04863                user->curauthreq++;
04864             break;
04865          }
04866       }
04867       AST_LIST_UNLOCK(&users);
04868    }
04869 
04870    /* If the AUTHREQ limit test failed, send back an error */
04871    if (authreq_restrict) {
04872       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04873       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04874       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
04875       return 0;
04876    }
04877 
04878    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04879    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04880       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
04881       ast_string_field_set(p, challenge, challenge);
04882       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
04883       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04884    }
04885    if (p->encmethods)
04886       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04887 
04888    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
04889 
04890    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
04891 
04892    if (p->encmethods)
04893       ast_set_flag(p, IAX_ENCRYPTED);
04894 
04895    return res;
04896 }
04897 
04898 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
04899 {
04900    char requeststr[256];
04901    char md5secret[256] = "";
04902    char secret[256] = "";
04903    char rsasecret[256] = "";
04904    int res = -1; 
04905    int x;
04906    struct iax2_user *user = NULL;
04907 
04908    AST_LIST_LOCK(&users);
04909    AST_LIST_TRAVERSE(&users, user, entry) {
04910       if (!strcmp(user->name, p->username))
04911          break;
04912    }
04913    if (user) {
04914       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04915          user->curauthreq--;
04916          ast_clear_flag(p, IAX_MAXAUTHREQ);
04917       }
04918       ast_string_field_set(p, host, user->name);
04919    }
04920    AST_LIST_UNLOCK(&users);
04921 
04922    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
04923       return res;
04924    if (ies->password)
04925       ast_copy_string(secret, ies->password, sizeof(secret));
04926    if (ies->md5_result)
04927       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04928    if (ies->rsa_result)
04929       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04930    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
04931       struct ast_key *key;
04932       char *keyn;
04933       char tmpkey[256];
04934       char *stringp=NULL;
04935       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
04936       stringp=tmpkey;
04937       keyn = strsep(&stringp, ":");
04938       while(keyn) {
04939          key = ast_key_get(keyn, AST_KEY_PUBLIC);
04940          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
04941             res = 0;
04942             break;
04943          } else if (!key)
04944             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
04945          keyn = strsep(&stringp, ":");
04946       }
04947    } else if (p->authmethods & IAX_AUTH_MD5) {
04948       struct MD5Context md5;
04949       unsigned char digest[16];
04950       char *tmppw, *stringp;
04951       
04952       tmppw = ast_strdupa(p->secret);
04953       stringp = tmppw;
04954       while((tmppw = strsep(&stringp, ";"))) {
04955          MD5Init(&md5);
04956          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
04957          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04958          MD5Final(digest, &md5);
04959          /* If they support md5, authenticate with it.  */
04960          for (x=0;x<16;x++)
04961             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
04962          if (!strcasecmp(requeststr, md5secret)) {
04963             res = 0;
04964             break;
04965          }
04966       }
04967    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
04968       if (!strcmp(secret, p->secret))
04969          res = 0;
04970    }
04971    return res;
04972 }
04973 
04974 /*! \brief Verify inbound registration */
04975 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04976 {
04977    char requeststr[256] = "";
04978    char peer[256] = "";
04979    char md5secret[256] = "";
04980    char rsasecret[256] = "";
04981    char secret[256] = "";
04982    struct iax2_peer *p;
04983    struct ast_key *key;
04984    char *keyn;
04985    int x;
04986    int expire = 0;
04987 
04988    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
04989    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
04990    if (ies->username)
04991       ast_copy_string(peer, ies->username, sizeof(peer));
04992    if (ies->password)
04993       ast_copy_string(secret, ies->password, sizeof(secret));
04994    if (ies->md5_result)
04995       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04996    if (ies->rsa_result)
04997       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04998    if (ies->refresh)
04999       expire = ies->refresh;
05000 
05001    if (ast_strlen_zero(peer)) {
05002       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05003       return -1;
05004    }
05005 
05006    /* SLD: first call to lookup peer during registration */
05007    p = find_peer(peer, 1);
05008 
05009    if (!p) {
05010       if (authdebug)
05011          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05012       return -1;
05013    }
05014 
05015    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05016       if (authdebug)
05017          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05018       if (ast_test_flag(p, IAX_TEMPONLY))
05019          destroy_peer(p);
05020       return -1;
05021    }
05022 
05023    if (!ast_apply_ha(p->ha, sin)) {
05024       if (authdebug)
05025          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05026       if (ast_test_flag(p, IAX_TEMPONLY))
05027          destroy_peer(p);
05028       return -1;
05029    }
05030    if (!inaddrcmp(&p->addr, sin))
05031       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05032    ast_string_field_set(iaxs[callno], secret, p->secret);
05033    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05034    /* Check secret against what we have on file */
05035    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05036       if (!ast_strlen_zero(p->inkeys)) {
05037          char tmpkeys[256];
05038          char *stringp=NULL;
05039          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05040          stringp=tmpkeys;
05041          keyn = strsep(&stringp, ":");
05042          while(keyn) {
05043             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05044             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05045                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05046                break;
05047             } else if (!key) 
05048                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05049             keyn = strsep(&stringp, ":");
05050          }
05051          if (!keyn) {
05052             if (authdebug)
05053                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05054             if (ast_test_flag(p, IAX_TEMPONLY))
05055                destroy_peer(p);
05056             return -1;
05057          }
05058       } else {
05059          if (authdebug)
05060             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05061          if (ast_test_flag(p, IAX_TEMPONLY))
05062             destroy_peer(p);
05063          return -1;
05064       }
05065    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05066       struct MD5Context md5;
05067       unsigned char digest[16];
05068       char *tmppw, *stringp;
05069       
05070       tmppw = ast_strdupa(p->secret);
05071       stringp = tmppw;
05072       while((tmppw = strsep(&stringp, ";"))) {
05073          MD5Init(&md5);
05074          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05075          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05076          MD5Final(digest, &md5);
05077          for (x=0;x<16;x++)
05078             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05079          if (!strcasecmp(requeststr, md5secret)) 
05080             break;
05081       }
05082       if (tmppw) {
05083          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05084       } else {
05085          if (authdebug)
05086             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05087          if (ast_test_flag(p, IAX_TEMPONLY))
05088             destroy_peer(p);
05089          return -1;
05090       }
05091    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05092       /* They've provided a plain text password and we support that */
05093       if (strcmp(secret, p->secret)) {
05094          if (authdebug)
05095             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05096          if (ast_test_flag(p, IAX_TEMPONLY))
05097             destroy_peer(p);
05098          return -1;
05099       } else
05100          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05101    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05102       if (authdebug)
05103          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05104       if (ast_test_flag(p, IAX_TEMPONLY))
05105          destroy_peer(p);
05106       return -1;
05107    }
05108    ast_string_field_set(iaxs[callno], peer, peer);
05109    /* Choose lowest expiry number */
05110    if (expire && (expire < iaxs[callno]->expiry)) 
05111       iaxs[callno]->expiry = expire;
05112 
05113    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05114 
05115    if (ast_test_flag(p, IAX_TEMPONLY))
05116       destroy_peer(p);
05117    return 0;
05118    
05119 }
05120 
05121 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)
05122 {
05123    int res = -1;
05124    int x;
05125    if (!ast_strlen_zero(keyn)) {
05126       if (!(authmethods & IAX_AUTH_RSA)) {
05127          if (ast_strlen_zero(secret)) 
05128             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));
05129       } else if (ast_strlen_zero(challenge)) {
05130          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05131       } else {
05132          char sig[256];
05133          struct ast_key *key;
05134          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05135          if (!key) {
05136             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05137          } else {
05138             if (ast_sign(key, (char*)challenge, sig)) {
05139                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05140                res = -1;
05141             } else {
05142                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05143                res = 0;
05144             }
05145          }
05146       }
05147    } 
05148    /* Fall back */
05149    if (res && !ast_strlen_zero(secret)) {
05150       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05151          struct MD5Context md5;
05152          unsigned char digest[16];
05153          char digres[128];
05154          MD5Init(&md5);
05155          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05156          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05157          MD5Final(digest, &md5);
05158          /* If they support md5, authenticate with it.  */
05159          for (x=0;x<16;x++)
05160             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05161          if (ecx && dcx)
05162             build_enc_keys(digest, ecx, dcx);
05163          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05164          res = 0;
05165       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05166          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05167          res = 0;
05168       } else
05169          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05170    }
05171    return res;
05172 }
05173 
05174 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05175 {
05176    struct iax2_peer *peer = NULL;
05177    /* Start pessimistic */
05178    int res = -1;
05179    int authmethods = 0;
05180    struct iax_ie_data ied;
05181    
05182    memset(&ied, 0, sizeof(ied));
05183    
05184    if (ies->username)
05185       ast_string_field_set(p, username, ies->username);
05186    if (ies->challenge)
05187       ast_string_field_set(p, challenge, ies->challenge);
05188    if (ies->authmethods)
05189       authmethods = ies->authmethods;
05190    if (authmethods & IAX_AUTH_MD5)
05191       merge_encryption(p, ies->encmethods);
05192    else
05193       p->encmethods = 0;
05194 
05195    /* Check for override RSA authentication first */
05196    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05197       /* Normal password authentication */
05198       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05199    } else {
05200       AST_LIST_LOCK(&peers);
05201       AST_LIST_TRAVERSE(&peers, peer, entry) {
05202          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05203              /* No peer specified at our end, or this is the peer */
05204              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05205              /* No username specified in peer rule, or this is the right username */
05206              && (!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)))
05207              /* No specified host, or this is our host */
05208             ) {
05209             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05210             if (!res)
05211                break;   
05212          }
05213       }
05214       AST_LIST_UNLOCK(&peers);
05215       if (!peer) {
05216          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05217             that we're trying to authenticate *to* a realtime peer */
05218          if ((peer = realtime_peer(p->peer, NULL))) {
05219             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05220             if (ast_test_flag(peer, IAX_TEMPONLY))
05221                destroy_peer(peer);
05222          }
05223       }
05224    }
05225    if (ies->encmethods)
05226       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05227    if (!res)
05228       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05229    return res;
05230 }
05231 
05232 static int iax2_do_register(struct iax2_registry *reg);
05233 
05234 static void __iax2_do_register_s(void *data)
05235 {
05236    struct iax2_registry *reg = data;
05237    reg->expire = -1;
05238    iax2_do_register(reg);
05239 }
05240 
05241 static int iax2_do_register_s(void *data)
05242 {
05243 #ifdef SCHED_MULTITHREADED
05244    if (schedule_action(__iax2_do_register_s, data))
05245 #endif      
05246       __iax2_do_register_s(data);
05247    return 0;
05248 }
05249 
05250 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05251 {
05252    int newcall = 0;
05253    char newip[256];
05254    struct iax_ie_data ied;
05255    struct sockaddr_in new;
05256    
05257    
05258    memset(&ied, 0, sizeof(ied));
05259    if (ies->apparent_addr)
05260       bcopy(ies->apparent_addr, &new, sizeof(new));
05261    if (ies->callno)
05262       newcall = ies->callno;
05263    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05264       ast_log(LOG_WARNING, "Invalid transfer request\n");
05265       return -1;
05266    }
05267    pvt->transfercallno = newcall;
05268    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05269    inet_aton(newip, &pvt->transfer.sin_addr);
05270    pvt->transfer.sin_family = AF_INET;
05271    pvt->transferring = TRANSFER_BEGIN;
05272    pvt->transferid = ies->transferid;
05273    if (ies->transferid)
05274       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05275    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05276    return 0; 
05277 }
05278 
05279 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05280 {
05281    char exten[256] = "";
05282    int status = CACHE_FLAG_UNKNOWN;
05283    int expiry = iaxdefaultdpcache;
05284    int x;
05285    int matchmore = 0;
05286    struct iax2_dpcache *dp, *prev;
05287    
05288    if (ies->called_number)
05289       ast_copy_string(exten, ies->called_number, sizeof(exten));
05290 
05291    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05292       status = CACHE_FLAG_EXISTS;
05293    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05294       status = CACHE_FLAG_CANEXIST;
05295    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05296       status = CACHE_FLAG_NONEXISTENT;
05297 
05298    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05299       /* Don't really do anything with this */
05300    }
05301    if (ies->refresh)
05302       expiry = ies->refresh;
05303    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05304       matchmore = CACHE_FLAG_MATCHMORE;
05305    ast_mutex_lock(&dpcache_lock);
05306    prev = NULL;
05307    dp = pvt->dpentries;
05308    while(dp) {
05309       if (!strcmp(dp->exten, exten)) {
05310          /* Let them go */
05311          if (prev)
05312             prev->peer = dp->peer;
05313          else
05314             pvt->dpentries = dp->peer;
05315          dp->peer = NULL;
05316          dp->callno = 0;
05317          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05318          if (dp->flags & CACHE_FLAG_PENDING) {
05319             dp->flags &= ~CACHE_FLAG_PENDING;
05320             dp->flags |= status;
05321             dp->flags |= matchmore;
05322          }
05323          /* Wake up waiters */
05324          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05325             if (dp->waiters[x] > -1)
05326                write(dp->waiters[x], "asdf", 4);
05327       }
05328       prev = dp;
05329       dp = dp->peer;
05330    }
05331    ast_mutex_unlock(&dpcache_lock);
05332    return 0;
05333 }
05334 
05335 static int complete_transfer(int callno, struct iax_ies *ies)
05336 {
05337    int peercallno = 0;
05338    struct chan_iax2_pvt *pvt = iaxs[callno];
05339    struct iax_frame *cur;
05340    jb_frame frame;
05341 
05342    if (ies->callno)
05343       peercallno = ies->callno;
05344 
05345    if (peercallno < 1) {
05346       ast_log(LOG_WARNING, "Invalid transfer request\n");
05347       return -1;
05348    }
05349    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05350    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05351    /* Reset sequence numbers */
05352    pvt->oseqno = 0;
05353    pvt->rseqno = 0;
05354    pvt->iseqno = 0;
05355    pvt->aseqno = 0;
05356    pvt->peercallno = peercallno;
05357    pvt->transferring = TRANSFER_NONE;
05358    pvt->svoiceformat = -1;
05359    pvt->voiceformat = 0;
05360    pvt->svideoformat = -1;
05361    pvt->videoformat = 0;
05362    pvt->transfercallno = -1;
05363    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05364    memset(&pvt->offset, 0, sizeof(pvt->offset));
05365    /* reset jitterbuffer */
05366    while(jb_getall(pvt->jb,&frame) == JB_OK)
05367       iax2_frame_free(frame.data);
05368    jb_reset(pvt->jb);
05369    pvt->lag = 0;
05370    pvt->last = 0;
05371    pvt->lastsent = 0;
05372    pvt->nextpred = 0;
05373    pvt->pingtime = DEFAULT_RETRY_TIME;
05374    AST_LIST_LOCK(&iaxq.queue);
05375    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05376       /* We must cancel any packets that would have been transmitted
05377          because now we're talking to someone new.  It's okay, they
05378          were transmitted to someone that didn't care anyway. */
05379       if (callno == cur->callno) 
05380          cur->retries = -1;
05381    }
05382    AST_LIST_UNLOCK(&iaxq.queue);
05383    return 0; 
05384 }
05385 
05386 /*! \brief Acknowledgment received for OUR registration */
05387 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05388 {
05389    struct iax2_registry *reg;
05390    /* Start pessimistic */
05391    char peer[256] = "";
05392    char msgstatus[60];
05393    int refresh = 60;
05394    char ourip[256] = "<Unspecified>";
05395    struct sockaddr_in oldus;
05396    struct sockaddr_in us;
05397    int oldmsgs;
05398 
05399    memset(&us, 0, sizeof(us));
05400    if (ies->apparent_addr)
05401       bcopy(ies->apparent_addr, &us, sizeof(us));
05402    if (ies->username)
05403       ast_copy_string(peer, ies->username, sizeof(peer));
05404    if (ies->refresh)
05405       refresh = ies->refresh;
05406    if (ies->calling_number) {
05407       /* We don't do anything with it really, but maybe we should */
05408    }
05409    reg = iaxs[callno]->reg;
05410    if (!reg) {
05411       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05412       return -1;
05413    }
05414    memcpy(&oldus, &reg->us, sizeof(oldus));
05415    oldmsgs = reg->messages;
05416    if (inaddrcmp(&reg->addr, sin)) {
05417       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05418       return -1;
05419    }
05420    memcpy(&reg->us, &us, sizeof(reg->us));
05421    if (ies->msgcount >= 0)
05422       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05423    /* always refresh the registration at the interval requested by the server
05424       we are registering to
05425    */
05426    reg->refresh = refresh;
05427    if (reg->expire > -1)
05428       ast_sched_del(sched, reg->expire);
05429    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05430    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05431       if (option_verbose > 2) {
05432          if (reg->messages > 255)
05433             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05434          else if (reg->messages > 1)
05435             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05436          else if (reg->messages > 0)
05437             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05438          else
05439             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05440          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05441          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05442       }
05443       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05444    }
05445    reg->regstate = REG_STATE_REGISTERED;
05446    return 0;
05447 }
05448 
05449 static int iax2_register(char *value, int lineno)
05450 {
05451    struct iax2_registry *reg;
05452    char copy[256];
05453    char *username, *hostname, *secret;
05454    char *porta;
05455    char *stringp=NULL;
05456    
05457    if (!value)
05458       return -1;
05459    ast_copy_string(copy, value, sizeof(copy));
05460    stringp=copy;
05461    username = strsep(&stringp, "@");
05462    hostname = strsep(&stringp, "@");
05463    if (!hostname) {
05464       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05465       return -1;
05466    }
05467    stringp=username;
05468    username = strsep(&stringp, ":");
05469    secret = strsep(&stringp, ":");
05470    stringp=hostname;
05471    hostname = strsep(&stringp, ":");
05472    porta = strsep(&stringp, ":");
05473    
05474    if (porta && !atoi(porta)) {
05475       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05476       return -1;
05477    }
05478    if (!(reg = ast_calloc(1, sizeof(*reg))))
05479       return -1;
05480    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05481       free(reg);
05482       return -1;
05483    }
05484    ast_copy_string(reg->username, username, sizeof(reg->username));
05485    if (secret)
05486       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05487    reg->expire = -1;
05488    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05489    reg->addr.sin_family = AF_INET;
05490    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05491    AST_LIST_LOCK(&registrations);
05492    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05493    AST_LIST_UNLOCK(&registrations);
05494    
05495    return 0;
05496 }
05497 
05498 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05499 {
05500    char multi[256];
05501    char *stringp, *ext;
05502    if (!ast_strlen_zero(regcontext)) {
05503       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05504       stringp = multi;
05505       while((ext = strsep(&stringp, "&"))) {
05506          if (onoff) {
05507             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05508                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05509                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05510          } else
05511             ast_context_remove_extension(regcontext, ext, 1, NULL);
05512       }
05513    }
05514 }
05515 static void prune_peers(void);
05516 
05517 static void __expire_registry(void *data)
05518 {
05519    char *name = data;
05520    struct iax2_peer *p = NULL;
05521 
05522    /* Go through and grab this peer... and if it needs to be removed... then do it */
05523    AST_LIST_LOCK(&peers);
05524    AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
05525       if (!strcasecmp(p->name, name)) {
05526          p->expire = -1;
05527          break;
05528       }
05529    }
05530    AST_LIST_TRAVERSE_SAFE_END
05531    AST_LIST_UNLOCK(&peers);
05532 
05533    /* Peer is already gone for whatever reason */
05534    if (!p)
05535       return;
05536 
05537    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05538    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05539       realtime_update_peer(p->name, &p->addr, 0);
05540    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
05541    /* Reset the address */
05542    memset(&p->addr, 0, sizeof(p->addr));
05543    /* Reset expiry value */
05544    p->expiry = min_reg_expire;
05545    if (!ast_test_flag(p, IAX_TEMPONLY))
05546       ast_db_del("IAX/Registry", p->name);
05547    register_peer_exten(p, 0);
05548    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05549    if (iax2_regfunk)
05550       iax2_regfunk(p->name, 0);
05551 
05552    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05553       ast_set_flag(p, IAX_DELME);
05554       prune_peers();
05555    }
05556 }
05557 
05558 static int expire_registry(void *data)
05559 {
05560 #ifdef SCHED_MULTITHREADED
05561    if (schedule_action(__expire_registry, data))
05562 #endif      
05563       __expire_registry(data);
05564    return 0;
05565 }
05566 
05567 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05568 
05569 static void reg_source_db(struct iax2_peer *p)
05570 {
05571    char data[80];
05572    struct in_addr in;
05573    char *c, *d;
05574    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05575       c = strchr(data, ':');
05576       if (c) {
05577          *c = '\0';
05578          c++;
05579          if (inet_aton(data, &in)) {
05580             d = strchr(c, ':');
05581             if (d) {
05582                *d = '\0';
05583                d++;
05584                if (option_verbose > 2)
05585                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05586                   ast_inet_ntoa(in), atoi(c), atoi(d));
05587                iax2_poke_peer(p, 0);
05588                p->expiry = atoi(d);
05589                memset(&p->addr, 0, sizeof(p->addr));
05590                p->addr.sin_family = AF_INET;
05591                p->addr.sin_addr = in;
05592                p->addr.sin_port = htons(atoi(c));
05593                if (p->expire > -1)
05594                   ast_sched_del(sched, p->expire);
05595                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05596                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05597                if (iax2_regfunk)
05598                   iax2_regfunk(p->name, 1);
05599                register_peer_exten(p, 1);
05600             }              
05601                
05602          }
05603       }
05604    }
05605 }
05606 
05607 static int update_registry(const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05608 {
05609    /* Called from IAX thread only, with proper iaxsl lock */
05610    struct iax_ie_data ied;
05611    struct iax2_peer *p;
05612    int msgcount;
05613    char data[80];
05614    int version;
05615 
05616    memset(&ied, 0, sizeof(ied));
05617 
05618    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05619    if (!(p = find_peer(name, 1))) {
05620       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05621       return -1;
05622    }
05623 
05624    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05625       if (sin->sin_addr.s_addr) {
05626          time_t nowtime;
05627          time(&nowtime);
05628          realtime_update_peer(name, sin, nowtime);
05629       } else {
05630          realtime_update_peer(name, sin, 0);
05631       }
05632    }
05633    if (inaddrcmp(&p->addr, sin)) {
05634       if (iax2_regfunk)
05635          iax2_regfunk(p->name, 1);
05636       /* Stash the IP address from which they registered */
05637       memcpy(&p->addr, sin, sizeof(p->addr));
05638       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05639       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05640          ast_db_put("IAX/Registry", p->name, data);
05641          if  (option_verbose > 2)
05642             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05643                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
05644          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05645          register_peer_exten(p, 1);
05646          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05647       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05648          if  (option_verbose > 2)
05649             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05650                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05651          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05652          register_peer_exten(p, 0);
05653          ast_db_del("IAX/Registry", p->name);
05654          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05655       }
05656       /* Update the host */
05657       /* Verify that the host is really there */
05658       iax2_poke_peer(p, callno);
05659    }     
05660 
05661    /* Make sure our call still exists, an INVAL at the right point may make it go away */
05662    if (!iaxs[callno])
05663       return 0;
05664 
05665    /* Store socket fd */
05666    p->sockfd = fd;
05667    /* Setup the expiry */
05668    if (p->expire > -1)
05669       ast_sched_del(sched, p->expire);
05670    /* treat an unspecified refresh interval as the minimum */
05671    if (!refresh)
05672       refresh = min_reg_expire;
05673    if (refresh > max_reg_expire) {
05674       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05675          p->name, max_reg_expire, refresh);
05676       p->expiry = max_reg_expire;
05677    } else if (refresh < min_reg_expire) {
05678       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05679          p->name, min_reg_expire, refresh);
05680       p->expiry = min_reg_expire;
05681    } else {
05682       p->expiry = refresh;
05683    }
05684    if (p->expiry && sin->sin_addr.s_addr)
05685       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05686    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05687    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05688    if (sin->sin_addr.s_addr) {
05689       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05690       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05691       if (!ast_strlen_zero(p->mailbox)) {
05692          int new, old;
05693          ast_app_inboxcount(p->mailbox, &new, &old);
05694          if (new > 255)
05695             new = 255;
05696          if (old > 255)
05697             old = 255;
05698          msgcount = (old << 8) | new;
05699          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05700       }
05701       if (ast_test_flag(p, IAX_HASCALLERID)) {
05702          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05703          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05704       }
05705    }
05706    version = iax_check_version(devtype);
05707    if (version) 
05708       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05709    if (ast_test_flag(p, IAX_TEMPONLY))
05710       destroy_peer(p);
05711    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05712 }
05713 
05714 static int registry_authrequest(const char *name, int callno)
05715 {
05716    struct iax_ie_data ied;
05717    struct iax2_peer *p;
05718    char challenge[10];
05719    /* SLD: third call to find_peer in registration */
05720    p = find_peer(name, 1);
05721    if (p) {
05722       memset(&ied, 0, sizeof(ied));
05723       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05724       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05725          /* Build the challenge */
05726          snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05727          ast_string_field_set(iaxs[callno], challenge, challenge);
05728          /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
05729          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05730       }
05731       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05732       if (ast_test_flag(p, IAX_TEMPONLY))
05733          destroy_peer(p);
05734       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05735    } 
05736    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05737    return 0;
05738 }
05739 
05740 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
05741 {
05742    struct iax2_registry *reg;
05743    /* Start pessimistic */
05744    struct iax_ie_data ied;
05745    char peer[256] = "";
05746    char challenge[256] = "";
05747    int res;
05748    int authmethods = 0;
05749    if (ies->authmethods)
05750       authmethods = ies->authmethods;
05751    if (ies->username)
05752       ast_copy_string(peer, ies->username, sizeof(peer));
05753    if (ies->challenge)
05754       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05755    memset(&ied, 0, sizeof(ied));
05756    reg = iaxs[callno]->reg;
05757    if (reg) {
05758          if (inaddrcmp(&reg->addr, sin)) {
05759             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05760             return -1;
05761          }
05762          if (ast_strlen_zero(reg->secret)) {
05763             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05764             reg->regstate = REG_STATE_NOAUTH;
05765             return -1;
05766          }
05767          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05768          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05769          if (reg->secret[0] == '[') {
05770             char tmpkey[256];
05771             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05772             tmpkey[strlen(tmpkey) - 1] = '\0';
05773             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05774          } else
05775             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05776          if (!res) {
05777             reg->regstate = REG_STATE_AUTHSENT;
05778             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05779          } else
05780             return -1;
05781          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05782    } else   
05783       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05784    return -1;
05785 }
05786 
05787 static void stop_stuff(int callno)
05788 {
05789    iax2_destroy_helper(iaxs[callno]);
05790 }
05791 
05792 static void __auth_reject(void *nothing)
05793 {
05794    /* Called from IAX thread only, without iaxs lock */
05795    int callno = (int)(long)(nothing);
05796    struct iax_ie_data ied;
05797    ast_mutex_lock(&iaxsl[callno]);
05798    if (iaxs[callno]) {
05799       memset(&ied, 0, sizeof(ied));
05800       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05801          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05802          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05803       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05804          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05805          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05806       }
05807       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05808    }
05809    ast_mutex_unlock(&iaxsl[callno]);
05810 }
05811 
05812 static int auth_reject(void *data)
05813 {
05814    int callno = (int)(long)(data);
05815    ast_mutex_lock(&iaxsl[callno]);
05816    if (iaxs[callno])
05817       iaxs[callno]->authid = -1;
05818    ast_mutex_unlock(&iaxsl[callno]);
05819 #ifdef SCHED_MULTITHREADED
05820    if (schedule_action(__auth_reject, data))
05821 #endif      
05822       __auth_reject(data);
05823    return 0;
05824 }
05825 
05826 static int auth_fail(int callno, int failcode)
05827 {
05828    /* Schedule sending the authentication failure in one second, to prevent
05829       guessing */
05830    ast_mutex_lock(&iaxsl[callno]);
05831    if (iaxs[callno]) {
05832       iaxs[callno]->authfail = failcode;
05833       if (delayreject) {
05834          if (iaxs[callno]->authid > -1)
05835             ast_sched_del(sched, iaxs[callno]->authid);
05836          iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05837       } else
05838          auth_reject((void *)(long)callno);
05839    }
05840    ast_mutex_unlock(&iaxsl[callno]);
05841    return 0;
05842 }
05843 
05844 static void __auto_hangup(void *nothing)
05845 {
05846    /* Called from IAX thread only, without iaxs lock */
05847    int callno = (int)(long)(nothing);
05848    struct iax_ie_data ied;
05849    ast_mutex_lock(&iaxsl[callno]);
05850    if (iaxs[callno]) {
05851       memset(&ied, 0, sizeof(ied));
05852       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05853       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05854       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05855    }
05856    ast_mutex_unlock(&iaxsl[callno]);
05857 }
05858 
05859 static int auto_hangup(void *data)
05860 {
05861    int callno = (int)(long)(data);
05862    ast_mutex_lock(&iaxsl[callno]);
05863    if (iaxs[callno]) {
05864       iaxs[callno]->autoid = -1;
05865    }
05866    ast_mutex_unlock(&iaxsl[callno]);
05867 #ifdef SCHED_MULTITHREADED
05868    if (schedule_action(__auto_hangup, data))
05869 #endif      
05870       __auto_hangup(data);
05871    return 0;
05872 }
05873 
05874 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
05875 {
05876    struct iax_ie_data ied;
05877    /* Auto-hangup with 30 seconds of inactivity */
05878    if (iaxs[callno]->autoid > -1)
05879       ast_sched_del(sched, iaxs[callno]->autoid);
05880    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05881    memset(&ied, 0, sizeof(ied));
05882    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05883    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05884    dp->flags |= CACHE_FLAG_TRANSMITTED;
05885 }
05886 
05887 static int iax2_vnak(int callno)
05888 {
05889    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05890 }
05891 
05892 static void vnak_retransmit(int callno, int last)
05893 {
05894    struct iax_frame *f;
05895 
05896    AST_LIST_LOCK(&iaxq.queue);
05897    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
05898       /* Send a copy immediately */
05899       if ((f->callno == callno) && iaxs[f->callno] &&
05900          (f->oseqno >= last)) {
05901          send_packet(f);
05902       }
05903    }
05904    AST_LIST_UNLOCK(&iaxq.queue);
05905 }
05906 
05907 static void __iax2_poke_peer_s(void *data)
05908 {
05909    struct iax2_peer *peer = data;
05910    iax2_poke_peer(peer, 0);
05911 }
05912 
05913 static int iax2_poke_peer_s(void *data)
05914 {
05915    struct iax2_peer *peer = data;
05916    peer->pokeexpire = -1;
05917 #ifdef SCHED_MULTITHREADED
05918    if (schedule_action(__iax2_poke_peer_s, data))
05919 #endif      
05920       __iax2_poke_peer_s(data);
05921    return 0;
05922 }
05923 
05924 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
05925 {
05926    int res = 0;
05927    struct iax_frame *fr;
05928    struct ast_iax2_meta_hdr *meta;
05929    struct ast_iax2_meta_trunk_hdr *mth;
05930    int calls = 0;
05931    
05932    /* Point to frame */
05933    fr = (struct iax_frame *)tpeer->trunkdata;
05934    /* Point to meta data */
05935    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
05936    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
05937    if (tpeer->trunkdatalen) {
05938       /* We're actually sending a frame, so fill the meta trunk header and meta header */
05939       meta->zeros = 0;
05940       meta->metacmd = IAX_META_TRUNK;
05941       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
05942          meta->cmddata = IAX_META_TRUNK_MINI;
05943       else
05944          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
05945       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
05946       /* And the rest of the ast_iax2 header */
05947       fr->direction = DIRECTION_OUTGRESS;
05948       fr->retrans = -1;
05949       fr->transfer = 0;
05950       /* Any appropriate call will do */
05951       fr->data = fr->afdata;
05952       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
05953       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
05954       calls = tpeer->calls;
05955 #if 0
05956       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));
05957 #endif      
05958       /* Reset transmit trunk side data */
05959       tpeer->trunkdatalen = 0;
05960       tpeer->calls = 0;
05961    }
05962    if (res < 0)
05963       return res;
05964    return calls;
05965 }
05966 
05967 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
05968 {
05969    /* Drop when trunk is about 5 seconds idle */
05970    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
05971       return 1;
05972    return 0;
05973 }
05974 
05975 static int timing_read(int *id, int fd, short events, void *cbdata)
05976 {
05977    char buf[1024];
05978    int res;
05979    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
05980    int processed = 0;
05981    int totalcalls = 0;
05982 #ifdef ZT_TIMERACK
05983    int x = 1;
05984 #endif
05985    struct timeval now;
05986    if (iaxtrunkdebug)
05987       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
05988    gettimeofday(&now, NULL);
05989    if (events & AST_IO_PRI) {
05990 #ifdef ZT_TIMERACK
05991       /* Great, this is a timing interface, just call the ioctl */
05992       if (ioctl(fd, ZT_TIMERACK, &x)) 
05993          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
05994       res = 0;
05995 #endif      
05996    } else {
05997       /* Read and ignore from the pseudo channel for timing */
05998       res = read(fd, buf, sizeof(buf));
05999       if (res < 1) {
06000          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06001          return 1;
06002       }
06003    }
06004    /* For each peer that supports trunking... */
06005    ast_mutex_lock(&tpeerlock);
06006    tpeer = tpeers;
06007    while(tpeer) {
06008       processed++;
06009       res = 0;
06010       ast_mutex_lock(&tpeer->lock);
06011       /* We can drop a single tpeer per pass.  That makes all this logic
06012          substantially easier */
06013       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06014          /* Take it out of the list, but don't free it yet, because it
06015             could be in use */
06016          if (prev)
06017             prev->next = tpeer->next;
06018          else
06019             tpeers = tpeer->next;
06020          drop = tpeer;
06021       } else {
06022          res = send_trunk(tpeer, &now);
06023          if (iaxtrunkdebug)
06024             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);
06025       }     
06026       totalcalls += res;   
06027       res = 0;
06028       ast_mutex_unlock(&tpeer->lock);
06029       prev = tpeer;
06030       tpeer = tpeer->next;
06031    }
06032    ast_mutex_unlock(&tpeerlock);
06033    if (drop) {
06034       ast_mutex_lock(&drop->lock);
06035       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06036          because by the time they could get tpeerlock, we've already grabbed it */
06037       ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06038       free(drop->trunkdata);
06039       ast_mutex_unlock(&drop->lock);
06040       ast_mutex_destroy(&drop->lock);
06041       free(drop);
06042       
06043    }
06044    if (iaxtrunkdebug)
06045       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06046    iaxtrunkdebug =0;
06047    return 1;
06048 }
06049 
06050 struct dpreq_data {
06051    int callno;
06052    char context[AST_MAX_EXTENSION];
06053    char callednum[AST_MAX_EXTENSION];
06054    char *callerid;
06055 };
06056 
06057 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06058 {
06059    unsigned short dpstatus = 0;
06060    struct iax_ie_data ied1;
06061    int mm;
06062 
06063    memset(&ied1, 0, sizeof(ied1));
06064    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06065    /* Must be started */
06066    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06067       dpstatus = IAX_DPSTATUS_EXISTS;
06068    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06069       dpstatus = IAX_DPSTATUS_CANEXIST;
06070    } else {
06071       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06072    }
06073    if (ast_ignore_pattern(context, callednum))
06074       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06075    if (mm)
06076       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06077    if (!skiplock)
06078       ast_mutex_lock(&iaxsl[callno]);
06079    if (iaxs[callno]) {
06080       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06081       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06082       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06083       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06084    }
06085    if (!skiplock)
06086       ast_mutex_unlock(&iaxsl[callno]);
06087 }
06088 
06089 static void *dp_lookup_thread(void *data)
06090 {
06091    /* Look up for dpreq */
06092    struct dpreq_data *dpr = data;
06093    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06094    if (dpr->callerid)
06095       free(dpr->callerid);
06096    free(dpr);
06097    return NULL;
06098 }
06099 
06100 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06101 {
06102    pthread_t newthread;
06103    struct dpreq_data *dpr;
06104    pthread_attr_t attr;
06105    
06106    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06107       return;
06108 
06109    pthread_attr_init(&attr);
06110    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06111 
06112    dpr->callno = callno;
06113    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06114    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06115    if (callerid)
06116       dpr->callerid = ast_strdup(callerid);
06117    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06118       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06119    }
06120 
06121    pthread_attr_destroy(&attr);
06122 }
06123 
06124 struct iax_dual {
06125    struct ast_channel *chan1;
06126    struct ast_channel *chan2;
06127 };
06128 
06129 static void *iax_park_thread(void *stuff)
06130 {
06131    struct ast_channel *chan1, *chan2;
06132    struct iax_dual *d;
06133    struct ast_frame *f;
06134    int ext;
06135    int res;
06136    d = stuff;
06137    chan1 = d->chan1;
06138    chan2 = d->chan2;
06139    free(d);
06140    f = ast_read(chan1);
06141    if (f)
06142       ast_frfree(f);
06143    res = ast_park_call(chan1, chan2, 0, &ext);
06144    ast_hangup(chan2);
06145    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06146    return NULL;
06147 }
06148 
06149 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06150 {
06151    struct iax_dual *d;
06152    struct ast_channel *chan1m, *chan2m;
06153    pthread_t th;
06154    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06155    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06156    if (chan2m && chan1m) {
06157       /* Make formats okay */
06158       chan1m->readformat = chan1->readformat;
06159       chan1m->writeformat = chan1->writeformat;
06160       ast_channel_masquerade(chan1m, chan1);
06161       /* Setup the extensions and such */
06162       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06163       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06164       chan1m->priority = chan1->priority;
06165       
06166       /* We make a clone of the peer channel too, so we can play
06167          back the announcement */
06168       /* Make formats okay */
06169       chan2m->readformat = chan2->readformat;
06170       chan2m->writeformat = chan2->writeformat;
06171       ast_channel_masquerade(chan2m, chan2);
06172       /* Setup the extensions and such */
06173       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06174       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06175       chan2m->priority = chan2->priority;
06176       if (ast_do_masquerade(chan2m)) {
06177          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06178          ast_hangup(chan2m);
06179          return -1;
06180       }
06181    } else {
06182       if (chan1m)
06183          ast_hangup(chan1m);
06184       if (chan2m)
06185          ast_hangup(chan2m);
06186       return -1;
06187    }
06188    if ((d = ast_calloc(1, sizeof(*d)))) {
06189       pthread_attr_t attr;
06190 
06191       pthread_attr_init(&attr);
06192       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06193 
06194       d->chan1 = chan1m;
06195       d->chan2 = chan2m;
06196       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06197          pthread_attr_destroy(&attr);
06198          return 0;
06199       }
06200       pthread_attr_destroy(&attr);
06201       free(d);
06202    }
06203    return -1;
06204 }
06205 
06206 
06207 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06208 
06209 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06210 {
06211    unsigned int ourver;
06212    char rsi[80];
06213    snprintf(rsi, sizeof(rsi), "si-%s", si);
06214    if (iax_provision_version(&ourver, rsi, 1))
06215       return 0;
06216    if (option_debug)
06217       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06218    if (ourver != ver) 
06219       iax2_provision(sin, sockfd, NULL, rsi, 1);
06220    return 0;
06221 }
06222 
06223 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06224 {
06225    jb_info stats;
06226    jb_getinfo(pvt->jb, &stats);
06227    
06228    memset(iep, 0, sizeof(*iep));
06229 
06230    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06231    if(stats.frames_in == 0) stats.frames_in = 1;
06232    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06233    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06234    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06235    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06236    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06237 }
06238 
06239 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06240 {
06241    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06242    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06243    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06244    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06245    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06246    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06247    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06248 }
06249 
06250 static int socket_read(int *id, int fd, short events, void *cbdata)
06251 {
06252    struct iax2_thread *thread;
06253    socklen_t len;
06254    time_t t;
06255    static time_t last_errtime=0;
06256 
06257    thread = find_idle_thread();
06258    if (thread) {
06259       len = sizeof(thread->iosin);
06260       thread->iofd = fd;
06261       thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len);
06262       if (thread->iores < 0) {
06263          if (errno != ECONNREFUSED && errno != EAGAIN)
06264             ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06265          handle_error();
06266          insert_idle_thread(thread);
06267          return 1;
06268       }
06269       if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06270          insert_idle_thread(thread);
06271          return 1;
06272       }
06273       /* Mark as ready and send on its way */
06274       thread->iostate = IAX_IOSTATE_READY;
06275 #ifdef DEBUG_SCHED_MULTITHREAD
06276       ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06277 #endif
06278       signal_condition(&thread->lock, &thread->cond);
06279    } else {
06280       time(&t);
06281       if (t != last_errtime)
06282          ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
06283       last_errtime = t;
06284       usleep(1);
06285    }
06286    return 1;
06287 }
06288 
06289 static int acf_iaxvar_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
06290 {
06291    const char *value;
06292    char tmp[256];
06293    snprintf(tmp, sizeof(tmp), "~IAX2~%s", data);
06294    value = pbx_builtin_getvar_helper(chan, tmp);
06295    ast_copy_string(buf, value ? value : "", len);
06296    return 0;
06297 }
06298 
06299 static int acf_iaxvar_write(struct ast_channel *chan, char *cmd, char *varname, const char *value)
06300 {
06301    char tmp[256];
06302    /* Inherit forever */
06303    snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname);
06304    pbx_builtin_setvar_helper(chan, tmp, value);
06305    return 0;
06306 }
06307 
06308 static struct ast_custom_function iaxvar_function = {
06309    .name = "IAXVAR",
06310    .synopsis = "Sets or retrieves a remote variable",
06311    .syntax = "IAXVAR(<varname>)",
06312    .read = acf_iaxvar_read,
06313    .write = acf_iaxvar_write,
06314 };
06315 
06316 static int socket_process(struct iax2_thread *thread)
06317 {
06318    struct sockaddr_in sin;
06319    int res;
06320    int updatehistory=1;
06321    int new = NEW_PREVENT;
06322    void *ptr;
06323    int dcallno = 0;
06324    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06325    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06326    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06327    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06328    struct ast_iax2_meta_trunk_hdr *mth;
06329    struct ast_iax2_meta_trunk_entry *mte;
06330    struct ast_iax2_meta_trunk_mini *mtm;
06331    struct iax_frame *fr;
06332    struct iax_frame *cur;
06333    struct ast_frame f = { 0, };
06334    struct ast_channel *c;
06335    struct iax2_dpcache *dp;
06336    struct iax2_peer *peer;
06337    struct iax2_trunk_peer *tpeer;
06338    struct timeval rxtrunktime;
06339    struct iax_ies ies;
06340    struct iax_ie_data ied0, ied1;
06341    int format;
06342    int fd;
06343    int exists;
06344    int minivid = 0;
06345    unsigned int ts;
06346    char empty[32]="";      /* Safety measure */
06347    struct iax_frame *duped_fr;
06348    char host_pref_buf[128];
06349    char caller_pref_buf[128];
06350    struct ast_codec_pref pref;
06351    char *using_prefs = "mine";
06352 
06353    /* allocate an iax_frame with 4096 bytes of data buffer */
06354    fr = alloca(sizeof(*fr) + 4096);
06355    fr->callno = 0;
06356 
06357    /* Copy frequently used parameters to the stack */
06358    res = thread->iores;
06359    fd = thread->iofd;
06360    memcpy(&sin, &thread->iosin, sizeof(sin));
06361 
06362    if (res < sizeof(*mh)) {
06363       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06364       return 1;
06365    }
06366    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06367       if (res < sizeof(*vh)) {
06368          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));
06369          return 1;
06370       }
06371 
06372       /* This is a video frame, get call number */
06373       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06374       minivid = 1;
06375    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06376       unsigned char metatype;
06377 
06378       if (res < sizeof(*meta)) {
06379          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));
06380          return 1;
06381       }
06382 
06383       /* This is a meta header */
06384       switch(meta->metacmd) {
06385       case IAX_META_TRUNK:
06386          if (res < (sizeof(*meta) + sizeof(*mth))) {
06387             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06388                sizeof(*meta) + sizeof(*mth));
06389             return 1;
06390          }
06391          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06392          ts = ntohl(mth->ts);
06393          metatype = meta->cmddata;
06394          res -= (sizeof(*meta) + sizeof(*mth));
06395          ptr = mth->data;
06396          tpeer = find_tpeer(&sin, fd);
06397          if (!tpeer) {
06398             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));
06399             return 1;
06400          }
06401          tpeer->trunkact = ast_tvnow();
06402          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06403             tpeer->rxtrunktime = tpeer->trunkact;
06404          rxtrunktime = tpeer->rxtrunktime;
06405          ast_mutex_unlock(&tpeer->lock);
06406          while(res >= sizeof(*mte)) {
06407             /* Process channels */
06408             unsigned short callno, trunked_ts, len;
06409 
06410             if (metatype == IAX_META_TRUNK_MINI) {
06411                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06412                ptr += sizeof(*mtm);
06413                res -= sizeof(*mtm);
06414                len = ntohs(mtm->len);
06415                callno = ntohs(mtm->mini.callno);
06416                trunked_ts = ntohs(mtm->mini.ts);
06417             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06418                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06419                ptr += sizeof(*mte);
06420                res -= sizeof(*mte);
06421                len = ntohs(mte->len);
06422                callno = ntohs(mte->callno);
06423                trunked_ts = 0;
06424             } else {
06425                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06426                break;
06427             }
06428             /* Stop if we don't have enough data */
06429             if (len > res)
06430                break;
06431             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06432             if (fr->callno) {
06433                ast_mutex_lock(&iaxsl[fr->callno]);
06434                /* If it's a valid call, deliver the contents.  If not, we
06435                   drop it, since we don't have a scallno to use for an INVAL */
06436                /* Process as a mini frame */
06437                memset(&f, 0, sizeof(f));
06438                f.frametype = AST_FRAME_VOICE;
06439                if (iaxs[fr->callno]) {
06440                   if (iaxs[fr->callno]->voiceformat > 0) {
06441                      f.subclass = iaxs[fr->callno]->voiceformat;
06442                      f.datalen = len;
06443                      if (f.datalen >= 0) {
06444                         if (f.datalen)
06445                            f.data = ptr;
06446                         if(trunked_ts) {
06447                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06448                         } else
06449                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06450                         /* Don't pass any packets until we're started */
06451                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06452                            /* Common things */
06453                            f.src = "IAX2";
06454                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06455                               f.samples = ast_codec_get_samples(&f);
06456                            iax_frame_wrap(fr, &f);
06457                            duped_fr = iaxfrdup2(fr);
06458                            if (duped_fr) {
06459                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06460                            }
06461                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
06462                            if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06463                               iaxs[fr->callno]->last = fr->ts;
06464 #if 1
06465                               if (option_debug && iaxdebug)
06466                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06467 #endif
06468                            }
06469                         }
06470                      } else {
06471                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06472                      }
06473                   } else {
06474                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06475                      iax2_vnak(fr->callno);
06476                   }
06477                }
06478                ast_mutex_unlock(&iaxsl[fr->callno]);
06479             }
06480             ptr += len;
06481             res -= len;
06482          }
06483          
06484       }
06485       return 1;
06486    }
06487 
06488 #ifdef DEBUG_SUPPORT
06489    if (iaxdebug && (res >= sizeof(*fh)))
06490       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06491 #endif
06492    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06493       if (res < sizeof(*fh)) {
06494          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));
06495          return 1;
06496       }
06497 
06498       /* Get the destination call number */
06499       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06500       /* Retrieve the type and subclass */
06501       f.frametype = fh->type;
06502       if (f.frametype == AST_FRAME_VIDEO) {
06503          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06504       } else {
06505          f.subclass = uncompress_subclass(fh->csub);
06506       }
06507       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06508                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06509                          (f.subclass == IAX_COMMAND_REGREL)))
06510          new = NEW_ALLOW;
06511    } else {
06512       /* Don't know anything about it yet */
06513       f.frametype = AST_FRAME_NULL;
06514       f.subclass = 0;
06515    }
06516 
06517    if (!fr->callno)
06518       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06519 
06520    if (fr->callno > 0) 
06521       ast_mutex_lock(&iaxsl[fr->callno]);
06522 
06523    if (!fr->callno || !iaxs[fr->callno]) {
06524       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06525          frame, reply with an inval */
06526       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06527          /* We can only raw hangup control frames */
06528          if (((f.subclass != IAX_COMMAND_INVAL) &&
06529              (f.subclass != IAX_COMMAND_TXCNT) &&
06530              (f.subclass != IAX_COMMAND_TXACC) &&
06531              (f.subclass != IAX_COMMAND_FWDOWNL))||
06532              (f.frametype != AST_FRAME_IAX))
06533             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06534             fd);
06535       }
06536       if (fr->callno > 0) 
06537          ast_mutex_unlock(&iaxsl[fr->callno]);
06538       return 1;
06539    }
06540    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06541       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06542          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06543          ast_mutex_unlock(&iaxsl[fr->callno]);
06544          return 1;
06545       }
06546 #ifdef DEBUG_SUPPORT
06547       else if (iaxdebug)
06548          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06549 #endif
06550    }
06551 
06552    /* count this frame */
06553    iaxs[fr->callno]->frames_received++;
06554 
06555    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06556       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06557       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06558       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06559    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06560       if (option_debug  && iaxdebug)
06561          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06562       /* Check if it's out of order (and not an ACK or INVAL) */
06563       fr->oseqno = fh->oseqno;
06564       fr->iseqno = fh->iseqno;
06565       fr->ts = ntohl(fh->ts);
06566 #ifdef IAXTESTS
06567       if (test_resync) {
06568          if (option_debug)
06569             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06570          fr->ts += test_resync;
06571       }
06572 #endif /* IAXTESTS */
06573 #if 0
06574       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06575            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06576                         (f.subclass == IAX_COMMAND_NEW ||
06577                          f.subclass == IAX_COMMAND_AUTHREQ ||
06578                          f.subclass == IAX_COMMAND_ACCEPT ||
06579                          f.subclass == IAX_COMMAND_REJECT))      ) )
06580 #endif
06581       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06582          updatehistory = 0;
06583       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06584          (iaxs[fr->callno]->iseqno ||
06585             ((f.subclass != IAX_COMMAND_TXCNT) &&
06586             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06587             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06588             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06589             (f.subclass != IAX_COMMAND_TXACC)) ||
06590             (f.frametype != AST_FRAME_IAX))) {
06591          if (
06592           ((f.subclass != IAX_COMMAND_ACK) &&
06593            (f.subclass != IAX_COMMAND_INVAL) &&
06594            (f.subclass != IAX_COMMAND_TXCNT) &&
06595            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06596            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06597            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06598            (f.subclass != IAX_COMMAND_TXACC) &&
06599            (f.subclass != IAX_COMMAND_VNAK)) ||
06600            (f.frametype != AST_FRAME_IAX)) {
06601             /* If it's not an ACK packet, it's out of order. */
06602             if (option_debug)
06603                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06604                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06605             if (iaxs[fr->callno]->iseqno > fr->oseqno) {
06606                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06607                if ((f.frametype != AST_FRAME_IAX) || 
06608                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06609                   if (option_debug)
06610                      ast_log(LOG_DEBUG, "Acking anyway\n");
06611                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06612                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06613                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06614                }
06615             } else {
06616                /* Send a VNAK requesting retransmission */
06617                iax2_vnak(fr->callno);
06618             }
06619             ast_mutex_unlock(&iaxsl[fr->callno]);
06620             return 1;
06621          }
06622       } else {
06623          /* Increment unless it's an ACK or VNAK */
06624          if (((f.subclass != IAX_COMMAND_ACK) &&
06625              (f.subclass != IAX_COMMAND_INVAL) &&
06626              (f.subclass != IAX_COMMAND_TXCNT) &&
06627              (f.subclass != IAX_COMMAND_TXACC) &&
06628             (f.subclass != IAX_COMMAND_VNAK)) ||
06629              (f.frametype != AST_FRAME_IAX))
06630             iaxs[fr->callno]->iseqno++;
06631       }
06632       /* A full frame */
06633       if (res < sizeof(*fh)) {
06634          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06635          ast_mutex_unlock(&iaxsl[fr->callno]);
06636          return 1;
06637       }
06638       f.datalen = res - sizeof(*fh);
06639 
06640       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
06641          from the real peer, not the transfer peer */
06642       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06643           ((f.subclass != IAX_COMMAND_INVAL) ||
06644            (f.frametype != AST_FRAME_IAX))) {
06645          unsigned char x;
06646          /* XXX This code is not very efficient.  Surely there is a better way which still
06647                 properly handles boundary conditions? XXX */
06648          /* First we have to qualify that the ACKed value is within our window */
06649          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
06650             if (fr->iseqno == x)
06651                break;
06652          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
06653             /* The acknowledgement is within our window.  Time to acknowledge everything
06654                that it says to */
06655             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
06656                /* Ack the packet with the given timestamp */
06657                if (option_debug && iaxdebug)
06658                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06659                AST_LIST_LOCK(&iaxq.queue);
06660                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06661                   /* If it's our call, and our timestamp, mark -1 retries */
06662                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
06663                      cur->retries = -1;
06664                      /* Destroy call if this is the end */
06665                      if (cur->final) { 
06666                         if (iaxdebug && option_debug)
06667                            ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
06668                         iax2_destroy(fr->callno);
06669                      }
06670                   }
06671                }
06672                AST_LIST_UNLOCK(&iaxq.queue);
06673             }
06674             /* Note how much we've received acknowledgement for */
06675             if (iaxs[fr->callno])
06676                iaxs[fr->callno]->rseqno = fr->iseqno;
06677             else {
06678                /* Stop processing now */
06679                ast_mutex_unlock(&iaxsl[fr->callno]);
06680                return 1;
06681             }
06682          } else
06683             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
06684       }
06685       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06686          ((f.frametype != AST_FRAME_IAX) || 
06687           ((f.subclass != IAX_COMMAND_TXACC) &&
06688            (f.subclass != IAX_COMMAND_TXCNT)))) {
06689          /* Only messages we accept from a transfer host are TXACC and TXCNT */
06690          ast_mutex_unlock(&iaxsl[fr->callno]);
06691          return 1;
06692       }
06693 
06694       if (f.datalen) {
06695          if (f.frametype == AST_FRAME_IAX) {
06696             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
06697                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
06698                ast_mutex_unlock(&iaxsl[fr->callno]);
06699                return 1;
06700             }
06701             f.data = NULL;
06702          } else
06703             f.data = thread->buf + sizeof(*fh);
06704       } else {
06705          if (f.frametype == AST_FRAME_IAX)
06706             f.data = NULL;
06707          else
06708             f.data = empty;
06709          memset(&ies, 0, sizeof(ies));
06710       }
06711       if (f.frametype == AST_FRAME_VOICE) {
06712          if (f.subclass != iaxs[fr->callno]->voiceformat) {
06713                iaxs[fr->callno]->voiceformat = f.subclass;
06714                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06715                if (iaxs[fr->callno]->owner) {
06716                   int orignative;
06717 retryowner:
06718                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
06719                      ast_mutex_unlock(&iaxsl[fr->callno]);
06720                      usleep(1);
06721                      ast_mutex_lock(&iaxsl[fr->callno]);
06722                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
06723                   }
06724                   if (iaxs[fr->callno]) {
06725                      if (iaxs[fr->callno]->owner) {
06726                         orignative = iaxs[fr->callno]->owner->nativeformats;
06727                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
06728                         if (iaxs[fr->callno]->owner->readformat)
06729                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
06730                         iaxs[fr->callno]->owner->nativeformats = orignative;
06731                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
06732                      }
06733                   } else {
06734                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06735                      /* Free remote variables (if any) */
06736                      if (ies.vars)
06737                         ast_variables_destroy(ies.vars);
06738                      ast_mutex_unlock(&iaxsl[fr->callno]);
06739                      return 1;
06740                   }
06741                }
06742          }
06743       }
06744       if (f.frametype == AST_FRAME_VIDEO) {
06745          if (f.subclass != iaxs[fr->callno]->videoformat) {
06746             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06747             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
06748          }
06749       }
06750       if (f.frametype == AST_FRAME_IAX) {
06751          if (iaxs[fr->callno]->initid > -1) {
06752             /* Don't auto congest anymore since we've gotten something usefulb ack */
06753             ast_sched_del(sched, iaxs[fr->callno]->initid);
06754             iaxs[fr->callno]->initid = -1;
06755          }
06756          /* Handle the IAX pseudo frame itself */
06757          if (option_debug && iaxdebug)
06758             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06759 
06760                         /* Update last ts unless the frame's timestamp originated with us. */
06761          if (iaxs[fr->callno]->last < fr->ts &&
06762                             f.subclass != IAX_COMMAND_ACK &&
06763                             f.subclass != IAX_COMMAND_PONG &&
06764                             f.subclass != IAX_COMMAND_LAGRP) {
06765             iaxs[fr->callno]->last = fr->ts;
06766             if (option_debug && iaxdebug)
06767                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06768          }
06769 
06770          switch(f.subclass) {
06771          case IAX_COMMAND_ACK:
06772             /* Do nothing */
06773             break;
06774          case IAX_COMMAND_QUELCH:
06775             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06776                     /* Generate Manager Hold event, if necessary*/
06777                if (iaxs[fr->callno]->owner) {
06778                   manager_event(EVENT_FLAG_CALL, "Hold",
06779                      "Channel: %s\r\n"
06780                      "Uniqueid: %s\r\n",
06781                      iaxs[fr->callno]->owner->name, 
06782                      iaxs[fr->callno]->owner->uniqueid);
06783                }
06784 
06785                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
06786                if (ies.musiconhold) {
06787                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
06788                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
06789                      ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD, 
06790                         S_OR(mohsuggest, NULL),
06791                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
06792                   }
06793                }
06794             }
06795             break;
06796          case IAX_COMMAND_UNQUELCH:
06797             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06798                     /* Generate Manager Unhold event, if necessary*/
06799                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
06800                   manager_event(EVENT_FLAG_CALL, "Unhold",
06801                      "Channel: %s\r\n"
06802                      "Uniqueid: %s\r\n",
06803                      iaxs[fr->callno]->owner->name, 
06804                      iaxs[fr->callno]->owner->uniqueid);
06805                }
06806 
06807                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
06808                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner))
06809                   ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD);
06810             }
06811             break;
06812          case IAX_COMMAND_TXACC:
06813             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
06814                /* Ack the packet with the given timestamp */
06815                AST_LIST_LOCK(&iaxq.queue);
06816                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06817                   /* Cancel any outstanding txcnt's */
06818                   if ((fr->callno == cur->callno) && (cur->transfer))
06819                      cur->retries = -1;
06820                }
06821                AST_LIST_UNLOCK(&iaxq.queue);
06822                memset(&ied1, 0, sizeof(ied1));
06823                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
06824                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06825                iaxs[fr->callno]->transferring = TRANSFER_READY;
06826             }
06827             break;
06828          case IAX_COMMAND_NEW:
06829             /* Ignore if it's already up */
06830             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06831                break;
06832             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06833                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06834             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
06835             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
06836                fr->callno = make_trunk(fr->callno, 1);
06837             }
06838             /* For security, always ack immediately */
06839             if (delayreject)
06840                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06841             if (check_access(fr->callno, &sin, &ies)) {
06842                /* They're not allowed on */
06843                auth_fail(fr->callno, IAX_COMMAND_REJECT);
06844                if (authdebug)
06845                   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);
06846                break;
06847             }
06848             /* This might re-enter the IAX code and need the lock */
06849             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
06850                ast_mutex_unlock(&iaxsl[fr->callno]);
06851                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
06852                ast_mutex_lock(&iaxsl[fr->callno]);
06853             } else
06854                exists = 0;
06855             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
06856                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
06857                   memset(&ied0, 0, sizeof(ied0));
06858                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
06859                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
06860                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06861                   if (authdebug)
06862                      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);
06863                } else {
06864                   /* Select an appropriate format */
06865 
06866                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06867                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06868                         using_prefs = "reqonly";
06869                      } else {
06870                         using_prefs = "disabled";
06871                      }
06872                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
06873                      memset(&pref, 0, sizeof(pref));
06874                      strcpy(caller_pref_buf, "disabled");
06875                      strcpy(host_pref_buf, "disabled");
06876                   } else {
06877                      using_prefs = "mine";
06878                      /* If the information elements are in here... use them */
06879                      if (ies.codec_prefs)
06880                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
06881                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06882                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
06883                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06884                            pref = iaxs[fr->callno]->rprefs;
06885                            using_prefs = "caller";
06886                         } else {
06887                            pref = iaxs[fr->callno]->prefs;
06888                         }
06889                      } else
06890                         pref = iaxs[fr->callno]->prefs;
06891                      
06892                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
06893                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
06894                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
06895                   }
06896                   if (!format) {
06897                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06898                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
06899                      if (!format) {
06900                         memset(&ied0, 0, sizeof(ied0));
06901                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06902                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06903                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06904                         if (authdebug) {
06905                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06906                               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);
06907                            else 
06908                               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);
06909                         }
06910                      } else {
06911                         /* Pick one... */
06912                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06913                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
06914                               format = 0;
06915                         } else {
06916                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06917                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
06918                               memset(&pref, 0, sizeof(pref));
06919                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06920                               strcpy(caller_pref_buf,"disabled");
06921                               strcpy(host_pref_buf,"disabled");
06922                            } else {
06923                               using_prefs = "mine";
06924                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06925                                  /* Do the opposite of what we tried above. */
06926                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06927                                     pref = iaxs[fr->callno]->prefs;                       
06928                                  } else {
06929                                     pref = iaxs[fr->callno]->rprefs;
06930                                     using_prefs = "caller";
06931                                  }
06932                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
06933                            
06934                               } else /* if no codec_prefs IE do it the old way */
06935                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
06936                            }
06937                         }
06938 
06939                         if (!format) {
06940                            memset(&ied0, 0, sizeof(ied0));
06941                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06942                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06943                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06944                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06945                            if (authdebug)
06946                               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);
06947                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
06948                            break;
06949                         }
06950                      }
06951                   }
06952                   if (format) {
06953                      /* No authentication required, let them in */
06954                      memset(&ied1, 0, sizeof(ied1));
06955                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
06956                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
06957                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
06958                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
06959                         if (option_verbose > 2) 
06960                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
06961                                     "%srequested format = %s,\n"
06962                                     "%srequested prefs = %s,\n"
06963                                     "%sactual format = %s,\n"
06964                                     "%shost prefs = %s,\n"
06965                                     "%spriority = %s\n",
06966                                     ast_inet_ntoa(sin.sin_addr), 
06967                                     VERBOSE_PREFIX_4,
06968                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
06969                                     VERBOSE_PREFIX_4,
06970                                     caller_pref_buf,
06971                                     VERBOSE_PREFIX_4,
06972                                     ast_getformatname(format), 
06973                                     VERBOSE_PREFIX_4,
06974                                     host_pref_buf, 
06975                                     VERBOSE_PREFIX_4,
06976                                     using_prefs);
06977                         
06978                         if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
06979                            iax2_destroy(fr->callno);
06980                         else if (ies.vars) {
06981                            struct ast_variable *var, *prev = NULL;
06982                            char tmp[256];
06983                            for (var = ies.vars; var; var = var->next) {
06984                               if (prev)
06985                                  free(prev);
06986                               prev = var;
06987                               snprintf(tmp, sizeof(tmp), "__~IAX2~%s", var->name);
06988                               pbx_builtin_setvar_helper(c, tmp, var->value);
06989                            }
06990                            ies.vars = NULL;
06991                         }
06992                      } else {
06993                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
06994                         /* If this is a TBD call, we're ready but now what...  */
06995                         if (option_verbose > 2)
06996                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
06997                      }
06998                   }
06999                }
07000                break;
07001             }
07002             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07003                merge_encryption(iaxs[fr->callno],ies.encmethods);
07004             else
07005                iaxs[fr->callno]->encmethods = 0;
07006             if (!authenticate_request(iaxs[fr->callno]))
07007                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07008             break;
07009          case IAX_COMMAND_DPREQ:
07010             /* Request status in the dialplan */
07011             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07012                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07013                if (iaxcompat) {
07014                   /* Spawn a thread for the lookup */
07015                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07016                } else {
07017                   /* Just look it up */
07018                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07019                }
07020             }
07021             break;
07022          case IAX_COMMAND_HANGUP:
07023             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07024             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07025             /* Set hangup cause according to remote */
07026             if (ies.causecode && iaxs[fr->callno]->owner)
07027                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07028             /* Send ack immediately, before we destroy */
07029             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07030             iax2_destroy(fr->callno);
07031             break;
07032          case IAX_COMMAND_REJECT:
07033             /* Set hangup cause according to remote */
07034             if (ies.causecode && iaxs[fr->callno]->owner)
07035                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07036 
07037             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07038                if (iaxs[fr->callno]->owner && authdebug)
07039                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07040                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07041                      ies.cause ? ies.cause : "<Unknown>");
07042                ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07043                   fr->callno);
07044             }
07045             /* Send ack immediately, before we destroy */
07046             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07047                          fr->ts, NULL, 0, fr->iseqno);
07048             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07049                iaxs[fr->callno]->error = EPERM;
07050             iax2_destroy(fr->callno);
07051             break;
07052          case IAX_COMMAND_TRANSFER:
07053             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07054                /* Set BLINDTRANSFER channel variables */
07055                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07056                pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07057                if (!strcmp(ies.called_number, ast_parking_ext())) {
07058                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07059                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07060                   } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
07061                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07062                } else {
07063                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07064                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07065                         ies.called_number, iaxs[fr->callno]->context);
07066                   else
07067                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07068                         ies.called_number, iaxs[fr->callno]->context);
07069                }
07070             } else
07071                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07072             break;
07073          case IAX_COMMAND_ACCEPT:
07074             /* Ignore if call is already up or needs authentication or is a TBD */
07075             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07076                break;
07077             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07078                /* Send ack immediately, before we destroy */
07079                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07080                iax2_destroy(fr->callno);
07081                break;
07082             }
07083             if (ies.format) {
07084                iaxs[fr->callno]->peerformat = ies.format;
07085             } else {
07086                if (iaxs[fr->callno]->owner)
07087                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07088                else
07089                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07090             }
07091             if (option_verbose > 2)
07092                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));
07093             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07094                memset(&ied0, 0, sizeof(ied0));
07095                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07096                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07097                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07098                if (authdebug)
07099                   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);
07100             } else {
07101                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07102                if (iaxs[fr->callno]->owner) {
07103                   /* Switch us to use a compatible format */
07104                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07105                   if (option_verbose > 2)
07106                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07107 retryowner2:
07108                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07109                      ast_mutex_unlock(&iaxsl[fr->callno]);
07110                      usleep(1);
07111                      ast_mutex_lock(&iaxsl[fr->callno]);
07112                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07113                   }
07114                   
07115                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07116                      /* Setup read/write formats properly. */
07117                      if (iaxs[fr->callno]->owner->writeformat)
07118                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07119                      if (iaxs[fr->callno]->owner->readformat)
07120                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07121                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07122                   }
07123                }
07124             }
07125             if (iaxs[fr->callno]) {
07126                ast_mutex_lock(&dpcache_lock);
07127                dp = iaxs[fr->callno]->dpentries;
07128                while(dp) {
07129                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07130                      iax2_dprequest(dp, fr->callno);
07131                   }
07132                   dp = dp->peer;
07133                }
07134                ast_mutex_unlock(&dpcache_lock);
07135             }
07136             break;
07137          case IAX_COMMAND_POKE:
07138             /* Send back a pong packet with the original timestamp */
07139             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07140             break;
07141          case IAX_COMMAND_PING:
07142          {
07143             struct iax_ie_data pingied;
07144             construct_rr(iaxs[fr->callno], &pingied);
07145             /* Send back a pong packet with the original timestamp */
07146             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07147          }
07148             break;
07149          case IAX_COMMAND_PONG:
07150             /* Calculate ping time */
07151             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07152             /* save RR info */
07153             save_rr(fr, &ies);
07154 
07155             if (iaxs[fr->callno]->peerpoke) {
07156                peer = iaxs[fr->callno]->peerpoke;
07157                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07158                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07159                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07160                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07161                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07162                   }
07163                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07164                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07165                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07166                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07167                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07168                   }
07169                }
07170                peer->lastms = iaxs[fr->callno]->pingtime;
07171                if (peer->smoothing && (peer->lastms > -1))
07172                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07173                else if (peer->smoothing && peer->lastms < 0)
07174                   peer->historicms = (0 + peer->historicms) / 2;
07175                else              
07176                   peer->historicms = iaxs[fr->callno]->pingtime;
07177 
07178                /* Remove scheduled iax2_poke_noanswer */
07179                if (peer->pokeexpire > -1)
07180                   ast_sched_del(sched, peer->pokeexpire);
07181                /* Schedule the next cycle */
07182                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07183                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07184                else
07185                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07186                /* and finally send the ack */
07187                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07188                /* And wrap up the qualify call */
07189                iax2_destroy(fr->callno);
07190                peer->callno = 0;
07191                if (option_debug)
07192                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07193             }
07194             break;
07195          case IAX_COMMAND_LAGRQ:
07196          case IAX_COMMAND_LAGRP:
07197             f.src = "LAGRQ";
07198             f.mallocd = 0;
07199             f.offset = 0;
07200             f.samples = 0;
07201             iax_frame_wrap(fr, &f);
07202             if(f.subclass == IAX_COMMAND_LAGRQ) {
07203                /* Received a LAGRQ - echo back a LAGRP */
07204                fr->af.subclass = IAX_COMMAND_LAGRP;
07205                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07206             } else {
07207                /* Received LAGRP in response to our LAGRQ */
07208                unsigned int ts;
07209                /* This is a reply we've been given, actually measure the difference */
07210                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07211                iaxs[fr->callno]->lag = ts - fr->ts;
07212                if (option_debug && iaxdebug)
07213                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07214                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07215             }
07216             break;
07217          case IAX_COMMAND_AUTHREQ:
07218             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07219                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>");
07220                break;
07221             }
07222             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07223                ast_log(LOG_WARNING, 
07224                   "I don't know how to authenticate %s to %s\n", 
07225                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07226             }
07227             break;
07228          case IAX_COMMAND_AUTHREP:
07229             /* For security, always ack immediately */
07230             if (delayreject)
07231                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07232             /* Ignore once we've started */
07233             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07234                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>");
07235                break;
07236             }
07237             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07238                if (authdebug)
07239                   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);
07240                memset(&ied0, 0, sizeof(ied0));
07241                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07242                break;
07243             }
07244             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07245                /* This might re-enter the IAX code and need the lock */
07246                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07247             } else
07248                exists = 0;
07249             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07250                if (authdebug)
07251                   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);
07252                memset(&ied0, 0, sizeof(ied0));
07253                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07254                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07255                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07256             } else {
07257                /* Select an appropriate format */
07258                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07259                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07260                      using_prefs = "reqonly";
07261                   } else {
07262                      using_prefs = "disabled";
07263                   }
07264                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07265                   memset(&pref, 0, sizeof(pref));
07266                   strcpy(caller_pref_buf, "disabled");
07267                   strcpy(host_pref_buf, "disabled");
07268                } else {
07269                   using_prefs = "mine";
07270                   if (ies.codec_prefs)
07271                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07272                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07273                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07274                         pref = iaxs[fr->callno]->rprefs;
07275                         using_prefs = "caller";
07276                      } else {
07277                         pref = iaxs[fr->callno]->prefs;
07278                      }
07279                   } else /* if no codec_prefs IE do it the old way */
07280                      pref = iaxs[fr->callno]->prefs;
07281                
07282                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07283                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07284                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07285                }
07286                if (!format) {
07287                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07288                      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);
07289                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07290                   }
07291                   if (!format) {
07292                      if (authdebug) {
07293                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07294                            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);
07295                         else
07296                            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);
07297                      }
07298                      memset(&ied0, 0, sizeof(ied0));
07299                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07300                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07301                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07302                   } else {
07303                      /* Pick one... */
07304                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07305                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07306                            format = 0;
07307                      } else {
07308                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07309                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07310                            memset(&pref, 0, sizeof(pref));
07311                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07312                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07313                            strcpy(caller_pref_buf,"disabled");
07314                            strcpy(host_pref_buf,"disabled");
07315                         } else {
07316                            using_prefs = "mine";
07317                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07318                               /* Do the opposite of what we tried above. */
07319                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07320                                  pref = iaxs[fr->callno]->prefs;                 
07321                               } else {
07322                                  pref = iaxs[fr->callno]->rprefs;
07323                                  using_prefs = "caller";
07324                               }
07325                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07326                            } else /* if no codec_prefs IE do it the old way */
07327                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07328                         }
07329                      }
07330                      if (!format) {
07331                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07332                         if (authdebug) {
07333                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07334                               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);
07335                            else
07336                               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);
07337                         }
07338                         memset(&ied0, 0, sizeof(ied0));
07339                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07340                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07341                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07342                      }
07343                   }
07344                }
07345                if (format) {
07346                   /* Authentication received */
07347                   memset(&ied1, 0, sizeof(ied1));
07348                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07349                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07350                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07351                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07352                      if (option_verbose > 2) 
07353                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07354                                  "%srequested format = %s,\n"
07355                                  "%srequested prefs = %s,\n"
07356                                  "%sactual format = %s,\n"
07357                                  "%shost prefs = %s,\n"
07358                                  "%spriority = %s\n", 
07359                                  ast_inet_ntoa(sin.sin_addr), 
07360                                  VERBOSE_PREFIX_4,
07361                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07362                                  VERBOSE_PREFIX_4,
07363                                  caller_pref_buf,
07364                                  VERBOSE_PREFIX_4,
07365                                  ast_getformatname(format),
07366                                  VERBOSE_PREFIX_4,
07367                                  host_pref_buf,
07368                                  VERBOSE_PREFIX_4,
07369                                  using_prefs);
07370 
07371                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07372                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07373                         iax2_destroy(fr->callno);
07374                   } else {
07375                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07376                      /* If this is a TBD call, we're ready but now what...  */
07377                      if (option_verbose > 2)
07378                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07379                   }
07380                }
07381             }
07382             break;
07383          case IAX_COMMAND_DIAL:
07384             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07385                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07386                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07387                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07388                   if (authdebug)
07389                      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);
07390                   memset(&ied0, 0, sizeof(ied0));
07391                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07392                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07393                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07394                } else {
07395                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07396                   if (option_verbose > 2) 
07397                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
07398                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07399                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07400                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07401                      iax2_destroy(fr->callno);
07402                }
07403             }
07404             break;
07405          case IAX_COMMAND_INVAL:
07406             iaxs[fr->callno]->error = ENOTCONN;
07407             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07408             iax2_destroy(fr->callno);
07409             if (option_debug)
07410                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07411             break;
07412          case IAX_COMMAND_VNAK:
07413             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07414             /* Force retransmission */
07415             vnak_retransmit(fr->callno, fr->iseqno);
07416             break;
07417          case IAX_COMMAND_REGREQ:
07418          case IAX_COMMAND_REGREL:
07419             /* For security, always ack immediately */
07420             if (delayreject)
07421                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07422             if (register_verify(fr->callno, &sin, &ies)) {
07423                /* Send delayed failure */
07424                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07425                break;
07426             }
07427             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
07428                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
07429                if (f.subclass == IAX_COMMAND_REGREL)
07430                   memset(&sin, 0, sizeof(sin));
07431                if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
07432                   ast_log(LOG_WARNING, "Registry error\n");
07433                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07434                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07435                break;
07436             }
07437             registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
07438             break;
07439          case IAX_COMMAND_REGACK:
07440             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
07441                ast_log(LOG_WARNING, "Registration failure\n");
07442             /* Send ack immediately, before we destroy */
07443             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07444             iax2_destroy(fr->callno);
07445             break;
07446          case IAX_COMMAND_REGREJ:
07447             if (iaxs[fr->callno]->reg) {
07448                if (authdebug) {
07449                   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));
07450                   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>");
07451                }
07452                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07453             }
07454             /* Send ack immediately, before we destroy */
07455             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07456             iax2_destroy(fr->callno);
07457             break;
07458          case IAX_COMMAND_REGAUTH:
07459             /* Authentication request */
07460             if (registry_rerequest(&ies, fr->callno, &sin)) {
07461                memset(&ied0, 0, sizeof(ied0));
07462                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07463                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07464                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07465             }
07466             break;
07467          case IAX_COMMAND_TXREJ:
07468             iaxs[fr->callno]->transferring = 0;
07469             if (option_verbose > 2) 
07470                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07471             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07472             if (iaxs[fr->callno]->bridgecallno) {
07473                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07474                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07475                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07476                }
07477             }
07478             break;
07479          case IAX_COMMAND_TXREADY:
07480             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
07481                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
07482                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
07483                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
07484                else
07485                   iaxs[fr->callno]->transferring = TRANSFER_READY;
07486                if (option_verbose > 2) 
07487                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07488                if (iaxs[fr->callno]->bridgecallno) {
07489                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
07490                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
07491                      /* They're both ready, now release them. */
07492                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
07493                         if (option_verbose > 2) 
07494                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07495                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07496 
07497                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
07498                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
07499 
07500                         memset(&ied0, 0, sizeof(ied0));
07501                         memset(&ied1, 0, sizeof(ied1));
07502                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07503                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07504                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
07505                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
07506                      } else {
07507                         if (option_verbose > 2) 
07508                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07509                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07510 
07511                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07512                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07513                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07514                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07515 
07516                         /* Stop doing lag & ping requests */
07517                         stop_stuff(fr->callno);
07518                         stop_stuff(iaxs[fr->callno]->bridgecallno);
07519 
07520                         memset(&ied0, 0, sizeof(ied0));
07521                         memset(&ied1, 0, sizeof(ied1));
07522                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07523                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07524                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07525                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07526                      }
07527 
07528                   }
07529                }
07530             }
07531             break;
07532          case IAX_COMMAND_TXREQ:
07533             try_transfer(iaxs[fr->callno], &ies);
07534             break;
07535          case IAX_COMMAND_TXCNT:
07536             if (iaxs[fr->callno]->transferring)
07537                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07538             break;
07539          case IAX_COMMAND_TXREL:
07540             /* Send ack immediately, rather than waiting until we've changed addresses */
07541             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07542             complete_transfer(fr->callno, &ies);
07543             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
07544             break;   
07545          case IAX_COMMAND_TXMEDIA:
07546             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
07547                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
07548                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
07549             }
07550             break;   
07551          case IAX_COMMAND_DPREP:
07552             complete_dpreply(iaxs[fr->callno], &ies);
07553             break;
07554          case IAX_COMMAND_UNSUPPORT:
07555             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07556             break;
07557          case IAX_COMMAND_FWDOWNL:
07558             /* Firmware download */
07559             memset(&ied0, 0, sizeof(ied0));
07560             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07561             if (res < 0)
07562                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07563             else if (res > 0)
07564                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07565             else
07566                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07567             break;
07568          default:
07569             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
07570             memset(&ied0, 0, sizeof(ied0));
07571             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07572             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07573          }
07574          /* Free remote variables (if any) */
07575          if (ies.vars)
07576             ast_variables_destroy(ies.vars);
07577 
07578          /* Don't actually pass these frames along */
07579          if ((f.subclass != IAX_COMMAND_ACK) && 
07580            (f.subclass != IAX_COMMAND_TXCNT) && 
07581            (f.subclass != IAX_COMMAND_TXACC) && 
07582            (f.subclass != IAX_COMMAND_INVAL) &&
07583            (f.subclass != IAX_COMMAND_VNAK)) { 
07584             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07585                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07586          }
07587          ast_mutex_unlock(&iaxsl[fr->callno]);
07588          return 1;
07589       }
07590       /* Unless this is an ACK or INVAL frame, ack it */
07591       if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07592          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07593    } else if (minivid) {
07594       f.frametype = AST_FRAME_VIDEO;
07595       if (iaxs[fr->callno]->videoformat > 0) 
07596          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07597       else {
07598          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07599          iax2_vnak(fr->callno);
07600          ast_mutex_unlock(&iaxsl[fr->callno]);
07601          return 1;
07602       }
07603       f.datalen = res - sizeof(*vh);
07604       if (f.datalen)
07605          f.data = thread->buf + sizeof(*vh);
07606       else
07607          f.data = NULL;
07608 #ifdef IAXTESTS
07609       if (test_resync) {
07610          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
07611       } else
07612 #endif /* IAXTESTS */
07613          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
07614    } else {
07615       /* A mini frame */
07616       f.frametype = AST_FRAME_VOICE;
07617       if (iaxs[fr->callno]->voiceformat > 0)
07618          f.subclass = iaxs[fr->callno]->voiceformat;
07619       else {
07620          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07621          iax2_vnak(fr->callno);
07622          ast_mutex_unlock(&iaxsl[fr->callno]);
07623          return 1;
07624       }
07625       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07626       if (f.datalen < 0) {
07627          ast_log(LOG_WARNING, "Datalen < 0?\n");
07628          ast_mutex_unlock(&iaxsl[fr->callno]);
07629          return 1;
07630       }
07631       if (f.datalen)
07632          f.data = thread->buf + sizeof(*mh);
07633       else
07634          f.data = NULL;
07635 #ifdef IAXTESTS
07636       if (test_resync) {
07637          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07638       } else
07639 #endif /* IAXTESTS */
07640       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07641       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
07642    }
07643    /* Don't pass any packets until we're started */
07644    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07645       ast_mutex_unlock(&iaxsl[fr->callno]);
07646       return 1;
07647    }
07648    /* Common things */
07649    f.src = "IAX2";
07650    f.mallocd = 0;
07651    f.offset = 0;
07652    f.len = 0;
07653    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07654       f.samples = ast_codec_get_samples(&f);
07655       /* We need to byteswap incoming slinear samples from network byte order */
07656       if (f.subclass == AST_FORMAT_SLINEAR)
07657          ast_frame_byteswap_be(&f);
07658    } else
07659       f.samples = 0;
07660    iax_frame_wrap(fr, &f);
07661 
07662    /* If this is our most recent packet, use it as our basis for timestamping */
07663    if (iaxs[fr->callno]->last < fr->ts) {
07664       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
07665       fr->outoforder = 0;
07666    } else {
07667       if (option_debug && iaxdebug)
07668          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);
07669       fr->outoforder = -1;
07670    }
07671    duped_fr = iaxfrdup2(fr);
07672    if (duped_fr) {
07673       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07674    }
07675    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07676       iaxs[fr->callno]->last = fr->ts;
07677 #if 1
07678       if (option_debug && iaxdebug)
07679          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07680 #endif
07681    }
07682 
07683    /* Always run again */
07684    ast_mutex_unlock(&iaxsl[fr->callno]);
07685    return 1;
07686 }
07687 
07688 /* Function to clean up process thread if it is cancelled */
07689 static void iax2_process_thread_cleanup(void *data)
07690 {
07691    struct iax2_thread *thread = data;
07692    ast_mutex_destroy(&thread->lock);
07693    ast_cond_destroy(&thread->cond);
07694    free(thread);
07695    ast_atomic_dec_and_test(&iaxactivethreadcount);
07696 }
07697 
07698 static void *iax2_process_thread(void *data)
07699 {
07700    struct iax2_thread *thread = data;
07701    struct timeval tv;
07702    struct timespec ts;
07703    int put_into_idle = 0;
07704 
07705    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
07706    pthread_cleanup_push(iax2_process_thread_cleanup, data);
07707    for(;;) {
07708       /* Wait for something to signal us to be awake */
07709       ast_mutex_lock(&thread->lock);
07710 
07711       /* Put into idle list if applicable */
07712       if (put_into_idle)
07713          insert_idle_thread(thread);
07714 
07715       if (thread->type == IAX_TYPE_DYNAMIC) {
07716          /* Wait to be signalled or time out */
07717          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
07718          ts.tv_sec = tv.tv_sec;
07719          ts.tv_nsec = tv.tv_usec * 1000;
07720          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
07721             ast_mutex_unlock(&thread->lock);
07722             AST_LIST_LOCK(&dynamic_list);
07723             AST_LIST_REMOVE(&dynamic_list, thread, list);
07724             iaxdynamicthreadcount--;
07725             AST_LIST_UNLOCK(&dynamic_list);
07726             break;      /* exiting the main loop */
07727          }
07728       } else {
07729          ast_cond_wait(&thread->cond, &thread->lock);
07730       }
07731       ast_mutex_unlock(&thread->lock);
07732 
07733       /* Add ourselves to the active list now */
07734       AST_LIST_LOCK(&active_list);
07735       AST_LIST_INSERT_HEAD(&active_list, thread, list);
07736       AST_LIST_UNLOCK(&active_list);
07737 
07738       /* See what we need to do */
07739       switch(thread->iostate) {
07740       case IAX_IOSTATE_READY:
07741          thread->actions++;
07742          thread->iostate = IAX_IOSTATE_PROCESSING;
07743          socket_process(thread);
07744          break;
07745       case IAX_IOSTATE_SCHEDREADY:
07746          thread->actions++;
07747          thread->iostate = IAX_IOSTATE_PROCESSING;
07748 #ifdef SCHED_MULTITHREADED
07749          thread->schedfunc(thread->scheddata);
07750 #endif      
07751          break;
07752       }
07753       time(&thread->checktime);
07754       thread->iostate = IAX_IOSTATE_IDLE;
07755 #ifdef DEBUG_SCHED_MULTITHREAD
07756       thread->curfunc[0]='\0';
07757 #endif      
07758 
07759       /* Now... remove ourselves from the active list, and return to the idle list */
07760       AST_LIST_LOCK(&active_list);
07761       AST_LIST_REMOVE(&active_list, thread, list);
07762       AST_LIST_UNLOCK(&active_list);
07763 
07764       /* Go back into our respective list */
07765       put_into_idle = 1;
07766    }
07767 
07768    /* I am exiting here on my own volition, I need to clean up my own data structures
07769    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
07770    */
07771    pthread_cleanup_pop(1);
07772 
07773    return NULL;
07774 }
07775 
07776 static int iax2_do_register(struct iax2_registry *reg)
07777 {
07778    struct iax_ie_data ied;
07779    if (option_debug && iaxdebug)
07780       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07781 
07782    if (reg->dnsmgr && 
07783        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
07784       /* Maybe the IP has changed, force DNS refresh */
07785       ast_dnsmgr_refresh(reg->dnsmgr);
07786    }
07787    
07788    /*
07789     * if IP has Changed, free allocated call to create a new one with new IP
07790     * call has the pointer to IP and must be updated to the new one
07791     */
07792    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
07793       ast_mutex_lock(&iaxsl[reg->callno]);
07794       iax2_destroy(reg->callno);
07795       ast_mutex_unlock(&iaxsl[reg->callno]);
07796       reg->callno = 0;
07797    }
07798    if (!reg->addr.sin_addr.s_addr) {
07799       if (option_debug && iaxdebug)
07800          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
07801       /* Setup the next registration attempt */
07802       if (reg->expire > -1)
07803          ast_sched_del(sched, reg->expire);
07804       reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07805       return -1;
07806    }
07807 
07808    if (!reg->callno) {
07809       if (option_debug)
07810          ast_log(LOG_DEBUG, "Allocate call number\n");
07811       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07812       if (reg->callno < 1) {
07813          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07814          return -1;
07815       } else if (option_debug)
07816          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07817       iaxs[reg->callno]->reg = reg;
07818    }
07819    /* Schedule the next registration attempt */
07820    if (reg->expire > -1)
07821       ast_sched_del(sched, reg->expire);
07822    /* Setup the next registration a little early */
07823    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07824    /* Send the request */
07825    memset(&ied, 0, sizeof(ied));
07826    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07827    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07828    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07829    reg->regstate = REG_STATE_REGSENT;
07830    return 0;
07831 }
07832 
07833 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
07834 {
07835    if (pos != 3)
07836       return NULL;
07837    return iax_prov_complete_template(line, word, pos, state);
07838 }
07839 
07840 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
07841 {
07842    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07843       is found for template */
07844    struct iax_ie_data provdata;
07845    struct iax_ie_data ied;
07846    unsigned int sig;
07847    struct sockaddr_in sin;
07848    int callno;
07849    struct create_addr_info cai;
07850 
07851    memset(&cai, 0, sizeof(cai));
07852 
07853    if (option_debug)
07854       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07855 
07856    if (iax_provision_build(&provdata, &sig, template, force)) {
07857       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07858       return 0;
07859    }
07860 
07861    if (end) {
07862       memcpy(&sin, end, sizeof(sin));
07863       cai.sockfd = sockfd;
07864    } else if (create_addr(dest, &sin, &cai))
07865       return -1;
07866 
07867    /* Build the rest of the message */
07868    memset(&ied, 0, sizeof(ied));
07869    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07870 
07871    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07872    if (!callno)
07873       return -1;
07874 
07875    ast_mutex_lock(&iaxsl[callno]);
07876    if (iaxs[callno]) {
07877       /* Schedule autodestruct in case they don't ever give us anything back */
07878       if (iaxs[callno]->autoid > -1)
07879          ast_sched_del(sched, iaxs[callno]->autoid);
07880       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07881       ast_set_flag(iaxs[callno], IAX_PROVISION);
07882       /* Got a call number now, so go ahead and send the provisioning information */
07883       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07884    }
07885    ast_mutex_unlock(&iaxsl[callno]);
07886 
07887    return 1;
07888 }
07889 
07890 static char *papp = "IAX2Provision";
07891 static char *psyn = "Provision a calling IAXy with a given template";
07892 static char *pdescrip = 
07893 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
07894 "the calling entity is in fact an IAXy) with the given template or\n"
07895 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
07896 
07897 /*! iax2provision
07898 \ingroup applications
07899 */
07900 static int iax2_prov_app(struct ast_channel *chan, void *data)
07901 {
07902    int res;
07903    char *sdata;
07904    char *opts;
07905    int force =0;
07906    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
07907    if (ast_strlen_zero(data))
07908       data = "default";
07909    sdata = ast_strdupa(data);
07910    opts = strchr(sdata, '|');
07911    if (opts)
07912       *opts='\0';
07913 
07914    if (chan->tech != &iax2_tech) {
07915       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
07916       return -1;
07917    } 
07918    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
07919       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
07920       return -1;
07921    }
07922    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
07923    if (option_verbose > 2)
07924       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
07925       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
07926       sdata, res);
07927    return res;
07928 }
07929 
07930 
07931 static int iax2_prov_cmd(int fd, int argc, char *argv[])
07932 {
07933    int force = 0;
07934    int res;
07935    if (argc < 4)
07936       return RESULT_SHOWUSAGE;
07937    if ((argc > 4)) {
07938       if (!strcasecmp(argv[4], "forced"))
07939          force = 1;
07940       else
07941          return RESULT_SHOWUSAGE;
07942    }
07943    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07944    if (res < 0)
07945       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07946    else if (res < 1)
07947       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07948    else
07949       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07950    return RESULT_SUCCESS;
07951 }
07952 
07953 static void __iax2_poke_noanswer(void *data)
07954 {
07955    struct iax2_peer *peer = data;
07956    if (peer->lastms > -1) {
07957       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07958       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07959       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07960    }
07961    if (peer->callno > 0) {
07962       ast_mutex_lock(&iaxsl[peer->callno]);
07963       iax2_destroy(peer->callno);
07964       ast_mutex_unlock(&iaxsl[peer->callno]);
07965    }
07966    peer->callno = 0;
07967    peer->lastms = -1;
07968    /* Try again quickly */
07969    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07970 }
07971 
07972 static int iax2_poke_noanswer(void *data)
07973 {
07974    struct iax2_peer *peer = data;
07975    peer->pokeexpire = -1;
07976 #ifdef SCHED_MULTITHREADED
07977    if (schedule_action(__iax2_poke_noanswer, data))
07978 #endif      
07979       __iax2_poke_noanswer(data);
07980    return 0;
07981 }
07982 
07983 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
07984 {
07985    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07986       /* IF we have no IP, or this isn't to be monitored, return
07987         immediately after clearing things out */
07988       peer->lastms = 0;
07989       peer->historicms = 0;
07990       peer->pokeexpire = -1;
07991       peer->callno = 0;
07992       return 0;
07993    }
07994    if (peer->callno > 0) {
07995       ast_log(LOG_NOTICE, "Still have a callno...\n");
07996       ast_mutex_lock(&iaxsl[peer->callno]);
07997       iax2_destroy(peer->callno);
07998       ast_mutex_unlock(&iaxsl[peer->callno]);
07999    }
08000    if (heldcall)
08001       ast_mutex_unlock(&iaxsl[heldcall]);
08002    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
08003    if (heldcall)
08004       ast_mutex_lock(&iaxsl[heldcall]);
08005    if (peer->callno < 1) {
08006       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08007       return -1;
08008    }
08009 
08010    /* Speed up retransmission times for this qualify call */
08011    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08012    iaxs[peer->callno]->peerpoke = peer;
08013    
08014    /* Remove any pending pokeexpire task */
08015    if (peer->pokeexpire > -1)
08016       ast_sched_del(sched, peer->pokeexpire);
08017 
08018    /* Queue up a new task to handle no reply */
08019    /* If the host is already unreachable then use the unreachable interval instead */
08020    if (peer->lastms < 0) {
08021       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
08022    } else
08023       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
08024 
08025    /* And send the poke */
08026    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08027 
08028    return 0;
08029 }
08030 
08031 static void free_context(struct iax2_context *con)
08032 {
08033    struct iax2_context *conl;
08034    while(con) {
08035       conl = con;
08036       con = con->next;
08037       free(conl);
08038    }
08039 }
08040 
08041 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08042 {
08043    int callno;
08044    int res;
08045    int fmt, native;
08046    struct sockaddr_in sin;
08047    struct ast_channel *c;
08048    struct parsed_dial_string pds;
08049    struct create_addr_info cai;
08050    char *tmpstr;
08051 
08052    memset(&pds, 0, sizeof(pds));
08053    tmpstr = ast_strdupa(data);
08054    parse_dial_string(tmpstr, &pds);
08055 
08056    memset(&cai, 0, sizeof(cai));
08057    cai.capability = iax2_capability;
08058 
08059    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08060 
08061    if (!pds.peer) {
08062       ast_log(LOG_WARNING, "No peer given\n");
08063       return NULL;
08064    }
08065           
08066    
08067    /* Populate our address from the given */
08068    if (create_addr(pds.peer, &sin, &cai)) {
08069       *cause = AST_CAUSE_UNREGISTERED;
08070       return NULL;
08071    }
08072 
08073    if (pds.port)
08074       sin.sin_port = htons(atoi(pds.port));
08075 
08076    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08077    if (callno < 1) {
08078       ast_log(LOG_WARNING, "Unable to create call\n");
08079       *cause = AST_CAUSE_CONGESTION;
08080       return NULL;
08081    }
08082 
08083    ast_mutex_lock(&iaxsl[callno]);
08084 
08085    /* If this is a trunk, update it now */
08086    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08087    if (ast_test_flag(&cai, IAX_TRUNK))
08088       callno = make_trunk(callno, 1);
08089    iaxs[callno]->maxtime = cai.maxtime;
08090    if (cai.found)
08091       ast_string_field_set(iaxs[callno], host, pds.peer);
08092 
08093    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08094 
08095    ast_mutex_unlock(&iaxsl[callno]);
08096 
08097    if (c) {
08098       /* Choose a format we can live with */
08099       if (c->nativeformats & format) 
08100          c->nativeformats &= format;
08101       else {
08102          native = c->nativeformats;
08103          fmt = format;
08104          res = ast_translator_best_choice(&fmt, &native);
08105          if (res < 0) {
08106             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08107                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08108             ast_hangup(c);
08109             return NULL;
08110          }
08111          c->nativeformats = native;
08112       }
08113       c->readformat = ast_best_codec(c->nativeformats);
08114       c->writeformat = c->readformat;
08115    }
08116 
08117    return c;
08118 }
08119 
08120 static void *sched_thread(void *ignore)
08121 {
08122    int count;
08123    int res;
08124    struct timeval tv;
08125    struct timespec ts;
08126 
08127    for (;;) {
08128       res = ast_sched_wait(sched);
08129       if ((res > 1000) || (res < 0))
08130          res = 1000;
08131       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08132       ts.tv_sec = tv.tv_sec;
08133       ts.tv_nsec = tv.tv_usec * 1000;
08134 
08135       pthread_testcancel();
08136       ast_mutex_lock(&sched_lock);
08137       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08138       ast_mutex_unlock(&sched_lock);
08139       pthread_testcancel();
08140 
08141       count = ast_sched_runq(sched);
08142       if (count >= 20)
08143          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08144    }
08145    return NULL;
08146 }
08147 
08148 static void *network_thread(void *ignore)
08149 {
08150    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08151       from the network, and queue them for delivery to the channels */
08152    int res, count, wakeup;
08153    struct iax_frame *f;
08154 
08155    if (timingfd > -1)
08156       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08157    
08158    for(;;) {
08159       pthread_testcancel();
08160 
08161       /* Go through the queue, sending messages which have not yet been
08162          sent, and scheduling retransmissions if appropriate */
08163       AST_LIST_LOCK(&iaxq.queue);
08164       count = 0;
08165       wakeup = -1;
08166       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08167          if (f->sentyet)
08168             continue;
08169          
08170          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
08171          if (ast_mutex_trylock(&iaxsl[f->callno])) {
08172             wakeup = 1;
08173             continue;
08174          }
08175 
08176          f->sentyet++;
08177 
08178          if (iaxs[f->callno]) {
08179             send_packet(f);
08180             count++;
08181          } 
08182 
08183          ast_mutex_unlock(&iaxsl[f->callno]);
08184 
08185          if (f->retries < 0) {
08186             /* This is not supposed to be retransmitted */
08187             AST_LIST_REMOVE(&iaxq.queue, f, list);
08188             iaxq.count--;
08189             /* Free the iax frame */
08190             iax_frame_free(f);
08191          } else {
08192             /* We need reliable delivery.  Schedule a retransmission */
08193             f->retries++;
08194             f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08195             signal_condition(&sched_lock, &sched_cond);
08196          }
08197       }
08198       AST_LIST_TRAVERSE_SAFE_END
08199       AST_LIST_UNLOCK(&iaxq.queue);
08200 
08201       pthread_testcancel();
08202 
08203       if (count >= 20)
08204          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08205 
08206       /* Now do the IO, and run scheduled tasks */
08207       res = ast_io_wait(io, wakeup);
08208       if (res >= 0) {
08209          if (res >= 20)
08210             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08211       }
08212    }
08213    return NULL;
08214 }
08215 
08216 static int start_network_thread(void)
08217 {
08218    pthread_attr_t attr;
08219    int threadcount = 0;
08220    int x;
08221    for (x = 0; x < iaxthreadcount; x++) {
08222       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08223       if (thread) {
08224          thread->type = IAX_TYPE_POOL;
08225          thread->threadnum = ++threadcount;
08226          ast_mutex_init(&thread->lock);
08227          ast_cond_init(&thread->cond, NULL);
08228          pthread_attr_init(&attr);
08229          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08230          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08231             ast_log(LOG_WARNING, "Failed to create new thread!\n");
08232             free(thread);
08233             thread = NULL;
08234          }
08235          AST_LIST_LOCK(&idle_list);
08236          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08237          AST_LIST_UNLOCK(&idle_list);
08238       }
08239    }
08240    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08241    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08242    if (option_verbose > 1)
08243       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08244    return 0;
08245 }
08246 
08247 static struct iax2_context *build_context(char *context)
08248 {
08249    struct iax2_context *con;
08250 
08251    if ((con = ast_calloc(1, sizeof(*con))))
08252       ast_copy_string(con->context, context, sizeof(con->context));
08253    
08254    return con;
08255 }
08256 
08257 static int get_auth_methods(char *value)
08258 {
08259    int methods = 0;
08260    if (strstr(value, "rsa"))
08261       methods |= IAX_AUTH_RSA;
08262    if (strstr(value, "md5"))
08263       methods |= IAX_AUTH_MD5;
08264    if (strstr(value, "plaintext"))
08265       methods |= IAX_AUTH_PLAINTEXT;
08266    return methods;
08267 }
08268 
08269 
08270 /*! \brief Check if address can be used as packet source.
08271  \return 0  address available, 1  address unavailable, -1  error
08272 */
08273 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08274 {
08275    int sd;
08276    int res;
08277    
08278    sd = socket(AF_INET, SOCK_DGRAM, 0);
08279    if (sd < 0) {
08280       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08281       return -1;
08282    }
08283 
08284    res = bind(sd, sa, salen);
08285    if (res < 0) {
08286       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08287       close(sd);
08288       return 1;
08289    }
08290 
08291    close(sd);
08292    return 0;
08293 }
08294 
08295 /*! \brief Parse the "sourceaddress" value,
08296   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08297   not found. */
08298 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08299 {
08300    struct sockaddr_in sin;
08301    int nonlocal = 1;
08302    int port = IAX_DEFAULT_PORTNO;
08303    int sockfd = defaultsockfd;
08304    char *tmp;
08305    char *addr;
08306    char *portstr;
08307 
08308    if (!(tmp = ast_strdupa(srcaddr)))
08309       return -1;
08310 
08311    addr = strsep(&tmp, ":");
08312    portstr = tmp;
08313 
08314    if (portstr) {
08315       port = atoi(portstr);
08316       if (port < 1)
08317          port = IAX_DEFAULT_PORTNO;
08318    }
08319    
08320    if (!ast_get_ip(&sin, addr)) {
08321       struct ast_netsock *sock;
08322       int res;
08323 
08324       sin.sin_port = 0;
08325       sin.sin_family = AF_INET;
08326       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08327       if (res == 0) {
08328          /* ip address valid. */
08329          sin.sin_port = htons(port);
08330          if (!(sock = ast_netsock_find(netsock, &sin)))
08331             sock = ast_netsock_find(outsock, &sin);
08332          if (sock) {
08333             sockfd = ast_netsock_sockfd(sock);
08334             nonlocal = 0;
08335          } else {
08336             unsigned int orig_saddr = sin.sin_addr.s_addr;
08337             /* INADDR_ANY matches anyway! */
08338             sin.sin_addr.s_addr = INADDR_ANY;
08339             if (ast_netsock_find(netsock, &sin)) {
08340                sin.sin_addr.s_addr = orig_saddr;
08341                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
08342                if (sock) {
08343                   sockfd = ast_netsock_sockfd(sock);
08344                   ast_netsock_unref(sock);
08345                   nonlocal = 0;
08346                } else {
08347                   nonlocal = 2;
08348                }
08349             }
08350          }
08351       }
08352    }
08353       
08354    peer->sockfd = sockfd;
08355 
08356    if (nonlocal == 1) {
08357       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08358          srcaddr, peer->name);
08359       return -1;
08360         } else if (nonlocal == 2) {
08361       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
08362          srcaddr, peer->name);
08363          return -1;
08364    } else {
08365       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08366       return 0;
08367    }
08368 }
08369 
08370       
08371 /*! \brief Create peer structure based on configuration */
08372 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08373 {
08374    struct iax2_peer *peer = NULL;
08375    struct ast_ha *oldha = NULL;
08376    int maskfound=0;
08377    int found=0;
08378    int firstpass=1;
08379 
08380    AST_LIST_LOCK(&peers);
08381    if (!temponly) {
08382       AST_LIST_TRAVERSE(&peers, peer, entry) {
08383          if (!strcmp(peer->name, name)) { 
08384             if (!ast_test_flag(peer, IAX_DELME))
08385                firstpass = 0;
08386             break;
08387          }
08388       }
08389    } else
08390       peer = NULL;   
08391    if (peer) {
08392       found++;
08393       if (firstpass) {
08394          oldha = peer->ha;
08395          peer->ha = NULL;
08396       }
08397       AST_LIST_REMOVE(&peers, peer, entry);
08398       AST_LIST_UNLOCK(&peers);
08399    } else {
08400       AST_LIST_UNLOCK(&peers);
08401       if ((peer = ast_calloc(1, sizeof(*peer)))) {
08402          peer->expire = -1;
08403          peer->pokeexpire = -1;
08404          peer->sockfd = defaultsockfd;
08405          if (ast_string_field_init(peer, 32)) {
08406             free(peer);
08407             peer = NULL;
08408          }
08409       }
08410    }
08411    if (peer) {
08412       if (firstpass) {
08413          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08414          peer->encmethods = iax2_encryption;
08415          peer->adsi = adsi;
08416          ast_string_field_set(peer,secret,"");
08417          if (!found) {
08418             ast_string_field_set(peer, name, name);
08419             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08420             peer->expiry = min_reg_expire;
08421          }
08422          peer->prefs = prefs;
08423          peer->capability = iax2_capability;
08424          peer->smoothing = 0;
08425          peer->pokefreqok = DEFAULT_FREQ_OK;
08426          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08427          ast_string_field_set(peer,context,"");
08428          ast_string_field_set(peer,peercontext,"");
08429          ast_clear_flag(peer, IAX_HASCALLERID);
08430          ast_string_field_set(peer, cid_name, "");
08431          ast_string_field_set(peer, cid_num, "");
08432       }
08433 
08434       if (!v) {
08435          v = alt;
08436          alt = NULL;
08437       }
08438       while(v) {
08439          if (!strcasecmp(v->name, "secret")) {
08440             ast_string_field_set(peer, secret, v->value);
08441          } else if (!strcasecmp(v->name, "mailbox")) {
08442             ast_string_field_set(peer, mailbox, v->value);
08443          } else if (!strcasecmp(v->name, "mohinterpret")) {
08444             ast_string_field_set(peer, mohinterpret, v->value);
08445          } else if (!strcasecmp(v->name, "mohsuggest")) {
08446             ast_string_field_set(peer, mohsuggest, v->value);
08447          } else if (!strcasecmp(v->name, "dbsecret")) {
08448             ast_string_field_set(peer, dbsecret, v->value);
08449          } else if (!strcasecmp(v->name, "trunk")) {
08450             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08451             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08452                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08453                ast_clear_flag(peer, IAX_TRUNK);
08454             }
08455          } else if (!strcasecmp(v->name, "auth")) {
08456             peer->authmethods = get_auth_methods(v->value);
08457          } else if (!strcasecmp(v->name, "encryption")) {
08458             peer->encmethods = get_encrypt_methods(v->value);
08459          } else if (!strcasecmp(v->name, "notransfer")) {
08460             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08461             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
08462             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08463          } else if (!strcasecmp(v->name, "transfer")) {
08464             if (!strcasecmp(v->value, "mediaonly")) {
08465                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
08466             } else if (ast_true(v->value)) {
08467                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08468             } else 
08469                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08470          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08471             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08472          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08473             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08474          } else if (!strcasecmp(v->name, "host")) {
08475             if (!strcasecmp(v->value, "dynamic")) {
08476                /* They'll register with us */
08477                ast_set_flag(peer, IAX_DYNAMIC); 
08478                if (!found) {
08479                   /* Initialize stuff iff we're not found, otherwise
08480                      we keep going with what we had */
08481                   memset(&peer->addr.sin_addr, 0, 4);
08482                   if (peer->addr.sin_port) {
08483                      /* If we've already got a port, make it the default rather than absolute */
08484                      peer->defaddr.sin_port = peer->addr.sin_port;
08485                      peer->addr.sin_port = 0;
08486                   }
08487                }
08488             } else {
08489                /* Non-dynamic.  Make sure we become that way if we're not */
08490                if (peer->expire > -1)
08491                   ast_sched_del(sched, peer->expire);
08492                peer->expire = -1;
08493                ast_clear_flag(peer, IAX_DYNAMIC);
08494                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08495                   ast_string_field_free_pools(peer);
08496                   free(peer);
08497                   return NULL;
08498                }
08499                if (!peer->addr.sin_port)
08500                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08501             }
08502             if (!maskfound)
08503                inet_aton("255.255.255.255", &peer->mask);
08504          } else if (!strcasecmp(v->name, "defaultip")) {
08505             if (ast_get_ip(&peer->defaddr, v->value)) {
08506                ast_string_field_free_pools(peer);
08507                free(peer);
08508                return NULL;
08509             }
08510          } else if (!strcasecmp(v->name, "sourceaddress")) {
08511             peer_set_srcaddr(peer, v->value);
08512          } else if (!strcasecmp(v->name, "permit") ||
08513                   !strcasecmp(v->name, "deny")) {
08514             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08515          } else if (!strcasecmp(v->name, "mask")) {
08516             maskfound++;
08517             inet_aton(v->value, &peer->mask);
08518          } else if (!strcasecmp(v->name, "context")) {
08519             ast_string_field_set(peer, context, v->value);
08520          } else if (!strcasecmp(v->name, "regexten")) {
08521             ast_string_field_set(peer, regexten, v->value);
08522          } else if (!strcasecmp(v->name, "peercontext")) {
08523             ast_string_field_set(peer, peercontext, v->value);
08524          } else if (!strcasecmp(v->name, "port")) {
08525             if (ast_test_flag(peer, IAX_DYNAMIC))
08526                peer->defaddr.sin_port = htons(atoi(v->value));
08527             else
08528                peer->addr.sin_port = htons(atoi(v->value));
08529          } else if (!strcasecmp(v->name, "username")) {
08530             ast_string_field_set(peer, username, v->value);
08531          } else if (!strcasecmp(v->name, "allow")) {
08532             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08533          } else if (!strcasecmp(v->name, "disallow")) {
08534             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08535          } else if (!strcasecmp(v->name, "callerid")) {
08536             if (!ast_strlen_zero(v->value)) {
08537                char name2[80];
08538                char num2[80];
08539                ast_callerid_split(v->value, name2, 80, num2, 80);
08540                ast_string_field_set(peer, cid_name, name2);
08541                ast_string_field_set(peer, cid_num, num2);
08542                ast_set_flag(peer, IAX_HASCALLERID);
08543             } else {
08544                ast_clear_flag(peer, IAX_HASCALLERID);
08545                ast_string_field_set(peer, cid_name, "");
08546                ast_string_field_set(peer, cid_num, "");
08547             }
08548          } else if (!strcasecmp(v->name, "fullname")) {
08549             if (!ast_strlen_zero(v->value)) {
08550                ast_string_field_set(peer, cid_name, v->value);
08551                ast_set_flag(peer, IAX_HASCALLERID);
08552             } else {
08553                ast_string_field_set(peer, cid_name, "");
08554                if (ast_strlen_zero(peer->cid_num))
08555                   ast_clear_flag(peer, IAX_HASCALLERID);
08556             }
08557          } else if (!strcasecmp(v->name, "cid_number")) {
08558             if (!ast_strlen_zero(v->value)) {
08559                ast_string_field_set(peer, cid_num, v->value);
08560                ast_set_flag(peer, IAX_HASCALLERID);
08561             } else {
08562                ast_string_field_set(peer, cid_num, "");
08563                if (ast_strlen_zero(peer->cid_name))
08564                   ast_clear_flag(peer, IAX_HASCALLERID);
08565             }
08566          } else if (!strcasecmp(v->name, "sendani")) {
08567             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08568          } else if (!strcasecmp(v->name, "inkeys")) {
08569             ast_string_field_set(peer, inkeys, v->value);
08570          } else if (!strcasecmp(v->name, "outkey")) {
08571             ast_string_field_set(peer, outkey, v->value);
08572          } else if (!strcasecmp(v->name, "qualify")) {
08573             if (!strcasecmp(v->value, "no")) {
08574                peer->maxms = 0;
08575             } else if (!strcasecmp(v->value, "yes")) {
08576                peer->maxms = DEFAULT_MAXMS;
08577             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08578                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);
08579                peer->maxms = 0;
08580             }
08581          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08582             peer->smoothing = ast_true(v->value);
08583          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08584             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08585                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);
08586             }
08587          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08588             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08589                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);
08590             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08591          } else if (!strcasecmp(v->name, "timezone")) {
08592             ast_string_field_set(peer, zonetag, v->value);
08593          } else if (!strcasecmp(v->name, "adsi")) {
08594             peer->adsi = ast_true(v->value);
08595          }/* else if (strcasecmp(v->name,"type")) */
08596          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08597          v = v->next;
08598          if (!v) {
08599             v = alt;
08600             alt = NULL;
08601          }
08602       }
08603       if (!peer->authmethods)
08604          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08605       ast_clear_flag(peer, IAX_DELME); 
08606       /* Make sure these are IPv4 addresses */
08607       peer->addr.sin_family = AF_INET;
08608    }
08609    if (oldha)
08610       ast_free_ha(oldha);
08611    return peer;
08612 }
08613 
08614 /*! \brief Create in-memory user structure from configuration */
08615 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08616 {
08617    struct iax2_user *user = NULL;
08618    struct iax2_context *con, *conl = NULL;
08619    struct ast_ha *oldha = NULL;
08620    struct iax2_context *oldcon = NULL;
08621    int format;
08622    int firstpass=1;
08623    int oldcurauthreq = 0;
08624    char *varname = NULL, *varval = NULL;
08625    struct ast_variable *tmpvar = NULL;
08626    
08627    AST_LIST_LOCK(&users);
08628    if (!temponly) {
08629       AST_LIST_TRAVERSE(&users, user, entry) {
08630          if (!strcmp(user->name, name)) { 
08631             if (!ast_test_flag(user, IAX_DELME))
08632                firstpass = 0;
08633             break;
08634          }
08635       }
08636    } else
08637       user = NULL;
08638 
08639    if (user) {
08640       if (firstpass) {
08641          oldcurauthreq = user->curauthreq;
08642          oldha = user->ha;
08643          oldcon = user->contexts;
08644          user->ha = NULL;
08645          user->contexts = NULL;
08646       }
08647       /* Already in the list, remove it and it will be added back (or FREE'd) */
08648       AST_LIST_REMOVE(&users, user, entry);
08649       AST_LIST_UNLOCK(&users);
08650    } else {
08651       AST_LIST_UNLOCK(&users);
08652       /* This is going to memset'd to 0 in the next block */
08653       user = ast_calloc(sizeof(*user),1);
08654    }
08655    
08656    if (user) {
08657       if (firstpass) {
08658          ast_string_field_free_pools(user);
08659          memset(user, 0, sizeof(struct iax2_user));
08660          if (ast_string_field_init(user, 32)) {
08661             free(user);
08662             user = NULL;
08663          }
08664          user->maxauthreq = maxauthreq;
08665          user->curauthreq = oldcurauthreq;
08666          user->prefs = prefs;
08667          user->capability = iax2_capability;
08668          user->encmethods = iax2_encryption;
08669          user->adsi = adsi;
08670          ast_string_field_set(user, name, name);
08671          ast_string_field_set(user, language, language);
08672          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08673          ast_clear_flag(user, IAX_HASCALLERID);
08674          ast_string_field_set(user, cid_name, "");
08675          ast_string_field_set(user, cid_num, "");
08676       }
08677       if (!v) {
08678          v = alt;
08679          alt = NULL;
08680       }
08681       while(v) {
08682          if (!strcasecmp(v->name, "context")) {
08683             con = build_context(v->value);
08684             if (con) {
08685                if (conl)
08686                   conl->next = con;
08687                else
08688                   user->contexts = con;
08689                conl = con;
08690             }
08691          } else if (!strcasecmp(v->name, "permit") ||
08692                   !strcasecmp(v->name, "deny")) {
08693             user->ha = ast_append_ha(v->name, v->value, user->ha);
08694          } else if (!strcasecmp(v->name, "setvar")) {
08695             varname = ast_strdupa(v->value);
08696             if (varname && (varval = strchr(varname,'='))) {
08697                *varval = '\0';
08698                varval++;
08699                if((tmpvar = ast_variable_new(varname, varval))) {
08700                   tmpvar->next = user->vars; 
08701                   user->vars = tmpvar;
08702                }
08703             }
08704          } else if (!strcasecmp(v->name, "allow")) {
08705             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08706          } else if (!strcasecmp(v->name, "disallow")) {
08707             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08708          } else if (!strcasecmp(v->name, "trunk")) {
08709             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08710             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08711                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08712                ast_clear_flag(user, IAX_TRUNK);
08713             }
08714          } else if (!strcasecmp(v->name, "auth")) {
08715             user->authmethods = get_auth_methods(v->value);
08716          } else if (!strcasecmp(v->name, "encryption")) {
08717             user->encmethods = get_encrypt_methods(v->value);
08718          } else if (!strcasecmp(v->name, "notransfer")) {
08719             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08720             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
08721             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08722          } else if (!strcasecmp(v->name, "transfer")) {
08723             if (!strcasecmp(v->value, "mediaonly")) {
08724                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
08725             } else if (ast_true(v->value)) {
08726                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08727             } else 
08728                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08729          } else if (!strcasecmp(v->name, "codecpriority")) {
08730             if(!strcasecmp(v->value, "caller"))
08731                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08732             else if(!strcasecmp(v->value, "disabled"))
08733                ast_set_flag(user, IAX_CODEC_NOPREFS);
08734             else if(!strcasecmp(v->value, "reqonly")) {
08735                ast_set_flag(user, IAX_CODEC_NOCAP);
08736                ast_set_flag(user, IAX_CODEC_NOPREFS);
08737             }
08738          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08739             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
08740          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08741             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
08742          } else if (!strcasecmp(v->name, "dbsecret")) {
08743             ast_string_field_set(user, dbsecret, v->value);
08744          } else if (!strcasecmp(v->name, "secret")) {
08745             if (!ast_strlen_zero(user->secret)) {
08746                char *old = ast_strdupa(user->secret);
08747 
08748                ast_string_field_build(user, secret, "%s;%s", old, v->value);
08749             } else
08750                ast_string_field_set(user, secret, v->value);
08751          } else if (!strcasecmp(v->name, "callerid")) {
08752             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
08753                char name2[80];
08754                char num2[80];
08755                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
08756                ast_string_field_set(user, cid_name, name2);
08757                ast_string_field_set(user, cid_num, num2);
08758                ast_set_flag(user, IAX_HASCALLERID);
08759             } else {
08760                ast_clear_flag(user, IAX_HASCALLERID);
08761                ast_string_field_set(user, cid_name, "");
08762                ast_string_field_set(user, cid_num, "");
08763             }
08764          } else if (!strcasecmp(v->name, "fullname")) {
08765             if (!ast_strlen_zero(v->value)) {
08766                ast_string_field_set(user, cid_name, v->value);
08767                ast_set_flag(user, IAX_HASCALLERID);
08768             } else {
08769                ast_string_field_set(user, cid_name, "");
08770                if (ast_strlen_zero(user->cid_num))
08771                   ast_clear_flag(user, IAX_HASCALLERID);
08772             }
08773          } else if (!strcasecmp(v->name, "cid_number")) {
08774             if (!ast_strlen_zero(v->value)) {
08775                ast_string_field_set(user, cid_num, v->value);
08776                ast_set_flag(user, IAX_HASCALLERID);
08777             } else {
08778                ast_string_field_set(user, cid_num, "");
08779                if (ast_strlen_zero(user->cid_name))
08780                   ast_clear_flag(user, IAX_HASCALLERID);
08781             }
08782          } else if (!strcasecmp(v->name, "accountcode")) {
08783             ast_string_field_set(user, accountcode, v->value);
08784          } else if (!strcasecmp(v->name, "mohinterpret")) {
08785             ast_string_field_set(user, mohinterpret, v->value);
08786          } else if (!strcasecmp(v->name, "mohsuggest")) {
08787             ast_string_field_set(user, mohsuggest, v->value);
08788          } else if (!strcasecmp(v->name, "language")) {
08789             ast_string_field_set(user, language, v->value);
08790          } else if (!strcasecmp(v->name, "amaflags")) {
08791             format = ast_cdr_amaflags2int(v->value);
08792             if (format < 0) {
08793                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08794             } else {
08795                user->amaflags = format;
08796             }
08797          } else if (!strcasecmp(v->name, "inkeys")) {
08798             ast_string_field_set(user, inkeys, v->value);
08799          } else if (!strcasecmp(v->name, "maxauthreq")) {
08800             user->maxauthreq = atoi(v->value);
08801             if (user->maxauthreq < 0)
08802                user->maxauthreq = 0;
08803          } else if (!strcasecmp(v->name, "adsi")) {
08804             user->adsi = ast_true(v->value);
08805          }/* else if (strcasecmp(v->name,"type")) */
08806          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08807          v = v->next;
08808          if (!v) {
08809             v = alt;
08810             alt = NULL;
08811          }
08812       }
08813       if (!user->authmethods) {
08814          if (!ast_strlen_zero(user->secret)) {
08815             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08816             if (!ast_strlen_zero(user->inkeys))
08817                user->authmethods |= IAX_AUTH_RSA;
08818          } else if (!ast_strlen_zero(user->inkeys)) {
08819             user->authmethods = IAX_AUTH_RSA;
08820          } else {
08821             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08822          }
08823       }
08824       ast_clear_flag(user, IAX_DELME);
08825    }
08826    if (oldha)
08827       ast_free_ha(oldha);
08828    if (oldcon)
08829       free_context(oldcon);
08830    return user;
08831 }
08832 
08833 static void delete_users(void)
08834 {
08835    struct iax2_user *user;
08836    struct iax2_peer *peer;
08837    struct iax2_registry *reg;
08838 
08839    AST_LIST_LOCK(&users);
08840    AST_LIST_TRAVERSE(&users, user, entry)
08841       ast_set_flag(user, IAX_DELME);
08842    AST_LIST_UNLOCK(&users);
08843 
08844    AST_LIST_LOCK(&registrations);
08845    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
08846       if (reg->expire > -1)
08847          ast_sched_del(sched, reg->expire);
08848       if (reg->callno) {
08849          ast_mutex_lock(&iaxsl[reg->callno]);
08850          if (iaxs[reg->callno]) {
08851             iaxs[reg->callno]->reg = NULL;
08852             iax2_destroy(reg->callno);
08853          }
08854          ast_mutex_unlock(&iaxsl[reg->callno]);
08855       }
08856       if (reg->dnsmgr)
08857          ast_dnsmgr_release(reg->dnsmgr);
08858       free(reg);
08859    }
08860    AST_LIST_UNLOCK(&registrations);
08861 
08862    AST_LIST_LOCK(&peers);
08863    AST_LIST_TRAVERSE(&peers, peer, entry)
08864       ast_set_flag(peer, IAX_DELME);
08865    AST_LIST_UNLOCK(&peers);
08866 }
08867 
08868 static void destroy_user(struct iax2_user *user)
08869 {
08870    ast_free_ha(user->ha);
08871    free_context(user->contexts);
08872    if(user->vars) {
08873       ast_variables_destroy(user->vars);
08874       user->vars = NULL;
08875    }
08876    ast_string_field_free_pools(user);
08877    free(user);
08878 }
08879 
08880 static void prune_users(void)
08881 {
08882    struct iax2_user *user = NULL;
08883 
08884    AST_LIST_LOCK(&users);
08885    AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) {
08886       if (ast_test_flag(user, IAX_DELME)) {
08887          destroy_user(user);
08888          AST_LIST_REMOVE_CURRENT(&users, entry);
08889       }
08890    }
08891    AST_LIST_TRAVERSE_SAFE_END
08892    AST_LIST_UNLOCK(&users);
08893 
08894 }
08895 
08896 static void destroy_peer(struct iax2_peer *peer)
08897 {
08898    ast_free_ha(peer->ha);
08899 
08900    /* Delete it, it needs to disappear */
08901    if (peer->expire > -1)
08902       ast_sched_del(sched, peer->expire);
08903    if (peer->pokeexpire > -1)
08904       ast_sched_del(sched, peer->pokeexpire);
08905    if (peer->callno > 0) {
08906       ast_mutex_lock(&iaxsl[peer->callno]);
08907       iax2_destroy(peer->callno);
08908       ast_mutex_unlock(&iaxsl[peer->callno]);
08909    }
08910 
08911    register_peer_exten(peer, 0);
08912 
08913    if (peer->dnsmgr)
08914       ast_dnsmgr_release(peer->dnsmgr);
08915 
08916    ast_string_field_free_pools(peer);
08917 
08918    free(peer);
08919 }
08920 
08921 static void prune_peers(void){
08922    /* Prune peers who still are supposed to be deleted */
08923    struct iax2_peer *peer = NULL;
08924 
08925    AST_LIST_LOCK(&peers);
08926    AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) {
08927       if (ast_test_flag(peer, IAX_DELME)) {
08928          destroy_peer(peer);
08929          AST_LIST_REMOVE_CURRENT(&peers, entry);
08930       }
08931    }
08932    AST_LIST_TRAVERSE_SAFE_END
08933    AST_LIST_UNLOCK(&peers);
08934 }
08935 
08936 static void set_timing(void)
08937 {
08938 #ifdef HAVE_ZAPTEL
08939    int bs = trunkfreq * 8;
08940    if (timingfd > -1) {
08941       if (
08942 #ifdef ZT_TIMERACK
08943          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08944 #endif         
08945          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08946          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08947    }
08948 #endif
08949 }
08950 
08951 
08952 /*! \brief Load configuration */
08953 static int set_config(char *config_file, int reload)
08954 {
08955    struct ast_config *cfg, *ucfg;
08956    int capability=iax2_capability;
08957    struct ast_variable *v;
08958    char *cat;
08959    const char *utype;
08960    const char *tosval;
08961    int format;
08962    int portno = IAX_DEFAULT_PORTNO;
08963    int  x;
08964    struct iax2_user *user;
08965    struct iax2_peer *peer;
08966    struct ast_netsock *ns;
08967 #if 0
08968    static unsigned short int last_port=0;
08969 #endif
08970 
08971    cfg = ast_config_load(config_file);
08972    
08973    if (!cfg) {
08974       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08975       return -1;
08976    }
08977 
08978    /* Reset global codec prefs */   
08979    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08980    
08981    /* Reset Global Flags */
08982    memset(&globalflags, 0, sizeof(globalflags));
08983    ast_set_flag(&globalflags, IAX_RTUPDATE);
08984 
08985 #ifdef SO_NO_CHECK
08986    nochecksums = 0;
08987 #endif
08988 
08989    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08990    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08991 
08992    maxauthreq = 3;
08993 
08994    v = ast_variable_browse(cfg, "general");
08995 
08996    /* Seed initial tos value */
08997    tosval = ast_variable_retrieve(cfg, "general", "tos");
08998    if (tosval) {
08999       if (ast_str2tos(tosval, &tos))
09000          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09001    }
09002    while(v) {
09003       if (!strcasecmp(v->name, "bindport")){ 
09004          if (reload)
09005             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09006          else
09007             portno = atoi(v->value);
09008       } else if (!strcasecmp(v->name, "pingtime")) 
09009          ping_time = atoi(v->value);
09010       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09011          if (reload) {
09012             if (atoi(v->value) != iaxthreadcount)
09013                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09014          } else {
09015             iaxthreadcount = atoi(v->value);
09016             if (iaxthreadcount < 1) {
09017                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09018                iaxthreadcount = 1;
09019             } else if (iaxthreadcount > 256) {
09020                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09021                iaxthreadcount = 256;
09022             }
09023          }
09024       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09025          if (reload) {
09026             AST_LIST_LOCK(&dynamic_list);
09027             iaxmaxthreadcount = atoi(v->value);
09028             AST_LIST_UNLOCK(&dynamic_list);
09029          } else {
09030             iaxmaxthreadcount = atoi(v->value);
09031             if (iaxmaxthreadcount < 0) {
09032                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09033                iaxmaxthreadcount = 0;
09034             } else if (iaxmaxthreadcount > 256) {
09035                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09036                iaxmaxthreadcount = 256;
09037             }
09038          }
09039       } else if (!strcasecmp(v->name, "nochecksums")) {
09040 #ifdef SO_NO_CHECK
09041          if (ast_true(v->value))
09042             nochecksums = 1;
09043          else
09044             nochecksums = 0;
09045 #else
09046          if (ast_true(v->value))
09047             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09048 #endif
09049       }
09050       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09051          maxjitterbuffer = atoi(v->value);
09052       else if (!strcasecmp(v->name, "resyncthreshold")) 
09053          resyncthreshold = atoi(v->value);
09054       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09055          maxjitterinterps = atoi(v->value);
09056       else if (!strcasecmp(v->name, "lagrqtime")) 
09057          lagrq_time = atoi(v->value);
09058       else if (!strcasecmp(v->name, "maxregexpire")) 
09059          max_reg_expire = atoi(v->value);
09060       else if (!strcasecmp(v->name, "minregexpire")) 
09061          min_reg_expire = atoi(v->value);
09062       else if (!strcasecmp(v->name, "bindaddr")) {
09063          if (reload) {
09064             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09065          } else {
09066             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09067                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09068             } else {
09069                if (option_verbose > 1) {
09070                   if (strchr(v->value, ':'))
09071                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09072                   else
09073                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09074                }
09075                if (defaultsockfd < 0) 
09076                   defaultsockfd = ast_netsock_sockfd(ns);
09077                ast_netsock_unref(ns);
09078             }
09079          }
09080       } else if (!strcasecmp(v->name, "authdebug"))
09081          authdebug = ast_true(v->value);
09082       else if (!strcasecmp(v->name, "encryption"))
09083          iax2_encryption = get_encrypt_methods(v->value);
09084       else if (!strcasecmp(v->name, "notransfer")) {
09085          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09086          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09087          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09088       } else if (!strcasecmp(v->name, "transfer")) {
09089          if (!strcasecmp(v->value, "mediaonly")) {
09090             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09091          } else if (ast_true(v->value)) {
09092             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09093          } else 
09094             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09095       } else if (!strcasecmp(v->name, "codecpriority")) {
09096          if(!strcasecmp(v->value, "caller"))
09097             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09098          else if(!strcasecmp(v->value, "disabled"))
09099             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09100          else if(!strcasecmp(v->value, "reqonly")) {
09101             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09102             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09103          }
09104       } else if (!strcasecmp(v->name, "jitterbuffer"))
09105          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
09106       else if (!strcasecmp(v->name, "forcejitterbuffer"))
09107          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
09108       else if (!strcasecmp(v->name, "delayreject"))
09109          delayreject = ast_true(v->value);
09110       else if (!strcasecmp(v->name, "rtcachefriends"))
09111          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
09112       else if (!strcasecmp(v->name, "rtignoreregexpire"))
09113          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
09114       else if (!strcasecmp(v->name, "rtupdate"))
09115          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09116       else if (!strcasecmp(v->name, "trunktimestamps"))
09117          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09118       else if (!strcasecmp(v->name, "rtautoclear")) {
09119          int i = atoi(v->value);
09120          if(i > 0)
09121             global_rtautoclear = i;
09122          else
09123             i = 0;
09124          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
09125       } else if (!strcasecmp(v->name, "trunkfreq")) {
09126          trunkfreq = atoi(v->value);
09127          if (trunkfreq < 10)
09128             trunkfreq = 10;
09129       } else if (!strcasecmp(v->name, "autokill")) {
09130          if (sscanf(v->value, "%d", &x) == 1) {
09131             if (x >= 0)
09132                autokill = x;
09133             else
09134                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09135          } else if (ast_true(v->value)) {
09136             autokill = DEFAULT_MAXMS;
09137          } else {
09138             autokill = 0;
09139          }
09140       } else if (!strcasecmp(v->name, "bandwidth")) {
09141          if (!strcasecmp(v->value, "low")) {
09142             capability = IAX_CAPABILITY_LOWBANDWIDTH;
09143          } else if (!strcasecmp(v->value, "medium")) {
09144             capability = IAX_CAPABILITY_MEDBANDWIDTH;
09145          } else if (!strcasecmp(v->value, "high")) {
09146             capability = IAX_CAPABILITY_FULLBANDWIDTH;
09147          } else
09148             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09149       } else if (!strcasecmp(v->name, "allow")) {
09150          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09151       } else if (!strcasecmp(v->name, "disallow")) {
09152          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09153       } else if (!strcasecmp(v->name, "register")) {
09154          iax2_register(v->value, v->lineno);
09155       } else if (!strcasecmp(v->name, "iaxcompat")) {
09156          iaxcompat = ast_true(v->value);
09157       } else if (!strcasecmp(v->name, "regcontext")) {
09158          ast_copy_string(regcontext, v->value, sizeof(regcontext));
09159          /* Create context if it doesn't exist already */
09160          if (!ast_context_find(regcontext))
09161             ast_context_create(NULL, regcontext, "IAX2");
09162       } else if (!strcasecmp(v->name, "tos")) {
09163          if (ast_str2tos(v->value, &tos))
09164             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09165       } else if (!strcasecmp(v->name, "accountcode")) {
09166          ast_copy_string(accountcode, v->value, sizeof(accountcode));
09167       } else if (!strcasecmp(v->name, "mohinterpret")) {
09168          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09169       } else if (!strcasecmp(v->name, "mohsuggest")) {
09170          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09171       } else if (!strcasecmp(v->name, "amaflags")) {
09172          format = ast_cdr_amaflags2int(v->value);
09173          if (format < 0) {
09174             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09175          } else {
09176             amaflags = format;
09177          }
09178       } else if (!strcasecmp(v->name, "language")) {
09179          ast_copy_string(language, v->value, sizeof(language));
09180       } else if (!strcasecmp(v->name, "maxauthreq")) {
09181          maxauthreq = atoi(v->value);
09182          if (maxauthreq < 0)
09183             maxauthreq = 0;
09184       } else if (!strcasecmp(v->name, "adsi")) {
09185          adsi = ast_true(v->value);
09186       } /*else if (strcasecmp(v->name,"type")) */
09187       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09188       v = v->next;
09189    }
09190    
09191    if (defaultsockfd < 0) {
09192       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09193          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09194       } else {
09195          if (option_verbose > 1)
09196             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09197          defaultsockfd = ast_netsock_sockfd(ns);
09198          ast_netsock_unref(ns);
09199       }
09200    }
09201    if (reload) {
09202       ast_netsock_release(outsock);
09203       outsock = ast_netsock_list_alloc();
09204       if (!outsock) {
09205          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09206          return -1;
09207       }
09208       ast_netsock_init(outsock);
09209    }
09210 
09211    if (min_reg_expire > max_reg_expire) {
09212       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09213          min_reg_expire, max_reg_expire, max_reg_expire);
09214       min_reg_expire = max_reg_expire;
09215    }
09216    iax2_capability = capability;
09217    
09218    ucfg = ast_config_load("users.conf");
09219    if (ucfg) {
09220       struct ast_variable *gen;
09221       int genhasiax;
09222       int genregisteriax;
09223       const char *hasiax, *registeriax;
09224       
09225       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09226       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09227       gen = ast_variable_browse(ucfg, "general");
09228       cat = ast_category_browse(ucfg, NULL);
09229       while (cat) {
09230          if (strcasecmp(cat, "general")) {
09231             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09232             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09233             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09234                /* Start with general parameters, then specific parameters, user and peer */
09235                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09236                if (user) {
09237                   AST_LIST_LOCK(&users);
09238                   AST_LIST_INSERT_HEAD(&users, user, entry);
09239                   AST_LIST_UNLOCK(&users);
09240                }
09241                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09242                if (peer) {
09243                   AST_LIST_LOCK(&peers);
09244                   AST_LIST_INSERT_HEAD(&peers, peer, entry);
09245                   AST_LIST_UNLOCK(&peers);
09246                   if (ast_test_flag(peer, IAX_DYNAMIC))
09247                      reg_source_db(peer);
09248                }
09249             }
09250             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09251                char tmp[256];
09252                const char *host = ast_variable_retrieve(ucfg, cat, "host");
09253                const char *username = ast_variable_retrieve(ucfg, cat, "username");
09254                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09255                if (!host)
09256                   host = ast_variable_retrieve(ucfg, "general", "host");
09257                if (!username)
09258                   username = ast_variable_retrieve(ucfg, "general", "username");
09259                if (!secret)
09260                   secret = ast_variable_retrieve(ucfg, "general", "secret");
09261                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09262                   if (!ast_strlen_zero(secret))
09263                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09264                   else
09265                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09266                   iax2_register(tmp, 0);
09267                }
09268             }
09269          }
09270          cat = ast_category_browse(ucfg, cat);
09271       }
09272       ast_config_destroy(ucfg);
09273    }
09274    
09275    cat = ast_category_browse(cfg, NULL);
09276    while(cat) {
09277       if (strcasecmp(cat, "general")) {
09278          utype = ast_variable_retrieve(cfg, cat, "type");
09279          if (utype) {
09280             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09281                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09282                if (user) {
09283                   AST_LIST_LOCK(&users);
09284                   AST_LIST_INSERT_HEAD(&users, user, entry);
09285                   AST_LIST_UNLOCK(&users);
09286                }
09287             }
09288             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09289                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09290                if (peer) {
09291                   AST_LIST_LOCK(&peers);
09292                   AST_LIST_INSERT_HEAD(&peers, peer, entry);
09293                   AST_LIST_UNLOCK(&peers);
09294                   if (ast_test_flag(peer, IAX_DYNAMIC))
09295                      reg_source_db(peer);
09296                }
09297             } else if (strcasecmp(utype, "user")) {
09298                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
09299             }
09300          } else
09301             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
09302       }
09303       cat = ast_category_browse(cfg, cat);
09304    }
09305    ast_config_destroy(cfg);
09306    set_timing();
09307    return capability;
09308 }
09309 
09310 static int reload_config(void)
09311 {
09312    char *config = "iax.conf";
09313    struct iax2_registry *reg;
09314    struct iax2_peer *peer;
09315 
09316    strcpy(accountcode, "");
09317    strcpy(language, "");
09318    strcpy(mohinterpret, "default");
09319    strcpy(mohsuggest, "");
09320    amaflags = 0;
09321    delayreject = 0;
09322    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09323    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09324    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09325    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09326    delete_users();
09327    set_config(config, 1);
09328    prune_peers();
09329    prune_users();
09330    AST_LIST_LOCK(&registrations);
09331    AST_LIST_TRAVERSE(&registrations, reg, entry)
09332       iax2_do_register(reg);
09333    AST_LIST_UNLOCK(&registrations);
09334    /* Qualify hosts, too */
09335    AST_LIST_LOCK(&peers);
09336    AST_LIST_TRAVERSE(&peers, peer, entry)
09337       iax2_poke_peer(peer, 0);
09338    AST_LIST_UNLOCK(&peers);
09339    reload_firmware();
09340    iax_provision_reload();
09341 
09342    return 0;
09343 }
09344 
09345 static int iax2_reload(int fd, int argc, char *argv[])
09346 {
09347    return reload_config();
09348 }
09349 
09350 static int reload(void)
09351 {
09352    return reload_config();
09353 }
09354 
09355 static int cache_get_callno_locked(const char *data)
09356 {
09357    struct sockaddr_in sin;
09358    int x;
09359    int callno;
09360    struct iax_ie_data ied;
09361    struct create_addr_info cai;
09362    struct parsed_dial_string pds;
09363    char *tmpstr;
09364 
09365    for (x=0; x<IAX_MAX_CALLS; x++) {
09366       /* Look for an *exact match* call.  Once a call is negotiated, it can only
09367          look up entries for a single context */
09368       if (!ast_mutex_trylock(&iaxsl[x])) {
09369          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09370             return x;
09371          ast_mutex_unlock(&iaxsl[x]);
09372       }
09373    }
09374 
09375    /* No match found, we need to create a new one */
09376 
09377    memset(&cai, 0, sizeof(cai));
09378    memset(&ied, 0, sizeof(ied));
09379    memset(&pds, 0, sizeof(pds));
09380 
09381    tmpstr = ast_strdupa(data);
09382    parse_dial_string(tmpstr, &pds);
09383 
09384    /* Populate our address from the given */
09385    if (create_addr(pds.peer, &sin, &cai))
09386       return -1;
09387 
09388    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09389       pds.peer, pds.username, pds.password, pds.context);
09390 
09391    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09392    if (callno < 1) {
09393       ast_log(LOG_WARNING, "Unable to create call\n");
09394       return -1;
09395    }
09396 
09397    ast_mutex_lock(&iaxsl[callno]);
09398    ast_string_field_set(iaxs[callno], dproot, data);
09399    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09400 
09401    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09402    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09403    /* the string format is slightly different from a standard dial string,
09404       because the context appears in the 'exten' position
09405    */
09406    if (pds.exten)
09407       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09408    if (pds.username)
09409       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09410    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09411    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09412    /* Keep password handy */
09413    if (pds.password)
09414       ast_string_field_set(iaxs[callno], secret, pds.password);
09415    if (pds.key)
09416       ast_string_field_set(iaxs[callno], outkey, pds.key);
09417    /* Start the call going */
09418    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09419 
09420    return callno;
09421 }
09422 
09423 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
09424 {
09425    struct iax2_dpcache *dp, *prev = NULL, *next;
09426    struct timeval tv;
09427    int x;
09428    int com[2];
09429    int timeout;
09430    int old=0;
09431    int outfd;
09432    int abort;
09433    int callno;
09434    struct ast_channel *c;
09435    struct ast_frame *f;
09436    gettimeofday(&tv, NULL);
09437    dp = dpcache;
09438    while(dp) {
09439       next = dp->next;
09440       /* Expire old caches */
09441       if (ast_tvcmp(tv, dp->expiry) > 0) {
09442             /* It's expired, let it disappear */
09443             if (prev)
09444                prev->next = dp->next;
09445             else
09446                dpcache = dp->next;
09447             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09448                /* Free memory and go again */
09449                free(dp);
09450             } else {
09451                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);
09452             }
09453             dp = next;
09454             continue;
09455       }
09456       /* We found an entry that matches us! */
09457       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
09458          break;
09459       prev = dp;
09460       dp = next;
09461    }
09462    if (!dp) {
09463       /* No matching entry.  Create a new one. */
09464       /* First, can we make a callno? */
09465       callno = cache_get_callno_locked(data);
09466       if (callno < 0) {
09467          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09468          return NULL;
09469       }
09470       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
09471          ast_mutex_unlock(&iaxsl[callno]);
09472          return NULL;
09473       }
09474       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09475       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09476       gettimeofday(&dp->expiry, NULL);
09477       dp->orig = dp->expiry;
09478       /* Expires in 30 mins by default */
09479       dp->expiry.tv_sec += iaxdefaultdpcache;
09480       dp->next = dpcache;
09481       dp->flags = CACHE_FLAG_PENDING;
09482       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09483          dp->waiters[x] = -1;
09484       dpcache = dp;
09485       dp->peer = iaxs[callno]->dpentries;
09486       iaxs[callno]->dpentries = dp;
09487       /* Send the request if we're already up */
09488       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09489          iax2_dprequest(dp, callno);
09490       ast_mutex_unlock(&iaxsl[callno]);
09491    }
09492    /* By here we must have a dp */
09493    if (dp->flags & CACHE_FLAG_PENDING) {
09494       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09495          for a reply to come back so long as it's pending */
09496       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09497          /* Find an empty slot */
09498          if (dp->waiters[x] < 0)
09499             break;
09500       }
09501       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09502          ast_log(LOG_WARNING, "No more waiter positions available\n");
09503          return NULL;
09504       }
09505       if (pipe(com)) {
09506          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09507          return NULL;
09508       }
09509       dp->waiters[x] = com[1];
09510       /* Okay, now we wait */
09511       timeout = iaxdefaulttimeout * 1000;
09512       /* Temporarily unlock */
09513       ast_mutex_unlock(&dpcache_lock);
09514       /* Defer any dtmf */
09515       if (chan)
09516          old = ast_channel_defer_dtmf(chan);
09517       abort = 0;
09518       while(timeout) {
09519          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09520          if (outfd > -1) {
09521             break;
09522          }
09523          if (c) {
09524             f = ast_read(c);
09525             if (f)
09526                ast_frfree(f);
09527             else {
09528                /* Got hung up on, abort! */
09529                break;
09530                abort = 1;
09531             }
09532          }
09533       }
09534       if (!timeout) {
09535          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09536       }
09537       ast_mutex_lock(&dpcache_lock);
09538       dp->waiters[x] = -1;
09539       close(com[1]);
09540       close(com[0]);
09541       if (abort) {
09542          /* Don't interpret anything, just abort.  Not sure what th epoint
09543            of undeferring dtmf on a hung up channel is but hey whatever */
09544          if (!old && chan)
09545             ast_channel_undefer_dtmf(chan);
09546          return NULL;
09547       }
09548       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09549          /* Now to do non-independent analysis the results of our wait */
09550          if (dp->flags & CACHE_FLAG_PENDING) {
09551             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09552                pending.  Don't let it take as long to timeout. */
09553             dp->flags &= ~CACHE_FLAG_PENDING;
09554             dp->flags |= CACHE_FLAG_TIMEOUT;
09555             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09556                systems without leaving it unavailable once the server comes back online */
09557             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09558             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09559                if (dp->waiters[x] > -1)
09560                   write(dp->waiters[x], "asdf", 4);
09561          }
09562       }
09563       /* Our caller will obtain the rest */
09564       if (!old && chan)
09565          ast_channel_undefer_dtmf(chan);
09566    }
09567    return dp;  
09568 }
09569 
09570 /*! \brief Part of the IAX2 switch interface */
09571 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09572 {
09573    struct iax2_dpcache *dp;
09574    int res = 0;
09575 #if 0
09576    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09577 #endif
09578    if ((priority != 1) && (priority != 2))
09579       return 0;
09580    ast_mutex_lock(&dpcache_lock);
09581    dp = find_cache(chan, data, context, exten, priority);
09582    if (dp) {
09583       if (dp->flags & CACHE_FLAG_EXISTS)
09584          res= 1;
09585    }
09586    ast_mutex_unlock(&dpcache_lock);
09587    if (!dp) {
09588       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09589    }
09590    return res;
09591 }
09592 
09593 /*! \brief part of the IAX2 dial plan switch interface */
09594 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09595 {
09596    int res = 0;
09597    struct iax2_dpcache *dp;
09598 #if 0
09599    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09600 #endif
09601    if ((priority != 1) && (priority != 2))
09602       return 0;
09603    ast_mutex_lock(&dpcache_lock);
09604    dp = find_cache(chan, data, context, exten, priority);
09605    if (dp) {
09606       if (dp->flags & CACHE_FLAG_CANEXIST)
09607          res= 1;
09608    }
09609    ast_mutex_unlock(&dpcache_lock);
09610    if (!dp) {
09611       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09612    }
09613    return res;
09614 }
09615 
09616 /*! \brief Part of the IAX2 Switch interface */
09617 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09618 {
09619    int res = 0;
09620    struct iax2_dpcache *dp;
09621 #if 0
09622    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09623 #endif
09624    if ((priority != 1) && (priority != 2))
09625       return 0;
09626    ast_mutex_lock(&dpcache_lock);
09627    dp = find_cache(chan, data, context, exten, priority);
09628    if (dp) {
09629       if (dp->flags & CACHE_FLAG_MATCHMORE)
09630          res= 1;
09631    }
09632    ast_mutex_unlock(&dpcache_lock);
09633    if (!dp) {
09634       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09635    }
09636    return res;
09637 }
09638 
09639 /*! \brief Execute IAX2 dialplan switch */
09640 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09641 {
09642    char odata[256];
09643    char req[256];
09644    char *ncontext;
09645    struct iax2_dpcache *dp;
09646    struct ast_app *dial;
09647 #if 0
09648    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);
09649 #endif
09650    if (priority == 2) {
09651       /* Indicate status, can be overridden in dialplan */
09652       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09653       if (dialstatus) {
09654          dial = pbx_findapp(dialstatus);
09655          if (dial) 
09656             pbx_exec(chan, dial, "");
09657       }
09658       return -1;
09659    } else if (priority != 1)
09660       return -1;
09661    ast_mutex_lock(&dpcache_lock);
09662    dp = find_cache(chan, data, context, exten, priority);
09663    if (dp) {
09664       if (dp->flags & CACHE_FLAG_EXISTS) {
09665          ast_copy_string(odata, data, sizeof(odata));
09666          ncontext = strchr(odata, '/');
09667          if (ncontext) {
09668             *ncontext = '\0';
09669             ncontext++;
09670             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09671          } else {
09672             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09673          }
09674          if (option_verbose > 2)
09675             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09676       } else {
09677          ast_mutex_unlock(&dpcache_lock);
09678          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09679          return -1;
09680       }
09681    }
09682    ast_mutex_unlock(&dpcache_lock);
09683    dial = pbx_findapp("Dial");
09684    if (dial) {
09685       return pbx_exec(chan, dial, req);
09686    } else {
09687       ast_log(LOG_WARNING, "No dial application registered\n");
09688    }
09689    return -1;
09690 }
09691 
09692 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
09693 {
09694    struct iax2_peer *peer;
09695    char *peername, *colname;
09696 
09697    peername = ast_strdupa(data);
09698 
09699    /* if our channel, return the IP address of the endpoint of current channel */
09700    if (!strcmp(peername,"CURRENTCHANNEL")) {
09701            unsigned short callno;
09702       if (chan->tech != &iax2_tech)
09703          return -1;
09704       callno = PTR_TO_CALLNO(chan->tech_pvt);   
09705       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
09706       return 0;
09707    }
09708 
09709    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
09710       *colname++ = '\0';
09711    else if ((colname = strchr(peername, '|')))
09712       *colname++ = '\0';
09713    else
09714       colname = "ip";
09715 
09716    if (!(peer = find_peer(peername, 1)))
09717       return -1;
09718 
09719    if (!strcasecmp(colname, "ip")) {
09720       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
09721    } else  if (!strcasecmp(colname, "status")) {
09722       peer_status(peer, buf, len); 
09723    } else  if (!strcasecmp(colname, "mailbox")) {
09724       ast_copy_string(buf, peer->mailbox, len);
09725    } else  if (!strcasecmp(colname, "context")) {
09726       ast_copy_string(buf, peer->context, len);
09727    } else  if (!strcasecmp(colname, "expire")) {
09728       snprintf(buf, len, "%d", peer->expire);
09729    } else  if (!strcasecmp(colname, "dynamic")) {
09730       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09731    } else  if (!strcasecmp(colname, "callerid_name")) {
09732       ast_copy_string(buf, peer->cid_name, len);
09733    } else  if (!strcasecmp(colname, "callerid_num")) {
09734       ast_copy_string(buf, peer->cid_num, len);
09735    } else  if (!strcasecmp(colname, "codecs")) {
09736       ast_getformatname_multiple(buf, len -1, peer->capability);
09737    } else  if (!strncasecmp(colname, "codec[", 6)) {
09738       char *codecnum, *ptr;
09739       int index = 0, codec = 0;
09740       
09741       codecnum = strchr(colname, '[');
09742       *codecnum = '\0';
09743       codecnum++;
09744       if ((ptr = strchr(codecnum, ']'))) {
09745          *ptr = '\0';
09746       }
09747       index = atoi(codecnum);
09748       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09749          ast_copy_string(buf, ast_getformatname(codec), len);
09750       }
09751    }
09752 
09753    return 0;
09754 }
09755 
09756 struct ast_custom_function iaxpeer_function = {
09757    .name = "IAXPEER",
09758    .synopsis = "Gets IAX peer information",
09759    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
09760    .read = function_iaxpeer,
09761    .desc = "If peername specified, valid items are:\n"
09762    "- ip (default)          The IP address.\n"
09763    "- status                The peer's status (if qualify=yes)\n"
09764    "- mailbox               The configured mailbox.\n"
09765    "- context               The configured context.\n"
09766    "- expire                The epoch time of the next expire.\n"
09767    "- dynamic               Is it dynamic? (yes/no).\n"
09768    "- callerid_name         The configured Caller ID name.\n"
09769    "- callerid_num          The configured Caller ID number.\n"
09770    "- codecs                The configured codecs.\n"
09771    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
09772    "\n"
09773    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
09774    "\n"
09775 };
09776 
09777 
09778 /*! \brief Part of the device state notification system ---*/
09779 static int iax2_devicestate(void *data) 
09780 {
09781    struct parsed_dial_string pds;
09782    char *tmp = ast_strdupa(data);
09783    struct iax2_peer *p;
09784    int res = AST_DEVICE_INVALID;
09785 
09786    memset(&pds, 0, sizeof(pds));
09787    parse_dial_string(tmp, &pds);
09788    if (ast_strlen_zero(pds.peer))
09789       return res;
09790    
09791    if (option_debug > 2)
09792       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09793 
09794    /* SLD: FIXME: second call to find_peer during registration */
09795    if (!(p = find_peer(pds.peer, 1)))
09796       return res;
09797 
09798    res = AST_DEVICE_UNAVAILABLE;
09799    if (option_debug > 2) 
09800       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09801          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09802    
09803    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09804        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09805       /* Peer is registered, or have default IP address
09806          and a valid registration */
09807       if (p->historicms == 0 || p->historicms <= p->maxms)
09808          /* let the core figure out whether it is in use or not */
09809          res = AST_DEVICE_UNKNOWN;  
09810    }
09811 
09812    if (ast_test_flag(p, IAX_TEMPONLY))
09813       destroy_peer(p);
09814 
09815    return res;
09816 }
09817 
09818 static struct ast_switch iax2_switch = 
09819 {
09820    name:          "IAX2",
09821    description:      "IAX Remote Dialplan Switch",
09822    exists:        iax2_exists,
09823    canmatch:      iax2_canmatch,
09824    exec:       iax2_exec,
09825    matchmore:     iax2_matchmore,
09826 };
09827 
09828 static char show_stats_usage[] =
09829 "Usage: iax2 show stats\n"
09830 "       Display statistics on IAX channel driver.\n";
09831 
09832 static char show_cache_usage[] =
09833 "Usage: iax2 show cache\n"
09834 "       Display currently cached IAX Dialplan results.\n";
09835 
09836 static char show_peer_usage[] =
09837 "Usage: iax2 show peer <name>\n"
09838 "       Display details on specific IAX peer\n";
09839 
09840 static char prune_realtime_usage[] =
09841 "Usage: iax2 prune realtime [<peername>|all]\n"
09842 "       Prunes object(s) from the cache\n";
09843 
09844 static char iax2_reload_usage[] =
09845 "Usage: iax2 reload\n"
09846 "       Reloads IAX configuration from iax.conf\n";
09847 
09848 static char show_prov_usage[] =
09849 "Usage: iax2 provision <host> <template> [forced]\n"
09850 "       Provisions the given peer or IP address using a template\n"
09851 "       matching either 'template' or '*' if the template is not\n"
09852 "       found.  If 'forced' is specified, even empty provisioning\n"
09853 "       fields will be provisioned as empty fields.\n";
09854 
09855 static char show_users_usage[] = 
09856 "Usage: iax2 show users [like <pattern>]\n"
09857 "       Lists all known IAX2 users.\n"
09858 "       Optional regular expression pattern is used to filter the user list.\n";
09859 
09860 static char show_channels_usage[] = 
09861 "Usage: iax2 show channels\n"
09862 "       Lists all currently active IAX channels.\n";
09863 
09864 static char show_netstats_usage[] = 
09865 "Usage: iax2 show netstats\n"
09866 "       Lists network status for all currently active IAX channels.\n";
09867 
09868 static char show_threads_usage[] = 
09869 "Usage: iax2 show threads\n"
09870 "       Lists status of IAX helper threads\n";
09871 
09872 static char show_peers_usage[] = 
09873 "Usage: iax2 show peers [registered] [like <pattern>]\n"
09874 "       Lists all known IAX2 peers.\n"
09875 "       Optional 'registered' argument lists only peers with known addresses.\n"
09876 "       Optional regular expression pattern is used to filter the peer list.\n";
09877 
09878 static char show_firmware_usage[] = 
09879 "Usage: iax2 show firmware\n"
09880 "       Lists all known IAX firmware images.\n";
09881 
09882 static char show_reg_usage[] =
09883 "Usage: iax2 show registry\n"
09884 "       Lists all registration requests and status.\n";
09885 
09886 static char debug_usage[] = 
09887 "Usage: iax2 set debug\n"
09888 "       Enables dumping of IAX packets for debugging purposes\n";
09889 
09890 static char no_debug_usage[] = 
09891 "Usage: iax2 set debug off\n"
09892 "       Disables dumping of IAX packets for debugging purposes\n";
09893 
09894 static char debug_trunk_usage[] =
09895 "Usage: iax2 set debug trunk\n"
09896 "       Requests current status of IAX trunking\n";
09897 
09898 static char no_debug_trunk_usage[] =
09899 "Usage: iax2 set debug trunk off\n"
09900 "       Requests current status of IAX trunking\n";
09901 
09902 static char debug_jb_usage[] =
09903 "Usage: iax2 set debug jb\n"
09904 "       Enables jitterbuffer debugging information\n";
09905 
09906 static char no_debug_jb_usage[] =
09907 "Usage: iax2 set debug jb off\n"
09908 "       Disables jitterbuffer debugging information\n";
09909 
09910 static char iax2_test_losspct_usage[] =
09911 "Usage: iax2 test losspct <percentage>\n"
09912 "       For testing, throws away <percentage> percent of incoming packets\n";
09913 
09914 #ifdef IAXTESTS
09915 static char iax2_test_late_usage[] =
09916 "Usage: iax2 test late <ms>\n"
09917 "       For testing, count the next frame as <ms> ms late\n";
09918 
09919 static char iax2_test_resync_usage[] =
09920 "Usage: iax2 test resync <ms>\n"
09921 "       For testing, adjust all future frames by <ms> ms\n";
09922 
09923 static char iax2_test_jitter_usage[] =
09924 "Usage: iax2 test jitter <ms> <pct>\n"
09925 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
09926 #endif /* IAXTESTS */
09927 
09928 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
09929    { "iax2", "trunk", "debug", NULL },
09930    iax2_do_trunk_debug, NULL,
09931    NULL };
09932 
09933 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
09934    { "iax2", "jb", "debug", NULL },
09935    iax2_do_jb_debug, NULL,
09936    NULL };
09937 
09938 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
09939    { "iax2", "no", "debug", NULL },
09940    iax2_no_debug, NULL,
09941    NULL };
09942 
09943 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
09944    { "iax2", "no", "trunk", "debug", NULL },
09945    iax2_no_trunk_debug, NULL,
09946    NULL };
09947 
09948 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
09949    { "iax2", "no", "jb", "debug", NULL },
09950    iax2_no_jb_debug, NULL,
09951    NULL };
09952 
09953 static struct ast_cli_entry cli_iax2[] = {
09954    { { "iax2", "show", "cache", NULL },
09955    iax2_show_cache, "Display IAX cached dialplan",
09956    show_cache_usage, NULL, },
09957 
09958    { { "iax2", "show", "channels", NULL },
09959    iax2_show_channels, "List active IAX channels",
09960    show_channels_usage, NULL, },
09961 
09962    { { "iax2", "show", "firmware", NULL },
09963    iax2_show_firmware, "List available IAX firmwares",
09964    show_firmware_usage, NULL, },
09965 
09966    { { "iax2", "show", "netstats", NULL },
09967    iax2_show_netstats, "List active IAX channel netstats",
09968    show_netstats_usage, NULL, },
09969 
09970    { { "iax2", "show", "peers", NULL },
09971    iax2_show_peers, "List defined IAX peers",
09972    show_peers_usage, NULL, },
09973 
09974    { { "iax2", "show", "registry", NULL },
09975    iax2_show_registry, "Display IAX registration status",
09976    show_reg_usage, NULL, },
09977 
09978    { { "iax2", "show", "stats", NULL },
09979    iax2_show_stats, "Display IAX statistics",
09980    show_stats_usage, NULL, },
09981 
09982    { { "iax2", "show", "threads", NULL },
09983    iax2_show_threads, "Display IAX helper thread info",
09984    show_threads_usage, NULL, },
09985 
09986    { { "iax2", "show", "users", NULL },
09987    iax2_show_users, "List defined IAX users",
09988    show_users_usage, NULL, },
09989 
09990    { { "iax2", "prune", "realtime", NULL },
09991    iax2_prune_realtime, "Prune a cached realtime lookup",
09992    prune_realtime_usage, complete_iax2_show_peer },
09993 
09994    { { "iax2", "reload", NULL },
09995    iax2_reload, "Reload IAX configuration",
09996    iax2_reload_usage },
09997 
09998    { { "iax2", "show", "peer", NULL },
09999    iax2_show_peer, "Show details on specific IAX peer",
10000    show_peer_usage, complete_iax2_show_peer },
10001 
10002    { { "iax2", "set", "debug", NULL },
10003    iax2_do_debug, "Enable IAX debugging",
10004    debug_usage },
10005 
10006    { { "iax2", "set", "debug", "trunk", NULL },
10007    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10008    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10009 
10010    { { "iax2", "set", "debug", "jb", NULL },
10011    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10012    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10013 
10014    { { "iax2", "set", "debug", "off", NULL },
10015    iax2_no_debug, "Disable IAX debugging",
10016    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10017 
10018    { { "iax2", "set", "debug", "trunk", "off", NULL },
10019    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10020    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10021 
10022    { { "iax2", "set", "debug", "jb", "off", NULL },
10023    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10024    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10025 
10026    { { "iax2", "test", "losspct", NULL },
10027    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10028    iax2_test_losspct_usage },
10029 
10030    { { "iax2", "provision", NULL },
10031    iax2_prov_cmd, "Provision an IAX device",
10032    show_prov_usage, iax2_prov_complete_template_3rd },
10033 
10034 #ifdef IAXTESTS
10035    { { "iax2", "test", "late", NULL },
10036    iax2_test_late, "Test the receipt of a late frame",
10037    iax2_test_late_usage },
10038 
10039    { { "iax2", "test", "resync", NULL },
10040    iax2_test_resync, "Test a resync in received timestamps",
10041    iax2_test_resync_usage },
10042 
10043    { { "iax2", "test", "jitter", NULL },
10044    iax2_test_jitter, "Simulates jitter for testing",
10045    iax2_test_jitter_usage },
10046 #endif /* IAXTESTS */
10047 };
10048 
10049 static int __unload_module(void)
10050 {
10051    struct iax2_thread *thread = NULL;
10052    int x;
10053 
10054    /* Make sure threads do not hold shared resources when they are canceled */
10055    
10056    /* Grab the sched lock resource to keep it away from threads about to die */
10057    /* Cancel the network thread, close the net socket */
10058    if (netthreadid != AST_PTHREADT_NULL) {
10059       AST_LIST_LOCK(&iaxq.queue);
10060       ast_mutex_lock(&sched_lock);
10061       pthread_cancel(netthreadid);
10062       ast_cond_signal(&sched_cond);
10063       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10064       AST_LIST_UNLOCK(&iaxq.queue);
10065       pthread_join(netthreadid, NULL);
10066    }
10067    if (schedthreadid != AST_PTHREADT_NULL) {
10068       ast_mutex_lock(&sched_lock);  
10069       pthread_cancel(schedthreadid);
10070       ast_cond_signal(&sched_cond);
10071       ast_mutex_unlock(&sched_lock);   
10072       pthread_join(schedthreadid, NULL);
10073    }
10074    
10075    /* Call for all threads to halt */
10076    AST_LIST_LOCK(&idle_list);
10077    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10078       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10079       pthread_cancel(thread->threadid);
10080    }
10081    AST_LIST_TRAVERSE_SAFE_END
10082    AST_LIST_UNLOCK(&idle_list);
10083 
10084    AST_LIST_LOCK(&active_list);
10085    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10086       AST_LIST_REMOVE_CURRENT(&active_list, list);
10087       pthread_cancel(thread->threadid);
10088    }
10089    AST_LIST_TRAVERSE_SAFE_END
10090    AST_LIST_UNLOCK(&active_list);
10091 
10092    AST_LIST_LOCK(&dynamic_list);
10093         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10094       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10095       pthread_cancel(thread->threadid);
10096         }
10097    AST_LIST_TRAVERSE_SAFE_END
10098         AST_LIST_UNLOCK(&dynamic_list);
10099 
10100    AST_LIST_HEAD_DESTROY(&iaxq.queue);
10101 
10102    /* Wait for threads to exit */
10103    while(0 < iaxactivethreadcount)
10104       usleep(10000);
10105    
10106    ast_netsock_release(netsock);
10107    ast_netsock_release(outsock);
10108    for (x=0;x<IAX_MAX_CALLS;x++)
10109       if (iaxs[x])
10110          iax2_destroy(x);
10111    ast_manager_unregister( "IAXpeers" );
10112    ast_manager_unregister( "IAXnetstats" );
10113    ast_unregister_application(papp);
10114    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10115    ast_unregister_switch(&iax2_switch);
10116    ast_channel_unregister(&iax2_tech);
10117    delete_users();
10118    iax_provision_unload();
10119    sched_context_destroy(sched);
10120 
10121    ast_mutex_destroy(&waresl.lock);
10122 
10123    for (x = 0; x < IAX_MAX_CALLS; x++)
10124       ast_mutex_destroy(&iaxsl[x]);
10125 
10126    return 0;
10127 }
10128 
10129 static int unload_module(void)
10130 {
10131    ast_custom_function_unregister(&iaxpeer_function);
10132    ast_custom_function_unregister(&iaxvar_function);
10133    return __unload_module();
10134 }
10135 
10136 
10137 /*! \brief Load IAX2 module, load configuraiton ---*/
10138 static int load_module(void)
10139 {
10140    char *config = "iax.conf";
10141    int res = 0;
10142    int x;
10143    struct iax2_registry *reg = NULL;
10144    struct iax2_peer *peer = NULL;
10145    
10146    ast_custom_function_register(&iaxpeer_function);
10147    ast_custom_function_register(&iaxvar_function);
10148 
10149    iax_set_output(iax_debug_output);
10150    iax_set_error(iax_error_output);
10151    jb_setoutput(jb_error_output, jb_warning_output, NULL);
10152    
10153 #ifdef HAVE_ZAPTEL
10154 #ifdef ZT_TIMERACK
10155    timingfd = open("/dev/zap/timer", O_RDWR);
10156    if (timingfd < 0)
10157 #endif
10158       timingfd = open("/dev/zap/pseudo", O_RDWR);
10159    if (timingfd < 0) 
10160       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10161 #endif      
10162 
10163    memset(iaxs, 0, sizeof(iaxs));
10164 
10165    for (x=0;x<IAX_MAX_CALLS;x++)
10166       ast_mutex_init(&iaxsl[x]);
10167    
10168    ast_cond_init(&sched_cond, NULL);
10169 
10170    io = io_context_create();
10171    sched = sched_context_create();
10172    
10173    if (!io || !sched) {
10174       ast_log(LOG_ERROR, "Out of memory\n");
10175       return -1;
10176    }
10177 
10178    netsock = ast_netsock_list_alloc();
10179    if (!netsock) {
10180       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10181       return -1;
10182    }
10183    ast_netsock_init(netsock);
10184 
10185    outsock = ast_netsock_list_alloc();
10186    if (!outsock) {
10187       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10188       return -1;
10189    }
10190    ast_netsock_init(outsock);
10191 
10192    ast_mutex_init(&waresl.lock);
10193 
10194    AST_LIST_HEAD_INIT(&iaxq.queue);
10195    
10196    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10197 
10198    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10199    
10200    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10201    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10202 
10203    if(set_config(config, 0) == -1)
10204       return AST_MODULE_LOAD_DECLINE;
10205 
10206    if (ast_channel_register(&iax2_tech)) {
10207       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10208       __unload_module();
10209       return -1;
10210    }
10211 
10212    if (ast_register_switch(&iax2_switch)) 
10213       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10214 
10215    res = start_network_thread();
10216    if (!res) {
10217       if (option_verbose > 1) 
10218          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10219    } else {
10220       ast_log(LOG_ERROR, "Unable to start network thread\n");
10221       ast_netsock_release(netsock);
10222       ast_netsock_release(outsock);
10223    }
10224 
10225    AST_LIST_LOCK(&registrations);
10226    AST_LIST_TRAVERSE(&registrations, reg, entry)
10227       iax2_do_register(reg);
10228    AST_LIST_UNLOCK(&registrations); 
10229 
10230    AST_LIST_LOCK(&peers);
10231    AST_LIST_TRAVERSE(&peers, peer, entry) {
10232       if (peer->sockfd < 0)
10233          peer->sockfd = defaultsockfd;
10234       iax2_poke_peer(peer, 0);
10235    }
10236    AST_LIST_UNLOCK(&peers);
10237    reload_firmware();
10238    iax_provision_reload();
10239    return res;
10240 }
10241 
10242 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10243       .load = load_module,
10244       .unload = unload_module,
10245       .reload = reload,
10246           );

Generated on Mon Apr 30 07:36:31 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1