Sat Nov 25 00:45:32 2006

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

Generated on Sat Nov 25 00:45:32 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6