Fri Sep 29 11:12:25 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: 42086 $")
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_DATA_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 
02604 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02605 {
02606    struct ast_variable *var;
02607    struct ast_variable *tmp;
02608    struct iax2_peer *peer=NULL;
02609    time_t regseconds, nowtime;
02610    int dynamic=0;
02611 
02612    if (peername)
02613       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02614    else {
02615       char iabuf[INET_ADDRSTRLEN];
02616       char porta[25];
02617       ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
02618       sprintf(porta, "%d", ntohs(sin->sin_port));
02619       var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL);
02620       if (var) {
02621          /* We'll need the peer name in order to build the structure! */
02622          tmp = var;
02623          while(tmp) {
02624             if (!strcasecmp(tmp->name, "name"))
02625                peername = tmp->value;
02626             tmp = tmp->next;
02627          }
02628       }
02629    }
02630    if (!var)
02631       return NULL;
02632 
02633    peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02634    
02635    if (!peer)
02636       return NULL;
02637 
02638    tmp = var;
02639    while(tmp) {
02640       /* Make sure it's not a user only... */
02641       if (!strcasecmp(tmp->name, "type")) {
02642          if (strcasecmp(tmp->value, "friend") &&
02643              strcasecmp(tmp->value, "peer")) {
02644             /* Whoops, we weren't supposed to exist! */
02645             destroy_peer(peer);
02646             peer = NULL;
02647             break;
02648          } 
02649       } else if (!strcasecmp(tmp->name, "regseconds")) {
02650          if (sscanf(tmp->value, "%ld", (time_t *)&regseconds) != 1)
02651             regseconds = 0;
02652       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02653          inet_aton(tmp->value, &(peer->addr.sin_addr));
02654       } else if (!strcasecmp(tmp->name, "port")) {
02655          peer->addr.sin_port = htons(atoi(tmp->value));
02656       } else if (!strcasecmp(tmp->name, "host")) {
02657          if (!strcasecmp(tmp->value, "dynamic"))
02658             dynamic = 1;
02659       }
02660       tmp = tmp->next;
02661    }
02662    if (!peer)
02663       return NULL;
02664 
02665    ast_variables_destroy(var);
02666 
02667    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02668       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02669       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02670          if (peer->expire > -1)
02671             ast_sched_del(sched, peer->expire);
02672          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer);
02673       }
02674       ast_mutex_lock(&peerl.lock);
02675       peer->next = peerl.peers;
02676       peerl.peers = peer;
02677       ast_mutex_unlock(&peerl.lock);
02678       if (ast_test_flag(peer, IAX_DYNAMIC))
02679          reg_source_db(peer);
02680    } else {
02681       ast_set_flag(peer, IAX_TEMPONLY);   
02682    }
02683 
02684    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02685       time(&nowtime);
02686       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02687          memset(&peer->addr, 0, sizeof(peer->addr));
02688          if (option_debug)
02689             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02690                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02691       }
02692       else {
02693          if (option_debug)
02694             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02695                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02696       }
02697    }
02698 
02699    return peer;
02700 }
02701 
02702 static struct iax2_user *realtime_user(const char *username)
02703 {
02704    struct ast_variable *var;
02705    struct ast_variable *tmp;
02706    struct iax2_user *user=NULL;
02707 
02708    var = ast_load_realtime("iaxusers", "name", username, NULL);
02709    if (!var)
02710       return NULL;
02711 
02712    tmp = var;
02713    while(tmp) {
02714       /* Make sure it's not a peer only... */
02715       if (!strcasecmp(tmp->name, "type")) {
02716          if (strcasecmp(tmp->value, "friend") &&
02717              strcasecmp(tmp->value, "user")) {
02718             return NULL;
02719          } 
02720       }
02721       tmp = tmp->next;
02722    }
02723 
02724    user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02725    if (!user)
02726       return NULL;
02727 
02728    ast_variables_destroy(var);
02729 
02730    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02731       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02732       ast_mutex_lock(&userl.lock);
02733       user->next = userl.users;
02734       userl.users = user;
02735       ast_mutex_unlock(&userl.lock);
02736    } else {
02737       ast_set_flag(user, IAX_TEMPONLY);   
02738    }
02739 
02740    return user;
02741 }
02742 
02743 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02744 {
02745         char port[10];
02746         char ipaddr[20];
02747         char regseconds[20];
02748    
02749         snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02750         ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
02751         snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02752         ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL);
02753 }
02754 
02755 struct create_addr_info {
02756    int capability;
02757    unsigned int flags;
02758    int maxtime;
02759    int encmethods;
02760    int found;
02761    int sockfd;
02762    char username[80];
02763    char secret[80];
02764    char outkey[80];
02765    char timezone[80];
02766    char prefs[32];
02767    char context[AST_MAX_CONTEXT];
02768    char peercontext[AST_MAX_CONTEXT];
02769 };
02770 
02771 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02772 {
02773    struct ast_hostent ahp;
02774    struct hostent *hp;
02775    struct iax2_peer *peer;
02776 
02777    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02778    cai->sockfd = defaultsockfd;
02779    cai->maxtime = 0;
02780    sin->sin_family = AF_INET;
02781 
02782    if (!(peer = find_peer(peername, 1))) {
02783       cai->found = 0;
02784 
02785       hp = ast_gethostbyname(peername, &ahp);
02786       if (hp) {
02787          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02788          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02789          /* use global iax prefs for unknown peer/user */
02790          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02791          return 0;
02792       } else {
02793          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02794          return -1;
02795       }
02796    }
02797 
02798    cai->found = 1;
02799    
02800    /* if the peer has no address (current or default), return failure */
02801    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02802       if (ast_test_flag(peer, IAX_TEMPONLY))
02803          destroy_peer(peer);
02804       return -1;
02805    }
02806 
02807    /* if the peer is being monitored and is currently unreachable, return failure */
02808    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02809       if (ast_test_flag(peer, IAX_TEMPONLY))
02810          destroy_peer(peer);
02811       return -1;
02812    }
02813 
02814    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02815    cai->maxtime = peer->maxms;
02816    cai->capability = peer->capability;
02817    cai->encmethods = peer->encmethods;
02818    cai->sockfd = peer->sockfd;
02819    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02820    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02821    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02822    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02823    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02824    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02825    if (ast_strlen_zero(peer->dbsecret)) {
02826       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02827    } else {
02828       char *family;
02829       char *key = NULL;
02830 
02831       family = ast_strdupa(peer->dbsecret);
02832       if (family) {
02833          key = strchr(family, '/');
02834          if (key)
02835             *key++ = '\0';
02836       }
02837       if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02838          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02839          if (ast_test_flag(peer, IAX_TEMPONLY))
02840             destroy_peer(peer);
02841          return -1;
02842       }
02843    }
02844 
02845    if (peer->addr.sin_addr.s_addr) {
02846       sin->sin_addr = peer->addr.sin_addr;
02847       sin->sin_port = peer->addr.sin_port;
02848    } else {
02849       sin->sin_addr = peer->defaddr.sin_addr;
02850       sin->sin_port = peer->defaddr.sin_port;
02851    }
02852 
02853    if (ast_test_flag(peer, IAX_TEMPONLY))
02854       destroy_peer(peer);
02855 
02856    return 0;
02857 }
02858 
02859 static int auto_congest(void *nothing)
02860 {
02861    int callno = PTR_TO_CALLNO(nothing);
02862    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02863    ast_mutex_lock(&iaxsl[callno]);
02864    if (iaxs[callno]) {
02865       iaxs[callno]->initid = -1;
02866       iax2_queue_frame(callno, &f);
02867       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02868    }
02869    ast_mutex_unlock(&iaxsl[callno]);
02870    return 0;
02871 }
02872 
02873 static unsigned int iax2_datetime(char *tz)
02874 {
02875    time_t t;
02876    struct tm tm;
02877    unsigned int tmp;
02878    time(&t);
02879    localtime_r(&t, &tm);
02880    if (!ast_strlen_zero(tz))
02881       ast_localtime(&t, &tm, tz);
02882    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02883    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02884    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02885    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02886    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02887    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02888    return tmp;
02889 }
02890 
02891 struct parsed_dial_string {
02892    char *username;
02893    char *password;
02894    char *key;
02895    char *peer;
02896    char *port;
02897    char *exten;
02898    char *context;
02899    char *options;
02900 };
02901 
02902 /*!
02903  * \brief Parses an IAX dial string into its component parts.
02904  * \param data the string to be parsed
02905  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
02906  * \return nothing
02907  *
02908  * This function parses the string and fills the structure
02909  * with pointers to its component parts. The input string
02910  * will be modified.
02911  *
02912  * \note This function supports both plaintext passwords and RSA
02913  * key names; if the password string is formatted as '[keyname]',
02914  * then the keyname will be placed into the key field, and the
02915  * password field will be set to NULL.
02916  *
02917  * \note The dial string format is:
02918  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
02919  */
02920 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
02921 {
02922    if (ast_strlen_zero(data))
02923       return;
02924 
02925    pds->peer = strsep(&data, "/");
02926    pds->exten = strsep(&data, "/");
02927    pds->options = data;
02928 
02929    if (pds->exten) {
02930       data = pds->exten;
02931       pds->exten = strsep(&data, "@");
02932       pds->context = data;
02933    }
02934 
02935    if (strchr(pds->peer, '@')) {
02936       data = pds->peer;
02937       pds->username = strsep(&data, "@");
02938       pds->peer = data;
02939    }
02940 
02941    if (pds->username) {
02942       data = pds->username;
02943       pds->username = strsep(&data, ":");
02944       pds->password = data;
02945    }
02946 
02947    data = pds->peer;
02948    pds->peer = strsep(&data, ":");
02949    pds->port = data;
02950 
02951    /* check for a key name wrapped in [] in the secret position, if found,
02952       move it to the key field instead
02953    */
02954    if (pds->password && (pds->password[0] == '[')) {
02955       pds->key = ast_strip_quoted(pds->password, "[", "]");
02956       pds->password = NULL;
02957    }
02958 }
02959 
02960 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
02961 {
02962    struct sockaddr_in sin;
02963    char *l=NULL, *n=NULL, *tmpstr;
02964    struct iax_ie_data ied;
02965    char *defaultrdest = "s";
02966    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02967    struct parsed_dial_string pds;
02968    struct create_addr_info cai;
02969 
02970    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
02971       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
02972       return -1;
02973    }
02974 
02975    memset(&cai, 0, sizeof(cai));
02976    cai.encmethods = iax2_encryption;
02977 
02978    memset(&pds, 0, sizeof(pds));
02979    tmpstr = ast_strdupa(dest);
02980    parse_dial_string(tmpstr, &pds);
02981 
02982    if (!pds.exten)
02983       pds.exten = defaultrdest;
02984 
02985    if (create_addr(pds.peer, &sin, &cai)) {
02986       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
02987       return -1;
02988    }
02989 
02990    if (!pds.username && !ast_strlen_zero(cai.username))
02991       pds.username = cai.username;
02992    if (!pds.password && !ast_strlen_zero(cai.secret))
02993       pds.password = cai.secret;
02994    if (!pds.key && !ast_strlen_zero(cai.outkey))
02995       pds.key = cai.outkey;
02996    if (!pds.context && !ast_strlen_zero(cai.peercontext))
02997       pds.context = cai.peercontext;
02998 
02999    /* Keep track of the context for outgoing calls too */
03000    ast_copy_string(c->context, cai.context, sizeof(c->context));
03001 
03002    if (pds.port)
03003       sin.sin_port = htons(atoi(pds.port));
03004 
03005    l = c->cid.cid_num;
03006    n = c->cid.cid_name;
03007 
03008    /* Now build request */ 
03009    memset(&ied, 0, sizeof(ied));
03010 
03011    /* On new call, first IE MUST be IAX version of caller */
03012    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03013    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03014    if (pds.options && strchr(pds.options, 'a')) {
03015       /* Request auto answer */
03016       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03017    }
03018 
03019    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03020 
03021    if (l) {
03022       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03023       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03024    } else {
03025       if (n)
03026          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03027       else
03028          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03029    }
03030 
03031    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03032    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03033 
03034    if (n)
03035       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03036    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03037       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03038 
03039    if (!ast_strlen_zero(c->language))
03040       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03041    if (!ast_strlen_zero(c->cid.cid_dnid))
03042       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03043 
03044    if (pds.context)
03045       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03046 
03047    if (pds.username)
03048       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03049 
03050    if (cai.encmethods)
03051       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03052 
03053    ast_mutex_lock(&iaxsl[callno]);
03054 
03055    if (!ast_strlen_zero(c->context))
03056       ast_copy_string(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context));
03057 
03058    if (pds.username)
03059       ast_copy_string(iaxs[callno]->username, pds.username, sizeof(iaxs[callno]->username));
03060 
03061    iaxs[callno]->encmethods = cai.encmethods;
03062 
03063    if (pds.key)
03064       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
03065    if (pds.password)
03066       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
03067 
03068    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03069    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03070    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03071    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03072 
03073    if (iaxs[callno]->maxtime) {
03074       /* Initialize pingtime and auto-congest time */
03075       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03076       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03077    } else if (autokill) {
03078       iaxs[callno]->pingtime = autokill / 2;
03079       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03080    }
03081 
03082    /* Transmit the string in a "NEW" request */
03083    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03084 
03085    ast_mutex_unlock(&iaxsl[callno]);
03086    ast_setstate(c, AST_STATE_RINGING);
03087    
03088    return 0;
03089 }
03090 
03091 static int iax2_hangup(struct ast_channel *c) 
03092 {
03093    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03094    int alreadygone;
03095    struct iax_ie_data ied;
03096    memset(&ied, 0, sizeof(ied));
03097    ast_mutex_lock(&iaxsl[callno]);
03098    if (callno && iaxs[callno]) {
03099       ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03100       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03101       /* Send the hangup unless we have had a transmission error or are already gone */
03102       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03103       if (!iaxs[callno]->error && !alreadygone) 
03104          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03105       /* Explicitly predestroy it */
03106       iax2_predestroy_nolock(callno);
03107       /* If we were already gone to begin with, destroy us now */
03108       if (alreadygone) {
03109          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03110          iax2_destroy_nolock(callno);
03111       }
03112    }
03113    ast_mutex_unlock(&iaxsl[callno]);
03114    if (option_verbose > 2) 
03115       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03116    return 0;
03117 }
03118 
03119 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03120 {
03121    struct ast_option_header *h;
03122    int res;
03123 
03124    switch (option) {
03125    case AST_OPTION_TXGAIN:
03126    case AST_OPTION_RXGAIN:
03127       /* these two cannot be sent, because they require a result */
03128       errno = ENOSYS;
03129       return -1;
03130    default:
03131       h = malloc(datalen + sizeof(*h));
03132       if (h) {
03133          h->flag = AST_OPTION_FLAG_REQUEST;
03134          h->option = htons(option);
03135          memcpy(h->data, data, datalen);
03136          res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03137                     AST_CONTROL_OPTION, 0, (unsigned char *) h,
03138                     datalen + sizeof(*h), -1);
03139          free(h);
03140          return res;
03141       } else {
03142          ast_log(LOG_WARNING, "Out of memory\n");
03143          return -1;
03144       }
03145    }
03146 }
03147 
03148 static struct ast_frame *iax2_read(struct ast_channel *c) 
03149 {
03150    static struct ast_frame f = { AST_FRAME_NULL, };
03151    ast_log(LOG_NOTICE, "I should never be called!\n");
03152    return &f;
03153 }
03154 
03155 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1)
03156 {
03157    int res;
03158    struct iax_ie_data ied0;
03159    struct iax_ie_data ied1;
03160    unsigned int transferid = rand();
03161    memset(&ied0, 0, sizeof(ied0));
03162    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03163    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03164    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03165 
03166    memset(&ied1, 0, sizeof(ied1));
03167    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03168    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03169    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03170    
03171    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03172    if (res)
03173       return -1;
03174    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03175    if (res)
03176       return -1;
03177    iaxs[callno0]->transferring = TRANSFER_BEGIN;
03178    iaxs[callno1]->transferring = TRANSFER_BEGIN;
03179    return 0;
03180 }
03181 
03182 static void lock_both(unsigned short callno0, unsigned short callno1)
03183 {
03184    ast_mutex_lock(&iaxsl[callno0]);
03185    while (ast_mutex_trylock(&iaxsl[callno1])) {
03186       ast_mutex_unlock(&iaxsl[callno0]);
03187       usleep(10);
03188       ast_mutex_lock(&iaxsl[callno0]);
03189    }
03190 }
03191 
03192 static void unlock_both(unsigned short callno0, unsigned short callno1)
03193 {
03194    ast_mutex_unlock(&iaxsl[callno1]);
03195    ast_mutex_unlock(&iaxsl[callno0]);
03196 }
03197 
03198 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)
03199 {
03200    struct ast_channel *cs[3];
03201    struct ast_channel *who;
03202    int to = -1;
03203    int res = -1;
03204    int transferstarted=0;
03205    struct ast_frame *f;
03206    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03207    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03208    struct timeval waittimer = {0, 0}, tv;
03209 
03210    lock_both(callno0, callno1);
03211    /* Put them in native bridge mode */
03212    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03213       iaxs[callno0]->bridgecallno = callno1;
03214       iaxs[callno1]->bridgecallno = callno0;
03215    }
03216    unlock_both(callno0, callno1);
03217 
03218    /* If not, try to bridge until we can execute a transfer, if we can */
03219    cs[0] = c0;
03220    cs[1] = c1;
03221    for (/* ever */;;) {
03222       /* Check in case we got masqueraded into */
03223       if ((c0->type != channeltype) || (c1->type != channeltype)) {
03224          if (option_verbose > 2)
03225             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03226          /* Remove from native mode */
03227          if (c0->type == channeltype) {
03228             ast_mutex_lock(&iaxsl[callno0]);
03229             iaxs[callno0]->bridgecallno = 0;
03230             ast_mutex_unlock(&iaxsl[callno0]);
03231          }
03232          if (c1->type == channeltype) {
03233             ast_mutex_lock(&iaxsl[callno1]);
03234             iaxs[callno1]->bridgecallno = 0;
03235             ast_mutex_unlock(&iaxsl[callno1]);
03236          }
03237          return AST_BRIDGE_FAILED_NOWARN;
03238       }
03239       if (c0->nativeformats != c1->nativeformats) {
03240          if (option_verbose > 2) {
03241             char buf0[255];
03242             char buf1[255];
03243             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03244             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03245             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03246          }
03247          /* Remove from native mode */
03248          lock_both(callno0, callno1);
03249          iaxs[callno0]->bridgecallno = 0;
03250          iaxs[callno1]->bridgecallno = 0;
03251          unlock_both(callno0, callno1);
03252          return AST_BRIDGE_FAILED_NOWARN;
03253       }
03254       /* check if transfered and if we really want native bridging */
03255       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) && 
03256       !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
03257          /* Try the transfer */
03258          if (iax2_start_transfer(callno0, callno1))
03259             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03260          transferstarted = 1;
03261       }
03262       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03263          /* Call has been transferred.  We're no longer involved */
03264          gettimeofday(&tv, NULL);
03265          if (ast_tvzero(waittimer)) {
03266             waittimer = tv;
03267          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03268             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03269             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03270             *fo = NULL;
03271             *rc = c0;
03272             res = AST_BRIDGE_COMPLETE;
03273             break;
03274          }
03275       }
03276       to = 1000;
03277       who = ast_waitfor_n(cs, 2, &to);
03278       if (timeoutms > -1) {
03279          timeoutms -= (1000 - to);
03280          if (timeoutms < 0)
03281             timeoutms = 0;
03282       }
03283       if (!who) {
03284          if (!timeoutms) {
03285             res = AST_BRIDGE_RETRY;
03286             break;
03287          }
03288          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03289             res = AST_BRIDGE_FAILED;
03290             break;
03291          }
03292          continue;
03293       }
03294       f = ast_read(who);
03295       if (!f) {
03296          *fo = NULL;
03297          *rc = who;
03298          res = AST_BRIDGE_COMPLETE;
03299          break;
03300       }
03301       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03302          *fo = f;
03303          *rc = who;
03304          res =  AST_BRIDGE_COMPLETE;
03305          break;
03306       }
03307       if ((f->frametype == AST_FRAME_VOICE) ||
03308           (f->frametype == AST_FRAME_TEXT) ||
03309           (f->frametype == AST_FRAME_VIDEO) || 
03310           (f->frametype == AST_FRAME_IMAGE) ||
03311           (f->frametype == AST_FRAME_DTMF)) {
03312          if ((f->frametype == AST_FRAME_DTMF) && 
03313              (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
03314             if ((who == c0)) {
03315                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
03316                   *rc = c0;
03317                   *fo = f;
03318                   res = AST_BRIDGE_COMPLETE;
03319                   /* Remove from native mode */
03320                   break;
03321                } else 
03322                   goto tackygoto;
03323             } else
03324             if ((who == c1)) {
03325                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
03326                   *rc = c1;
03327                   *fo = f;
03328                   res =  AST_BRIDGE_COMPLETE;
03329                   break;
03330                } else
03331                   goto tackygoto;
03332             }
03333          } else {
03334 #if 0
03335             if (iaxdebug && option_debug)
03336                ast_log(LOG_DEBUG, "Read from %s\n", who->name);
03337             if (who == last) 
03338                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
03339             last = who;
03340 #endif
03341 tackygoto:
03342             if (who == c0) 
03343                ast_write(c1, f);
03344             else 
03345                ast_write(c0, f);
03346          }
03347          ast_frfree(f);
03348       } else
03349          ast_frfree(f);
03350       /* Swap who gets priority */
03351       cs[2] = cs[0];
03352       cs[0] = cs[1];
03353       cs[1] = cs[2];
03354    }
03355    lock_both(callno0, callno1);
03356    if(iaxs[callno0])
03357       iaxs[callno0]->bridgecallno = 0;
03358    if(iaxs[callno1])
03359       iaxs[callno1]->bridgecallno = 0;
03360    unlock_both(callno0, callno1);
03361    return res;
03362 }
03363 
03364 static int iax2_answer(struct ast_channel *c)
03365 {
03366    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03367    if (option_debug)
03368       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03369    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03370 }
03371 
03372 static int iax2_indicate(struct ast_channel *c, int condition)
03373 {
03374    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03375    if (option_debug && iaxdebug)
03376       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03377    return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
03378 }
03379    
03380 static int iax2_transfer(struct ast_channel *c, const char *dest)
03381 {
03382    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03383    struct iax_ie_data ied;
03384    char tmp[256], *context;
03385    ast_copy_string(tmp, dest, sizeof(tmp));
03386    context = strchr(tmp, '@');
03387    if (context) {
03388       *context = '\0';
03389       context++;
03390    }
03391    memset(&ied, 0, sizeof(ied));
03392    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03393    if (context)
03394       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03395    if (option_debug)
03396       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03397    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03398 }
03399    
03400 
03401 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
03402 
03403 static int iax2_getpeertrunk(struct sockaddr_in sin)
03404 {
03405    struct iax2_peer *peer;
03406    int res = 0;
03407    ast_mutex_lock(&peerl.lock);
03408    peer = peerl.peers;
03409    while(peer) {
03410       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03411             (peer->addr.sin_port == sin.sin_port)) {
03412                res = ast_test_flag(peer, IAX_TRUNK);
03413                break;
03414       }
03415       peer = peer->next;
03416    }
03417    ast_mutex_unlock(&peerl.lock);
03418    return res;
03419 }
03420 
03421 /*--- ast_iax2_new: Create new call, interface with the PBX core */
03422 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03423 {
03424    struct ast_channel *tmp;
03425    struct chan_iax2_pvt *i;
03426    struct ast_variable *v = NULL;
03427 
03428    /* Don't hold call lock */
03429    ast_mutex_unlock(&iaxsl[callno]);
03430    tmp = ast_channel_alloc(1);
03431    ast_mutex_lock(&iaxsl[callno]);
03432    i = iaxs[callno];
03433    if (i && tmp) {
03434       tmp->tech = &iax2_tech;
03435       snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s-%d", i->host, i->callno);
03436       tmp->type = channeltype;
03437       /* We can support any format by default, until we get restricted */
03438       tmp->nativeformats = capability;
03439       tmp->readformat = ast_best_codec(capability);
03440       tmp->writeformat = ast_best_codec(capability);
03441       tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03442 
03443       if (!ast_strlen_zero(i->cid_num))
03444          tmp->cid.cid_num = strdup(i->cid_num);
03445       if (!ast_strlen_zero(i->cid_name))
03446          tmp->cid.cid_name = strdup(i->cid_name);
03447       if (!ast_strlen_zero(i->ani))
03448          tmp->cid.cid_ani = strdup(i->ani);
03449       tmp->cid.cid_pres = i->calling_pres;
03450       tmp->cid.cid_ton = i->calling_ton;
03451       tmp->cid.cid_tns = i->calling_tns;
03452 
03453       if (!ast_strlen_zero(i->language))
03454          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
03455       if (!ast_strlen_zero(i->dnid))
03456          tmp->cid.cid_dnid = strdup(i->dnid);
03457       if (!ast_strlen_zero(i->accountcode))
03458          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
03459       if (i->amaflags)
03460          tmp->amaflags = i->amaflags;
03461       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03462       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03463       tmp->adsicpe = i->peeradsicpe;
03464       i->owner = tmp;
03465       i->capability = capability;
03466       ast_setstate(tmp, state);
03467       if (state != AST_STATE_DOWN) {
03468          if (ast_pbx_start(tmp)) {
03469             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03470             ast_hangup(tmp);
03471             tmp = NULL;
03472          }
03473       }
03474       for (v = i->vars ; v ; v = v->next)
03475          pbx_builtin_setvar_helper(tmp,v->name,v->value);
03476       
03477       ast_mutex_lock(&usecnt_lock);
03478       usecnt++;
03479       ast_mutex_unlock(&usecnt_lock);
03480       ast_update_use_count();
03481    }
03482    return tmp;
03483 }
03484 
03485 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03486 {
03487    unsigned long int mssincetx; /* unsigned to handle overflows */
03488    long int ms, pred;
03489 
03490    tpeer->trunkact = *tv;
03491    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03492    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03493       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03494       tpeer->txtrunktime = *tv;
03495       tpeer->lastsent = 999999;
03496    }
03497    /* Update last transmit time now */
03498    tpeer->lasttxtime = *tv;
03499    
03500    /* Calculate ms offset */
03501    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03502    /* Predict from last value */
03503    pred = tpeer->lastsent + sampms;
03504    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03505       ms = pred;
03506    
03507    /* We never send the same timestamp twice, so fudge a little if we must */
03508    if (ms == tpeer->lastsent)
03509       ms = tpeer->lastsent + 1;
03510    tpeer->lastsent = ms;
03511    return ms;
03512 }
03513 
03514 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03515 {
03516    long ms; /* NOT unsigned */
03517    if (ast_tvzero(iaxs[callno]->rxcore)) {
03518       /* Initialize rxcore time if appropriate */
03519       gettimeofday(&iaxs[callno]->rxcore, NULL);
03520       /* Round to nearest 20ms so traces look pretty */
03521       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03522    }
03523    /* Calculate difference between trunk and channel */
03524    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03525    /* Return as the sum of trunk time and the difference between trunk and real time */
03526    return ms + ts;
03527 }
03528 
03529 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03530 {
03531    int ms;
03532    int voice = 0;
03533    int genuine = 0;
03534    int adjust;
03535    struct timeval *delivery = NULL;
03536 
03537 
03538    /* What sort of frame do we have?: voice is self-explanatory
03539       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03540       non-genuine frames are CONTROL frames [ringing etc], DTMF
03541       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03542       the others need a timestamp slaved to the voice frames so that they go in sequence
03543    */
03544    if (f) {
03545       if (f->frametype == AST_FRAME_VOICE) {
03546          voice = 1;
03547          delivery = &f->delivery;
03548       } else if (f->frametype == AST_FRAME_IAX) {
03549          genuine = 1;
03550       } else if (f->frametype == AST_FRAME_CNG) {
03551          p->notsilenttx = 0;  
03552       }
03553    }
03554    if (ast_tvzero(p->offset)) {
03555       gettimeofday(&p->offset, NULL);
03556       /* Round to nearest 20ms for nice looking traces */
03557       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03558    }
03559    /* If the timestamp is specified, just send it as is */
03560    if (ts)
03561       return ts;
03562    /* If we have a time that the frame arrived, always use it to make our timestamp */
03563    if (delivery && !ast_tvzero(*delivery)) {
03564       ms = ast_tvdiff_ms(*delivery, p->offset);
03565       if (option_debug > 2 && iaxdebug)
03566          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03567    } else {
03568       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03569       if (ms < 0)
03570          ms = 0;
03571       if (voice) {
03572          /* On a voice frame, use predicted values if appropriate */
03573          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03574             /* Adjust our txcore, keeping voice and non-voice synchronized */
03575             /* AN EXPLANATION:
03576                When we send voice, we usually send "calculated" timestamps worked out
03577                on the basis of the number of samples sent. When we send other frames,
03578                we usually send timestamps worked out from the real clock.
03579                The problem is that they can tend to drift out of step because the 
03580                   source channel's clock and our clock may not be exactly at the same rate.
03581                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03582                for this call.  Moving it adjusts timestamps for non-voice frames.
03583                We make the adjustment in the style of a moving average.  Each time we
03584                adjust p->offset by 10% of the difference between our clock-derived
03585                timestamp and the predicted timestamp.  That's why you see "10000"
03586                below even though IAX2 timestamps are in milliseconds.
03587                The use of a moving average avoids offset moving too radically.
03588                Generally, "adjust" roams back and forth around 0, with offset hardly
03589                changing at all.  But if a consistent different starts to develop it
03590                will be eliminated over the course of 10 frames (200-300msecs) 
03591             */
03592             adjust = (ms - p->nextpred);
03593             if (adjust < 0)
03594                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03595             else if (adjust > 0)
03596                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03597 
03598             if (!p->nextpred) {
03599                p->nextpred = ms; /*f->samples / 8;*/
03600                if (p->nextpred <= p->lastsent)
03601                   p->nextpred = p->lastsent + 3;
03602             }
03603             ms = p->nextpred;
03604          } else {
03605                 /* in this case, just use the actual
03606             * time, since we're either way off
03607             * (shouldn't happen), or we're  ending a
03608             * silent period -- and seed the next
03609             * predicted time.  Also, round ms to the
03610             * next multiple of frame size (so our
03611             * silent periods are multiples of
03612             * frame size too) */
03613 
03614             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03615                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03616                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03617 
03618             if (f->samples >= 8) /* check to make sure we dont core dump */
03619             {
03620                int diff = ms % (f->samples / 8);
03621                if (diff)
03622                    ms += f->samples/8 - diff;
03623             }
03624 
03625             p->nextpred = ms;
03626             p->notsilenttx = 1;
03627          }
03628       } else {
03629          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03630             it's a genuine frame */
03631          if (genuine) {
03632             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03633             if (ms <= p->lastsent)
03634                ms = p->lastsent + 3;
03635          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03636             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03637             ms = p->lastsent + 3;
03638          }
03639       }
03640    }
03641    p->lastsent = ms;
03642    if (voice)
03643       p->nextpred = p->nextpred + f->samples / 8;
03644    return ms;
03645 }
03646 
03647 #ifdef BRIDGE_OPTIMIZATION
03648 static unsigned int calc_fakestamp(struct chan_iax2_pvt *p1, struct chan_iax2_pvt *p2, unsigned int fakets)
03649 {
03650    int ms;
03651    /* Receive from p1, send to p2 */
03652    
03653    /* Setup rxcore if necessary on outgoing channel */
03654    if (ast_tvzero(p1->rxcore))
03655       p1->rxcore = ast_tvnow();
03656 
03657    /* Setup txcore if necessary on outgoing channel */
03658    if (ast_tvzero(p2->offset))
03659       p2->offset = ast_tvnow();
03660    
03661    /* Now, ts is the timestamp of the original packet in the orignal context.
03662       Adding rxcore to it gives us when we would want the packet to be delivered normally.
03663       Subtracting txcore of the outgoing channel gives us what we'd expect */
03664    
03665    ms = ast_tvdiff_ms(p1->rxcore, p2->offset);
03666    fakets += ms;
03667 
03668    p2->lastsent = fakets;
03669    return fakets;
03670 }
03671 #endif
03672 
03673 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03674 {
03675    /* Returns where in "receive time" we are.  That is, how many ms
03676       since we received (or would have received) the frame with timestamp 0 */
03677    int ms;
03678 #ifdef IAXTESTS
03679    int jit;
03680 #endif /* IAXTESTS */
03681    /* Setup rxcore if necessary */
03682    if (ast_tvzero(p->rxcore)) {
03683       p->rxcore = ast_tvnow();
03684       if (option_debug && iaxdebug)
03685          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03686                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03687       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03688 #if 1
03689       if (option_debug && iaxdebug)
03690          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03691                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03692 #endif
03693    }
03694 
03695    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03696 #ifdef IAXTESTS
03697    if (test_jit) {
03698       if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
03699          jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0));
03700          if ((int)(2.0 * rand() / (RAND_MAX + 1.0)))
03701             jit = -jit;
03702          ms += jit;
03703       }
03704    }
03705    if (test_late) {
03706       ms += test_late;
03707       test_late = 0;
03708    }
03709 #endif /* IAXTESTS */
03710    return ms;
03711 }
03712 
03713 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03714 {
03715    struct iax2_trunk_peer *tpeer;
03716    char iabuf[INET_ADDRSTRLEN];
03717    /* Finds and locks trunk peer */
03718    ast_mutex_lock(&tpeerlock);
03719    tpeer = tpeers;
03720    while(tpeer) {
03721       /* We don't lock here because tpeer->addr *never* changes */
03722       if (!inaddrcmp(&tpeer->addr, sin)) {
03723          ast_mutex_lock(&tpeer->lock);
03724          break;
03725       }
03726       tpeer = tpeer->next;
03727    }
03728    if (!tpeer) {
03729       tpeer = malloc(sizeof(struct iax2_trunk_peer));
03730       if (tpeer) {
03731          memset(tpeer, 0, sizeof(struct iax2_trunk_peer));
03732          ast_mutex_init(&tpeer->lock);
03733          tpeer->lastsent = 9999;
03734          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03735          tpeer->trunkact = ast_tvnow();
03736          ast_mutex_lock(&tpeer->lock);
03737          tpeer->next = tpeers;
03738          tpeer->sockfd = fd;
03739          tpeers = tpeer;
03740 #ifdef SO_NO_CHECK
03741          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03742 #endif
03743          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));
03744       }
03745    }
03746    ast_mutex_unlock(&tpeerlock);
03747    return tpeer;
03748 }
03749 
03750 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03751 {
03752    struct ast_frame *f;
03753    struct iax2_trunk_peer *tpeer;
03754    void *tmp, *ptr;
03755    struct ast_iax2_meta_trunk_entry *met;
03756    struct ast_iax2_meta_trunk_mini *mtm;
03757    char iabuf[INET_ADDRSTRLEN];
03758 
03759    f = &fr->af;
03760    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03761    if (tpeer) {
03762       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03763          /* Need to reallocate space */
03764          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03765             tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE);
03766             if (tmp) {
03767                tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03768                tpeer->trunkdata = tmp;
03769                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);
03770             } else {
03771                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));
03772                ast_mutex_unlock(&tpeer->lock);
03773                return -1;
03774             }
03775          } else {
03776             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));
03777             ast_mutex_unlock(&tpeer->lock);
03778             return -1;
03779          }
03780       }
03781 
03782       /* Append to meta frame */
03783       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03784       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03785          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03786          mtm->len = htons(f->datalen);
03787          mtm->mini.callno = htons(pvt->callno);
03788          mtm->mini.ts = htons(0xffff & fr->ts);
03789          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03790          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03791       } else {
03792          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03793          /* Store call number and length in meta header */
03794          met->callno = htons(pvt->callno);
03795          met->len = htons(f->datalen);
03796          /* Advance pointers/decrease length past trunk entry header */
03797          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03798          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03799       }
03800       /* Copy actual trunk data */
03801       memcpy(ptr, f->data, f->datalen);
03802       tpeer->trunkdatalen += f->datalen;
03803 
03804       tpeer->calls++;
03805       ast_mutex_unlock(&tpeer->lock);
03806    }
03807    return 0;
03808 }
03809 
03810 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03811 {
03812    aes_encrypt_key128(digest, ecx);
03813    aes_decrypt_key128(digest, dcx);
03814 }
03815 
03816 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03817 {
03818 #if 0
03819    /* Debug with "fake encryption" */
03820    int x;
03821    if (len % 16)
03822       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03823    for (x=0;x<len;x++)
03824       dst[x] = src[x] ^ 0xff;
03825 #else 
03826    unsigned char lastblock[16] = { 0 };
03827    int x;
03828    while(len > 0) {
03829       aes_decrypt(src, dst, dcx);
03830       for (x=0;x<16;x++)
03831          dst[x] ^= lastblock[x];
03832       memcpy(lastblock, src, sizeof(lastblock));
03833       dst += 16;
03834       src += 16;
03835       len -= 16;
03836    }
03837 #endif
03838 }
03839 
03840 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03841 {
03842 #if 0
03843    /* Debug with "fake encryption" */
03844    int x;
03845    if (len % 16)
03846       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03847    for (x=0;x<len;x++)
03848       dst[x] = src[x] ^ 0xff;
03849 #else
03850    unsigned char curblock[16] = { 0 };
03851    int x;
03852    while(len > 0) {
03853       for (x=0;x<16;x++)
03854          curblock[x] ^= src[x];
03855       aes_encrypt(curblock, dst, ecx);
03856       memcpy(curblock, dst, sizeof(curblock)); 
03857       dst += 16;
03858       src += 16;
03859       len -= 16;
03860    }
03861 #endif
03862 }
03863 
03864 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03865 {
03866    int padding;
03867    unsigned char *workspace;
03868    workspace = alloca(*datalen);
03869    if (!workspace)
03870       return -1;
03871    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03872       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03873       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03874          return -1;
03875       /* Decrypt */
03876       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03877 
03878       padding = 16 + (workspace[15] & 0xf);
03879       if (option_debug && iaxdebug)
03880          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03881       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03882          return -1;
03883 
03884       *datalen -= padding;
03885       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03886       f->frametype = fh->type;
03887       if (f->frametype == AST_FRAME_VIDEO) {
03888          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03889       } else {
03890          f->subclass = uncompress_subclass(fh->csub);
03891       }
03892    } else {
03893       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03894       if (option_debug && iaxdebug)
03895          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03896       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03897          return -1;
03898       /* Decrypt */
03899       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03900       padding = 16 + (workspace[15] & 0x0f);
03901       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03902          return -1;
03903       *datalen -= padding;
03904       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03905    }
03906    return 0;
03907 }
03908 
03909 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
03910 {
03911    int padding;
03912    unsigned char *workspace;
03913    workspace = alloca(*datalen + 32);
03914    if (!workspace)
03915       return -1;
03916    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03917       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03918       if (option_debug && iaxdebug)
03919          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03920       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03921       padding = 16 + (padding & 0xf);
03922       memcpy(workspace, poo, padding);
03923       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03924       workspace[15] &= 0xf0;
03925       workspace[15] |= (padding & 0xf);
03926       if (option_debug && iaxdebug)
03927          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]);
03928       *datalen += padding;
03929       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03930       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03931          memcpy(poo, workspace + *datalen - 32, 32);
03932    } else {
03933       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03934       if (option_debug && iaxdebug)
03935          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03936       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03937       padding = 16 + (padding & 0xf);
03938       memcpy(workspace, poo, padding);
03939       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03940       workspace[15] &= 0xf0;
03941       workspace[15] |= (padding & 0x0f);
03942       *datalen += padding;
03943       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03944       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03945          memcpy(poo, workspace + *datalen - 32, 32);
03946    }
03947    return 0;
03948 }
03949 
03950 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03951 {
03952    int res=-1;
03953    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03954       /* Search for possible keys, given secrets */
03955       struct MD5Context md5;
03956       unsigned char digest[16];
03957       char *tmppw, *stringp;
03958       
03959       tmppw = ast_strdupa(iaxs[callno]->secret);
03960       stringp = tmppw;
03961       while((tmppw = strsep(&stringp, ";"))) {
03962          MD5Init(&md5);
03963          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03964          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03965          MD5Final(digest, &md5);
03966          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03967          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03968          if (!res) {
03969             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03970             break;
03971          }
03972       }
03973    } else 
03974       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03975    return res;
03976 }
03977 
03978 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
03979 {
03980    /* Queue a packet for delivery on a given private structure.  Use "ts" for
03981       timestamp, or calculate if ts is 0.  Send immediately without retransmission
03982       or delayed, with retransmission */
03983    struct ast_iax2_full_hdr *fh;
03984    struct ast_iax2_mini_hdr *mh;
03985    struct ast_iax2_video_hdr *vh;
03986    struct {
03987       struct iax_frame fr2;
03988       unsigned char buffer[4096];
03989    } frb;
03990    struct iax_frame *fr;
03991    int res;
03992    int sendmini=0;
03993    unsigned int lastsent;
03994    unsigned int fts;
03995       
03996    if (!pvt) {
03997       ast_log(LOG_WARNING, "No private structure for packet?\n");
03998       return -1;
03999    }
04000    
04001    lastsent = pvt->lastsent;
04002 
04003    /* Calculate actual timestamp */
04004    fts = calc_timestamp(pvt, ts, f);
04005 
04006    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04007     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04008     * increment the "predicted timestamps" for voice, if we're predecting */
04009    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04010        return 0;
04011 
04012 
04013    if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)))
04014       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04015        (f->frametype == AST_FRAME_VOICE) 
04016       /* is a voice frame */ &&
04017       (f->subclass == pvt->svoiceformat) 
04018       /* is the same type */ ) {
04019          /* Force immediate rather than delayed transmission */
04020          now = 1;
04021          /* Mark that mini-style frame is appropriate */
04022          sendmini = 1;
04023    }
04024    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
04025       (f->frametype == AST_FRAME_VIDEO) &&
04026       ((f->subclass & ~0x1) == pvt->svideoformat)) {
04027          now = 1;
04028          sendmini = 1;
04029    }
04030    /* Allocate an iax_frame */
04031    if (now) {
04032       fr = &frb.fr2;
04033    } else
04034       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen);
04035    if (!fr) {
04036       ast_log(LOG_WARNING, "Out of memory\n");
04037       return -1;
04038    }
04039    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04040    iax_frame_wrap(fr, f);
04041 
04042    fr->ts = fts;
04043    fr->callno = pvt->callno;
04044    fr->transfer = transfer;
04045    fr->final = final;
04046    if (!sendmini) {
04047       /* We need a full frame */
04048       if (seqno > -1)
04049          fr->oseqno = seqno;
04050       else
04051          fr->oseqno = pvt->oseqno++;
04052       fr->iseqno = pvt->iseqno;
04053       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04054       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04055       fh->ts = htonl(fr->ts);
04056       fh->oseqno = fr->oseqno;
04057       if (transfer) {
04058          fh->iseqno = 0;
04059       } else
04060          fh->iseqno = fr->iseqno;
04061       /* Keep track of the last thing we've acknowledged */
04062       if (!transfer)
04063          pvt->aseqno = fr->iseqno;
04064       fh->type = fr->af.frametype & 0xFF;
04065       if (fr->af.frametype == AST_FRAME_VIDEO)
04066          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04067       else
04068          fh->csub = compress_subclass(fr->af.subclass);
04069       if (transfer) {
04070          fr->dcallno = pvt->transfercallno;
04071       } else
04072          fr->dcallno = pvt->peercallno;
04073       fh->dcallno = htons(fr->dcallno);
04074       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04075       fr->data = fh;
04076       fr->retries = 0;
04077       /* Retry after 2x the ping time has passed */
04078       fr->retrytime = pvt->pingtime * 2;
04079       if (fr->retrytime < MIN_RETRY_TIME)
04080          fr->retrytime = MIN_RETRY_TIME;
04081       if (fr->retrytime > MAX_RETRY_TIME)
04082          fr->retrytime = MAX_RETRY_TIME;
04083       /* Acks' don't get retried */
04084       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04085          fr->retries = -1;
04086       else if (f->frametype == AST_FRAME_VOICE)
04087          pvt->svoiceformat = f->subclass;
04088       else if (f->frametype == AST_FRAME_VIDEO)
04089          pvt->svideoformat = f->subclass & ~0x1;
04090       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04091          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04092             if (iaxdebug) {
04093                if (fr->transfer)
04094                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04095                else
04096                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04097             }
04098             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04099          } else
04100             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04101       }
04102    
04103       if (now) {
04104          res = send_packet(fr);
04105       } else
04106          res = iax2_transmit(fr);
04107    } else {
04108       if (ast_test_flag(pvt, IAX_TRUNK)) {
04109          iax2_trunk_queue(pvt, fr);
04110          res = 0;
04111       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04112          /* Video frame have no sequence number */
04113          fr->oseqno = -1;
04114          fr->iseqno = -1;
04115          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04116          vh->zeros = 0;
04117          vh->callno = htons(0x8000 | fr->callno);
04118          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04119          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04120          fr->data = vh;
04121          fr->retries = -1;
04122          res = send_packet(fr);        
04123       } else {
04124          /* Mini-frames have no sequence number */
04125          fr->oseqno = -1;
04126          fr->iseqno = -1;
04127          /* Mini frame will do */
04128          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04129          mh->callno = htons(fr->callno);
04130          mh->ts = htons(fr->ts & 0xFFFF);
04131          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04132          fr->data = mh;
04133          fr->retries = -1;
04134          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04135             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04136                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04137             } else
04138                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04139          }
04140          res = send_packet(fr);
04141       }
04142    }
04143    return res;
04144 }
04145 
04146 
04147 
04148 static int iax2_show_users(int fd, int argc, char *argv[])
04149 {
04150    regex_t regexbuf;
04151    int havepattern = 0;
04152 
04153 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04154 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04155 
04156    struct iax2_user *user;
04157    char auth[90];
04158    char *pstr = "";
04159 
04160    switch (argc) {
04161    case 5:
04162       if (!strcasecmp(argv[3], "like")) {
04163          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04164             return RESULT_SHOWUSAGE;
04165          havepattern = 1;
04166       } else
04167          return RESULT_SHOWUSAGE;
04168    case 3:
04169       break;
04170    default:
04171       return RESULT_SHOWUSAGE;
04172    }
04173 
04174    ast_mutex_lock(&userl.lock);
04175    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04176    for(user=userl.users;user;user=user->next) {
04177       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04178          continue;
04179 
04180       if (!ast_strlen_zero(user->secret)) {
04181          ast_copy_string(auth,user->secret,sizeof(auth));
04182       } else if (!ast_strlen_zero(user->inkeys)) {
04183          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04184       } else
04185          ast_copy_string(auth, "-no secret-", sizeof(auth));
04186 
04187       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04188          pstr = "REQ Only";
04189       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04190          pstr = "Disabled";
04191       else
04192          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04193 
04194       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04195             user->contexts ? user->contexts->context : context,
04196             user->ha ? "Yes" : "No", pstr);
04197 
04198    }
04199    ast_mutex_unlock(&userl.lock);
04200 
04201    if (havepattern)
04202       regfree(&regexbuf);
04203 
04204    return RESULT_SUCCESS;
04205 #undef FORMAT
04206 #undef FORMAT2
04207 }
04208 
04209 static int __iax2_show_peers(int manager, int fd, int argc, char *argv[])
04210 {
04211    regex_t regexbuf;
04212    int havepattern = 0;
04213    int total_peers = 0;
04214    int online_peers = 0;
04215    int offline_peers = 0;
04216    int unmonitored_peers = 0;
04217 
04218 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04219 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04220 
04221    struct iax2_peer *peer;
04222    char name[256];
04223    char iabuf[INET_ADDRSTRLEN];
04224    int registeredonly=0;
04225    char *term = manager ? "\r\n" : "\n";
04226 
04227    switch (argc) {
04228    case 6:
04229       if (!strcasecmp(argv[3], "registered"))
04230          registeredonly = 1;
04231       else
04232          return RESULT_SHOWUSAGE;
04233       if (!strcasecmp(argv[4], "like")) {
04234          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04235             return RESULT_SHOWUSAGE;
04236          havepattern = 1;
04237       } else
04238          return RESULT_SHOWUSAGE;
04239       break;
04240    case 5:
04241       if (!strcasecmp(argv[3], "like")) {
04242          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04243             return RESULT_SHOWUSAGE;
04244          havepattern = 1;
04245       } else
04246          return RESULT_SHOWUSAGE;
04247       break;
04248    case 4:
04249       if (!strcasecmp(argv[3], "registered"))
04250          registeredonly = 1;
04251       else
04252          return RESULT_SHOWUSAGE;
04253       break;
04254    case 3:
04255       break;
04256    default:
04257       return RESULT_SHOWUSAGE;
04258    }
04259 
04260    ast_mutex_lock(&peerl.lock);
04261    ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04262    for (peer = peerl.peers;peer;peer = peer->next) {
04263       char nm[20];
04264       char status[20];
04265       char srch[2000];
04266       int retstatus;
04267 
04268       if (registeredonly && !peer->addr.sin_addr.s_addr)
04269          continue;
04270       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04271          continue;
04272 
04273       if (!ast_strlen_zero(peer->username))
04274          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04275       else
04276          ast_copy_string(name, peer->name, sizeof(name));
04277       
04278       retstatus = peer_status(peer, status, sizeof(status));
04279       if (retstatus > 0)
04280          online_peers++;
04281       else if (!retstatus)
04282          offline_peers++;
04283       else
04284          unmonitored_peers++;
04285       
04286       ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm));
04287 
04288       snprintf(srch, sizeof(srch), FORMAT, name, 
04289                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
04290                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04291                nm,
04292                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04293                peer->encmethods ? "(E)" : "   ", status, term);
04294 
04295       ast_cli(fd, FORMAT, name, 
04296                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
04297                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04298                nm,
04299                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04300                peer->encmethods ? "(E)" : "   ", status, term);
04301       total_peers++;
04302    }
04303    ast_mutex_unlock(&peerl.lock);
04304 
04305    ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04306 
04307    if (havepattern)
04308       regfree(&regexbuf);
04309 
04310    return RESULT_SUCCESS;
04311 #undef FORMAT
04312 #undef FORMAT2
04313 }
04314 
04315 static int iax2_show_peers(int fd, int argc, char *argv[])
04316 {
04317    return __iax2_show_peers(0, fd, argc, argv);
04318 }
04319 static int manager_iax2_show_netstats( struct mansession *s, struct message *m )
04320 {
04321    ast_cli_netstats(s->fd, 0);
04322    ast_cli(s->fd, "\r\n");
04323    return RESULT_SUCCESS;
04324 }
04325 
04326 static int iax2_show_firmware(int fd, int argc, char *argv[])
04327 {
04328 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04329 #if !defined(__FreeBSD__)
04330 #define FORMAT "%-15.15s  %-15d %-15d\n"
04331 #else /* __FreeBSD__ */
04332 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04333 #endif /* __FreeBSD__ */
04334    struct iax_firmware *cur;
04335    if ((argc != 3) && (argc != 4))
04336       return RESULT_SHOWUSAGE;
04337    ast_mutex_lock(&waresl.lock);
04338    
04339    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04340    for (cur = waresl.wares;cur;cur = cur->next) {
04341       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04342          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04343             (int)ntohl(cur->fwh->datalen));
04344    }
04345    ast_mutex_unlock(&waresl.lock);
04346    return RESULT_SUCCESS;
04347 #undef FORMAT
04348 #undef FORMAT2
04349 }
04350 
04351 /* JDG: callback to display iax peers in manager */
04352 static int manager_iax2_show_peers( struct mansession *s, struct message *m )
04353 {
04354    char *a[] = { "iax2", "show", "users" };
04355    int ret;
04356    char *id;
04357    id = astman_get_header(m,"ActionID");
04358    if (!ast_strlen_zero(id))
04359       ast_cli(s->fd, "ActionID: %s\r\n",id);
04360    ret = __iax2_show_peers(1, s->fd, 3, a );
04361    ast_cli(s->fd, "\r\n\r\n" );
04362    return ret;
04363 } /* /JDG */
04364 
04365 static char *regstate2str(int regstate)
04366 {
04367    switch(regstate) {
04368    case REG_STATE_UNREGISTERED:
04369       return "Unregistered";
04370    case REG_STATE_REGSENT:
04371       return "Request Sent";
04372    case REG_STATE_AUTHSENT:
04373       return "Auth. Sent";
04374    case REG_STATE_REGISTERED:
04375       return "Registered";
04376    case REG_STATE_REJECTED:
04377       return "Rejected";
04378    case REG_STATE_TIMEOUT:
04379       return "Timeout";
04380    case REG_STATE_NOAUTH:
04381       return "No Authentication";
04382    default:
04383       return "Unknown";
04384    }
04385 }
04386 
04387 static int iax2_show_registry(int fd, int argc, char *argv[])
04388 {
04389 #define FORMAT2 "%-20.20s  %-10.10s  %-20.20s %8.8s  %s\n"
04390 #define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
04391    struct iax2_registry *reg;
04392    char host[80];
04393    char perceived[80];
04394    char iabuf[INET_ADDRSTRLEN];
04395    if (argc != 3)
04396       return RESULT_SHOWUSAGE;
04397    ast_mutex_lock(&peerl.lock);
04398    ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
04399    for (reg = registrations;reg;reg = reg->next) {
04400       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04401       if (reg->us.sin_addr.s_addr) 
04402          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
04403       else
04404          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04405       ast_cli(fd, FORMAT, host, 
04406                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04407    }
04408    ast_mutex_unlock(&peerl.lock);
04409    return RESULT_SUCCESS;
04410 #undef FORMAT
04411 #undef FORMAT2
04412 }
04413 
04414 #ifndef NEWJB
04415 static int jitterbufsize(struct chan_iax2_pvt *pvt) {
04416    int min, i;
04417    min = 99999999;
04418    for (i=0; i<MEMORY_SIZE; i++) {
04419       if (pvt->history[i] < min)
04420          min = pvt->history[i];
04421    }
04422    if (pvt->jitterbuffer - min > maxjitterbuffer)
04423       return maxjitterbuffer;
04424    else
04425       return pvt->jitterbuffer - min;
04426 }
04427 #endif
04428 
04429 static int iax2_show_channels(int fd, int argc, char *argv[])
04430 {
04431 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04432 #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"
04433 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04434    int x;
04435    int numchans = 0;
04436    char iabuf[INET_ADDRSTRLEN];
04437 
04438    if (argc != 3)
04439       return RESULT_SHOWUSAGE;
04440    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04441    for (x=0;x<IAX_MAX_CALLS;x++) {
04442       ast_mutex_lock(&iaxsl[x]);
04443       if (iaxs[x]) {
04444 #ifdef BRIDGE_OPTIMIZATION
04445          if (iaxs[x]->bridgecallno)
04446             ast_cli(fd, FORMATB,
04447                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04448                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 
04449                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
04450                   iaxs[x]->callno, iaxs[x]->peercallno, 
04451                   iaxs[x]->oseqno, iaxs[x]->iseqno, 
04452                   iaxs[x]->bridgecallno );
04453          else
04454 #endif
04455          {
04456             int lag, jitter, localdelay;
04457 #ifdef NEWJB
04458             jb_info jbinfo;
04459 
04460             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04461                jb_getinfo(iaxs[x]->jb, &jbinfo);
04462                jitter = jbinfo.jitter;
04463                localdelay = jbinfo.current - jbinfo.min;
04464             } else {
04465                jitter = -1;
04466                localdelay = 0;
04467             }
04468 #else
04469             jitter = iaxs[x]->jitter;
04470             localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0;
04471 #endif
04472             lag = iaxs[x]->remote_rr.delay;
04473             ast_cli(fd, FORMAT,
04474                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04475                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 
04476                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
04477                   iaxs[x]->callno, iaxs[x]->peercallno, 
04478                   iaxs[x]->oseqno, iaxs[x]->iseqno, 
04479                   lag,
04480                   jitter,
04481                   localdelay,
04482                   ast_getformatname(iaxs[x]->voiceformat) );
04483          }
04484          numchans++;
04485       }
04486       ast_mutex_unlock(&iaxsl[x]);
04487    }
04488    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04489    return RESULT_SUCCESS;
04490 #undef FORMAT
04491 #undef FORMAT2
04492 #undef FORMATB
04493 }
04494 
04495 static int ast_cli_netstats(int fd, int limit_fmt)
04496 {
04497    int x;
04498    int numchans = 0;
04499    for (x=0;x<IAX_MAX_CALLS;x++) {
04500       ast_mutex_lock(&iaxsl[x]);
04501       if (iaxs[x]) {
04502 #ifdef BRIDGE_OPTIMIZATION
04503          if (iaxs[x]->bridgecallno) {
04504             if (limit_fmt) 
04505                ast_cli(fd, "%-25.25s <NATIVE BRIDGED>",
04506                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
04507             else
04508                ast_cli(fd, "%s <NATIVE BRIDGED>",
04509                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
04510                         } else
04511 #endif
04512          {
04513             int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04514             char *fmt;
04515 #ifdef NEWJB
04516             jb_info jbinfo;
04517 
04518             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04519                jb_getinfo(iaxs[x]->jb, &jbinfo);
04520                localjitter = jbinfo.jitter;
04521                localdelay = jbinfo.current - jbinfo.min;
04522                locallost = jbinfo.frames_lost;
04523                locallosspct = jbinfo.losspct/1000;
04524                localdropped = jbinfo.frames_dropped;
04525                localooo = jbinfo.frames_ooo;
04526             } else {
04527                localjitter = -1;
04528                localdelay = 0;
04529                locallost = -1;
04530                locallosspct = -1;
04531                localdropped = 0;
04532                localooo = -1;
04533             }
04534 #else
04535             localjitter = iaxs[x]->jitter;
04536             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) 
04537             {
04538                localdelay = jitterbufsize(iaxs[x]);
04539                localdropped = iaxs[x]->frames_dropped;
04540             } else {
04541                localdelay = localdropped = 0;
04542             }
04543             locallost = locallosspct = localooo = -1;
04544 #endif
04545             if (limit_fmt)
04546                fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04547             else
04548                fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04549             ast_cli(fd, fmt,
04550                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04551                   iaxs[x]->pingtime,
04552                   localjitter, 
04553                   localdelay,
04554                   locallost,
04555                   locallosspct,
04556                   localdropped,
04557                   localooo,
04558                   iaxs[x]->frames_received/1000,
04559                   iaxs[x]->remote_rr.jitter,
04560                   iaxs[x]->remote_rr.delay,
04561                   iaxs[x]->remote_rr.losscnt,
04562                   iaxs[x]->remote_rr.losspct,
04563                   iaxs[x]->remote_rr.dropped,
04564                   iaxs[x]->remote_rr.ooo,
04565                   iaxs[x]->remote_rr.packets/1000
04566             );
04567          }
04568          numchans++;
04569       }
04570       ast_mutex_unlock(&iaxsl[x]);
04571    }
04572    return numchans;
04573 }
04574 
04575 static int iax2_show_netstats(int fd, int argc, char *argv[])
04576 {
04577    int numchans = 0;
04578    if (argc != 3)
04579       return RESULT_SHOWUSAGE;
04580    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04581    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04582    numchans = ast_cli_netstats(fd, 1);
04583    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04584    return RESULT_SUCCESS;
04585 }
04586 
04587 static int iax2_do_debug(int fd, int argc, char *argv[])
04588 {
04589    if (argc != 2)
04590       return RESULT_SHOWUSAGE;
04591    iaxdebug = 1;
04592    ast_cli(fd, "IAX2 Debugging Enabled\n");
04593    return RESULT_SUCCESS;
04594 }
04595 
04596 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04597 {
04598    if (argc != 3)
04599       return RESULT_SHOWUSAGE;
04600    iaxtrunkdebug = 1;
04601    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04602    return RESULT_SUCCESS;
04603 }
04604 
04605 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04606 {
04607    if (argc != 3)
04608       return RESULT_SHOWUSAGE;
04609 #ifdef NEWJB
04610    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04611 #endif
04612    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04613    return RESULT_SUCCESS;
04614 }
04615 
04616 static int iax2_no_debug(int fd, int argc, char *argv[])
04617 {
04618    if (argc != 3)
04619       return RESULT_SHOWUSAGE;
04620    iaxdebug = 0;
04621    ast_cli(fd, "IAX2 Debugging Disabled\n");
04622    return RESULT_SUCCESS;
04623 }
04624 
04625 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04626 {
04627    if (argc != 4)
04628       return RESULT_SHOWUSAGE;
04629    iaxtrunkdebug = 0;
04630    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04631    return RESULT_SUCCESS;
04632 }
04633 
04634 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04635 {
04636    if (argc != 4)
04637       return RESULT_SHOWUSAGE;
04638 #ifdef NEWJB
04639    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04640    jb_debug_output("\n");
04641 #endif
04642    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04643    return RESULT_SUCCESS;
04644 }
04645 
04646 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04647 {
04648    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04649    int res = -1;
04650    ast_mutex_lock(&iaxsl[callno]);
04651    if (iaxs[callno]) {
04652    /* If there's an outstanding error, return failure now */
04653       if (!iaxs[callno]->error) {
04654          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04655             res = 0;
04656             /* Don't waste bandwidth sending null frames */
04657          else if (f->frametype == AST_FRAME_NULL)
04658             res = 0;
04659          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04660             res = 0;
04661          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04662             res = 0;
04663          else
04664          /* Simple, just queue for transmission */
04665             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04666       } else {
04667          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04668       }
04669    }
04670    /* If it's already gone, just return */
04671    ast_mutex_unlock(&iaxsl[callno]);
04672    return res;
04673 }
04674 
04675 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04676       int now, int transfer, int final)
04677 {
04678    struct ast_frame f;
04679    f.frametype = type;
04680    f.subclass = command;
04681    f.datalen = datalen;
04682    f.samples = 0;
04683    f.mallocd = 0;
04684    f.offset = 0;
04685    f.src = (char *)__FUNCTION__;
04686    f.data = (char *)data;
04687    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04688 }
04689 
04690 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04691 {
04692    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04693 }
04694 
04695 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04696 {
04697    int res;
04698    ast_mutex_lock(&iaxsl[callno]);
04699    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04700    ast_mutex_unlock(&iaxsl[callno]);
04701    return res;
04702 }
04703 
04704 #ifdef BRIDGE_OPTIMIZATION
04705 static int forward_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const char *data, int datalen, int seqno)
04706 {
04707    return __send_command(iaxs[i->bridgecallno], type, command, ts, data, datalen, seqno, 0, 0, 0);
04708 }
04709 #endif
04710 
04711 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)
04712 {
04713    /* It is assumed that the callno has already been locked */
04714    iax2_predestroy_nolock(i->callno);
04715    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04716 }
04717 
04718 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)
04719 {
04720    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04721 }
04722 
04723 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04724 {
04725    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04726 }
04727 
04728 static int apply_context(struct iax2_context *con, char *context)
04729 {
04730    while(con) {
04731       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04732          return -1;
04733       con = con->next;
04734    }
04735    return 0;
04736 }
04737 
04738 
04739 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04740 {
04741    /* Start pessimistic */
04742    int res = -1;
04743    int version = 2;
04744    struct iax2_user *user, *best = NULL;
04745    int bestscore = 0;
04746    int gotcapability = 0;
04747    char iabuf[INET_ADDRSTRLEN];
04748    struct ast_variable *v = NULL, *tmpvar = NULL;
04749 
04750    if (!iaxs[callno])
04751       return res;
04752    if (ies->called_number)
04753       ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten));
04754    if (ies->calling_number) {
04755       ast_shrink_phone_number(ies->calling_number);
04756       ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num));
04757    }
04758    if (ies->calling_name)
04759       ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name));
04760    if (ies->calling_ani)
04761       ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani));
04762    if (ies->dnid)
04763       ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid));
04764    if (ies->called_context)
04765       ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context));
04766    if (ies->language)
04767       ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language));
04768    if (ies->username)
04769       ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username));
04770    if (ies->calling_ton > -1)
04771       iaxs[callno]->calling_ton = ies->calling_ton;
04772    if (ies->calling_tns > -1)
04773       iaxs[callno]->calling_tns = ies->calling_tns;
04774    if (ies->calling_pres > -1)
04775       iaxs[callno]->calling_pres = ies->calling_pres;
04776    if (ies->format)
04777       iaxs[callno]->peerformat = ies->format;
04778    if (ies->adsicpe)
04779       iaxs[callno]->peeradsicpe = ies->adsicpe;
04780    if (ies->capability) {
04781       gotcapability = 1;
04782       iaxs[callno]->peercapability = ies->capability;
04783    } 
04784    if (ies->version)
04785       version = ies->version;
04786 
04787    /* Use provided preferences until told otherwise for actual preferences */
04788    if(ies->codec_prefs) {
04789       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04790       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04791    }
04792 
04793    if (!gotcapability) 
04794       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04795    if (version > IAX_PROTO_VERSION) {
04796       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04797          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version);
04798       return res;
04799    }
04800    ast_mutex_lock(&userl.lock);
04801    /* Search the userlist for a compatible entry, and fill in the rest */
04802    user = userl.users;
04803    while(user) {
04804       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04805          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04806          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04807          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04808               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04809          if (!ast_strlen_zero(iaxs[callno]->username)) {
04810             /* Exact match, stop right now. */
04811             best = user;
04812             break;
04813          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04814             /* No required authentication */
04815             if (user->ha) {
04816                /* There was host authentication and we passed, bonus! */
04817                if (bestscore < 4) {
04818                   bestscore = 4;
04819                   best = user;
04820                }
04821             } else {
04822                /* No host access, but no secret, either, not bad */
04823                if (bestscore < 3) {
04824                   bestscore = 3;
04825                   best = user;
04826                }
04827             }
04828          } else {
04829             if (user->ha) {
04830                /* Authentication, but host access too, eh, it's something.. */
04831                if (bestscore < 2) {
04832                   bestscore = 2;
04833                   best = user;
04834                }
04835             } else {
04836                /* Authentication and no host access...  This is our baseline */
04837                if (bestscore < 1) {
04838                   bestscore = 1;
04839                   best = user;
04840                }
04841             }
04842          }
04843       }
04844       user = user->next;   
04845    }
04846    ast_mutex_unlock(&userl.lock);
04847    user = best;
04848    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04849       user = realtime_user(iaxs[callno]->username);
04850       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
04851           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
04852          destroy_user(user);
04853          user = NULL;
04854       }
04855    }
04856    if (user) {
04857       /* We found our match (use the first) */
04858       /* copy vars */
04859       for (v = user->vars ; v ; v = v->next) {
04860          if((tmpvar = ast_variable_new(v->name, v->value))) {
04861             tmpvar->next = iaxs[callno]->vars; 
04862             iaxs[callno]->vars = tmpvar;
04863          }
04864       }
04865       /* If a max AUTHREQ restriction is in place, activate it */
04866       if (user->maxauthreq > 0)
04867          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04868       iaxs[callno]->prefs = user->prefs;
04869       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04870       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04871       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04872       iaxs[callno]->encmethods = user->encmethods;
04873       /* Store the requested username if not specified */
04874       if (ast_strlen_zero(iaxs[callno]->username))
04875          ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username));
04876       /* Store whether this is a trunked call, too, of course, and move if appropriate */
04877       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04878       iaxs[callno]->capability = user->capability;
04879       /* And use the default context */
04880       if (ast_strlen_zero(iaxs[callno]->context)) {
04881          if (user->contexts)
04882             ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context));
04883          else
04884             ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context));
04885       }
04886       /* And any input keys */
04887       ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys));
04888       /* And the permitted authentication methods */
04889       iaxs[callno]->authmethods = user->authmethods;
04890       /* If they have callerid, override the given caller id.  Always store the ANI */
04891       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
04892          if (ast_test_flag(user, IAX_HASCALLERID)) {
04893             iaxs[callno]->calling_tns = 0;
04894             iaxs[callno]->calling_ton = 0;
04895             ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num));
04896             ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name));
04897             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
04898          }
04899          if (ast_strlen_zero(iaxs[callno]->ani))
04900             ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani));
04901       } else {
04902          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
04903       }
04904       if (!ast_strlen_zero(user->accountcode))
04905          ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode));
04906       if (user->amaflags)
04907          iaxs[callno]->amaflags = user->amaflags;
04908       if (!ast_strlen_zero(user->language))
04909          ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language));
04910       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);  
04911       /* Keep this check last */
04912       if (!ast_strlen_zero(user->dbsecret)) {
04913          char *family, *key=NULL;
04914          family = ast_strdupa(user->dbsecret);
04915          if (family) {
04916             key = strchr(family, '/');
04917             if (key) {
04918                *key = '\0';
04919                key++;
04920             }
04921          }
04922          if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret))) {
04923             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
04924             if (ast_test_flag(user, IAX_TEMPONLY)) {
04925                destroy_user(user);
04926                user = NULL;
04927             }
04928          }
04929       } else
04930          ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)); 
04931       res = 0;
04932    }
04933    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
04934    return res;
04935 }
04936 
04937 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
04938 {
04939    struct ast_iax2_full_hdr fh;
04940    char iabuf[INET_ADDRSTRLEN];
04941    fh.scallno = htons(src | IAX_FLAG_FULL);
04942    fh.dcallno = htons(dst);
04943    fh.ts = 0;
04944    fh.oseqno = 0;
04945    fh.iseqno = 0;
04946    fh.type = AST_FRAME_IAX;
04947    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04948    if (iaxdebug)
04949        iax_showframe(NULL, &fh, 0, sin, 0);
04950 #if 0
04951    if (option_debug)
04952 #endif   
04953       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04954          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
04955    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04956 }
04957 
04958 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
04959 {
04960    /* Select exactly one common encryption if there are any */
04961    p->encmethods &= enc;
04962    if (p->encmethods) {
04963       if (p->encmethods & IAX_ENCRYPT_AES128)
04964          p->encmethods = IAX_ENCRYPT_AES128;
04965       else
04966          p->encmethods = 0;
04967    }
04968 }
04969 
04970 static int authenticate_request(struct chan_iax2_pvt *p)
04971 {
04972    struct iax2_user *user = NULL;
04973    struct iax_ie_data ied;
04974    int res = -1, authreq_restrict = 0;
04975 
04976    memset(&ied, 0, sizeof(ied));
04977 
04978    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04979    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04980       ast_mutex_lock(&userl.lock);
04981       user = userl.users;
04982       while (user) {
04983          if (!strcmp(user->name, p->username)) {
04984             if (user->curauthreq == user->maxauthreq)
04985                authreq_restrict = 1;
04986             else
04987                user->curauthreq++;
04988             break;
04989          }
04990          user = user->next;
04991       }
04992       ast_mutex_unlock(&userl.lock);
04993    }
04994 
04995    /* If the AUTHREQ limit test failed, send back an error */
04996    if (authreq_restrict) {
04997       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04998       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04999       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05000       return 0;
05001    }
05002 
05003    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05004    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05005       snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
05006       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05007    }
05008    if (p->encmethods)
05009       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05010 
05011    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05012 
05013    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05014 
05015    if (p->encmethods)
05016       ast_set_flag(p, IAX_ENCRYPTED);
05017 
05018    return res;
05019 }
05020 
05021 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05022 {
05023    char requeststr[256];
05024    char md5secret[256] = "";
05025    char secret[256] = "";
05026    char rsasecret[256] = "";
05027    int res = -1; 
05028    int x;
05029    struct iax2_user *user = NULL;
05030 
05031    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05032       ast_mutex_lock(&userl.lock);
05033       user = userl.users;
05034       while (user) {
05035          if (!strcmp(user->name, p->username)) {
05036             user->curauthreq--;
05037             break;
05038          }
05039          user = user->next;
05040       }
05041       ast_mutex_unlock(&userl.lock);
05042       ast_clear_flag(p, IAX_MAXAUTHREQ);
05043    }
05044 
05045    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05046       return res;
05047    if (ies->password)
05048       ast_copy_string(secret, ies->password, sizeof(secret));
05049    if (ies->md5_result)
05050       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05051    if (ies->rsa_result)
05052       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05053    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05054       struct ast_key *key;
05055       char *keyn;
05056       char tmpkey[256];
05057       char *stringp=NULL;
05058       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05059       stringp=tmpkey;
05060       keyn = strsep(&stringp, ":");
05061       while(keyn) {
05062          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05063          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05064             res = 0;
05065             break;
05066          } else if (!key)
05067             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05068          keyn = strsep(&stringp, ":");
05069       }
05070    } else if (p->authmethods & IAX_AUTH_MD5) {
05071       struct MD5Context md5;
05072       unsigned char digest[16];
05073       char *tmppw, *stringp;
05074       
05075       tmppw = ast_strdupa(p->secret);
05076       stringp = tmppw;
05077       while((tmppw = strsep(&stringp, ";"))) {
05078          MD5Init(&md5);
05079          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05080          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05081          MD5Final(digest, &md5);
05082          /* If they support md5, authenticate with it.  */
05083          for (x=0;x<16;x++)
05084             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05085          if (!strcasecmp(requeststr, md5secret)) {
05086             res = 0;
05087             break;
05088          }
05089       }
05090    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05091       if (!strcmp(secret, p->secret))
05092          res = 0;
05093    }
05094    return res;
05095 }
05096 
05097 /*! \brief Verify inbound registration */
05098 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05099 {
05100    char requeststr[256] = "";
05101    char peer[256] = "";
05102    char md5secret[256] = "";
05103    char rsasecret[256] = "";
05104    char secret[256] = "";
05105    char iabuf[INET_ADDRSTRLEN];
05106    struct iax2_peer *p;
05107    struct ast_key *key;
05108    char *keyn;
05109    int x;
05110    int expire = 0;
05111 
05112    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05113    iaxs[callno]->peer[0] = '\0';
05114    if (ies->username)
05115       ast_copy_string(peer, ies->username, sizeof(peer));
05116    if (ies->password)
05117       ast_copy_string(secret, ies->password, sizeof(secret));
05118    if (ies->md5_result)
05119       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05120    if (ies->rsa_result)
05121       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05122    if (ies->refresh)
05123       expire = ies->refresh;
05124 
05125    if (ast_strlen_zero(peer)) {
05126       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05127       return -1;
05128    }
05129    /* We release the lock for the call to prevent a deadlock, but it's okay because
05130       only the current thread could possibly make it go away or make changes */
05131    ast_mutex_unlock(&iaxsl[callno]);
05132    /* SLD: first call to lookup peer during registration */
05133    p = find_peer(peer, 1);
05134    ast_mutex_lock(&iaxsl[callno]);
05135 
05136    if (!p) {
05137       if (authdebug)
05138          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05139       return -1;
05140    }
05141 
05142    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05143       if (authdebug)
05144          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05145       if (ast_test_flag(p, IAX_TEMPONLY))
05146          destroy_peer(p);
05147       return -1;
05148    }
05149 
05150    if (!ast_apply_ha(p->ha, sin)) {
05151       if (authdebug)
05152          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
05153       if (ast_test_flag(p, IAX_TEMPONLY))
05154          destroy_peer(p);
05155       return -1;
05156    }
05157    ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret));
05158    ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys));
05159    /* Check secret against what we have on file */
05160    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05161       if (!ast_strlen_zero(p->inkeys)) {
05162          char tmpkeys[256];
05163          char *stringp=NULL;
05164          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05165          stringp=tmpkeys;
05166          keyn = strsep(&stringp, ":");
05167          while(keyn) {
05168             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05169             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05170                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05171                break;
05172             } else if (!key) 
05173                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05174             keyn = strsep(&stringp, ":");
05175          }
05176          if (!keyn) {
05177             if (authdebug)
05178                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05179             if (ast_test_flag(p, IAX_TEMPONLY))
05180                destroy_peer(p);
05181             return -1;
05182          }
05183       } else {
05184          if (authdebug)
05185             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05186          if (ast_test_flag(p, IAX_TEMPONLY))
05187             destroy_peer(p);
05188          return -1;
05189       }
05190    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05191       /* They've provided a plain text password and we support that */
05192       if (strcmp(secret, p->secret)) {
05193          if (authdebug)
05194             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);
05195          if (ast_test_flag(p, IAX_TEMPONLY))
05196             destroy_peer(p);
05197          return -1;
05198       } else
05199          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05200    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05201       struct MD5Context md5;
05202       unsigned char digest[16];
05203       char *tmppw, *stringp;
05204       
05205       tmppw = ast_strdupa(p->secret);
05206       stringp = tmppw;
05207       while((tmppw = strsep(&stringp, ";"))) {
05208          MD5Init(&md5);
05209          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05210          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05211          MD5Final(digest, &md5);
05212          for (x=0;x<16;x++)
05213             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05214          if (!strcasecmp(requeststr, md5secret)) 
05215             break;
05216       }
05217       if (tmppw) {
05218          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05219       } else {
05220          if (authdebug)
05221             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);
05222          if (ast_test_flag(p, IAX_TEMPONLY))
05223             destroy_peer(p);
05224          return -1;
05225       }
05226    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05227       if (authdebug)
05228          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05229       if (ast_test_flag(p, IAX_TEMPONLY))
05230          destroy_peer(p);
05231       return -1;
05232    }
05233    ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer));
05234    /* Choose lowest expiry number */
05235    if (expire && (expire < iaxs[callno]->expiry)) 
05236       iaxs[callno]->expiry = expire;
05237 
05238    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05239 
05240    if (ast_test_flag(p, IAX_TEMPONLY))
05241       destroy_peer(p);
05242    return 0;
05243    
05244 }
05245 
05246 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)
05247 {
05248    int res = -1;
05249    int x;
05250    char iabuf[INET_ADDRSTRLEN];
05251    if (!ast_strlen_zero(keyn)) {
05252       if (!(authmethods & IAX_AUTH_RSA)) {
05253          if (ast_strlen_zero(secret)) 
05254             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));
05255       } else if (ast_strlen_zero(challenge)) {
05256          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05257       } else {
05258          char sig[256];
05259          struct ast_key *key;
05260          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05261          if (!key) {
05262             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05263          } else {
05264             if (ast_sign(key, challenge, sig)) {
05265                ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n");
05266                res = -1;
05267             } else {
05268                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05269                res = 0;
05270             }
05271          }
05272       }
05273    } 
05274    /* Fall back */
05275    if (res && !ast_strlen_zero(secret)) {
05276       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05277          struct MD5Context md5;
05278          unsigned char digest[16];
05279          char digres[128];
05280          MD5Init(&md5);
05281          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05282          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05283          MD5Final(digest, &md5);
05284          /* If they support md5, authenticate with it.  */
05285          for (x=0;x<16;x++)
05286             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05287          if (ecx && dcx)
05288             build_enc_keys(digest, ecx, dcx);
05289          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05290          res = 0;
05291       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05292          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05293          res = 0;
05294       } else
05295          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);
05296    }
05297    return res;
05298 }
05299 
05300 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey)
05301 {
05302    struct iax2_peer *peer;
05303    /* Start pessimistic */
05304    int res = -1;
05305    int authmethods = 0;
05306    struct iax_ie_data ied;
05307    
05308    memset(&ied, 0, sizeof(ied));
05309    
05310    if (ies->username)
05311       ast_copy_string(p->username, ies->username, sizeof(p->username));
05312    if (ies->challenge)
05313       ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge));
05314    if (ies->authmethods)
05315       authmethods = ies->authmethods;
05316    if (authmethods & IAX_AUTH_MD5)
05317       merge_encryption(p, ies->encmethods);
05318    else
05319       p->encmethods = 0;
05320 
05321    /* Check for override RSA authentication first */
05322    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05323       /* Normal password authentication */
05324       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05325    } else {
05326       ast_mutex_lock(&peerl.lock);
05327       peer = peerl.peers;
05328       while(peer) {
05329          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05330                         /* No peer specified at our end, or this is the peer */
05331           && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05332                         /* No username specified in peer rule, or this is the right username */
05333           && (!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)))
05334                         /* No specified host, or this is our host */
05335          ) {
05336             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05337             if (!res)
05338                break;   
05339          }
05340          peer = peer->next;
05341       }
05342       ast_mutex_unlock(&peerl.lock);
05343       if (!peer) {
05344          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05345             that we're trying to authenticate *to* a realtime peer */
05346          if ((peer = realtime_peer(p->peer, NULL))) {
05347             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05348             if (ast_test_flag(peer, IAX_TEMPONLY))
05349                destroy_peer(peer);
05350          }
05351       }
05352    }
05353    if (ies->encmethods)
05354       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05355    if (!res)
05356       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05357    return res;
05358 }
05359 
05360 static int iax2_do_register(struct iax2_registry *reg);
05361 
05362 static int iax2_do_register_s(void *data)
05363 {
05364    struct iax2_registry *reg = data;
05365    reg->expire = -1;
05366    iax2_do_register(reg);
05367    return 0;
05368 }
05369 
05370 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05371 {
05372    int newcall = 0;
05373    char newip[256];
05374    struct iax_ie_data ied;
05375    struct sockaddr_in new;
05376    
05377    
05378    memset(&ied, 0, sizeof(ied));
05379    if (ies->apparent_addr)
05380       bcopy(ies->apparent_addr, &new, sizeof(new));
05381    if (ies->callno)
05382       newcall = ies->callno;
05383    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05384       ast_log(LOG_WARNING, "Invalid transfer request\n");
05385       return -1;
05386    }
05387    pvt->transfercallno = newcall;
05388    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05389    inet_aton(newip, &pvt->transfer.sin_addr);
05390    pvt->transfer.sin_family = AF_INET;
05391    pvt->transferring = TRANSFER_BEGIN;
05392    pvt->transferid = ies->transferid;
05393    if (ies->transferid)
05394       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05395    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05396    return 0; 
05397 }
05398 
05399 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05400 {
05401    char exten[256] = "";
05402    int status = CACHE_FLAG_UNKNOWN;
05403    int expiry = iaxdefaultdpcache;
05404    int x;
05405    int matchmore = 0;
05406    struct iax2_dpcache *dp, *prev;
05407    
05408    if (ies->called_number)
05409       ast_copy_string(exten, ies->called_number, sizeof(exten));
05410 
05411    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05412       status = CACHE_FLAG_EXISTS;
05413    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05414       status = CACHE_FLAG_CANEXIST;
05415    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05416       status = CACHE_FLAG_NONEXISTENT;
05417 
05418    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05419       /* Don't really do anything with this */
05420    }
05421    if (ies->refresh)
05422       expiry = ies->refresh;
05423    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05424       matchmore = CACHE_FLAG_MATCHMORE;
05425    ast_mutex_lock(&dpcache_lock);
05426    prev = NULL;
05427    dp = pvt->dpentries;
05428    while(dp) {
05429       if (!strcmp(dp->exten, exten)) {
05430          /* Let them go */
05431          if (prev)
05432             prev->peer = dp->peer;
05433          else
05434             pvt->dpentries = dp->peer;
05435          dp->peer = NULL;
05436          dp->callno = 0;
05437          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05438          if (dp->flags & CACHE_FLAG_PENDING) {
05439             dp->flags &= ~CACHE_FLAG_PENDING;
05440             dp->flags |= status;
05441             dp->flags |= matchmore;
05442          }
05443          /* Wake up waiters */
05444          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05445             if (dp->waiters[x] > -1)
05446                write(dp->waiters[x], "asdf", 4);
05447       }
05448       prev = dp;
05449       dp = dp->peer;
05450    }
05451    ast_mutex_unlock(&dpcache_lock);
05452    return 0;
05453 }
05454 
05455 static int complete_transfer(int callno, struct iax_ies *ies)
05456 {
05457    int peercallno = 0;
05458    struct chan_iax2_pvt *pvt = iaxs[callno];
05459    struct iax_frame *cur;
05460 
05461    if (ies->callno)
05462       peercallno = ies->callno;
05463 
05464    if (peercallno < 1) {
05465       ast_log(LOG_WARNING, "Invalid transfer request\n");
05466       return -1;
05467    }
05468    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05469    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05470    /* Reset sequence numbers */
05471    pvt->oseqno = 0;
05472    pvt->rseqno = 0;
05473    pvt->iseqno = 0;
05474    pvt->aseqno = 0;
05475    pvt->peercallno = peercallno;
05476    pvt->transferring = TRANSFER_NONE;
05477    pvt->svoiceformat = -1;
05478    pvt->voiceformat = 0;
05479    pvt->svideoformat = -1;
05480    pvt->videoformat = 0;
05481    pvt->transfercallno = -1;
05482    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05483    memset(&pvt->offset, 0, sizeof(pvt->offset));
05484 #ifdef NEWJB
05485    {  /* reset jitterbuffer */
05486          jb_frame frame;
05487                while(jb_getall(pvt->jb,&frame) == JB_OK)
05488                   iax2_frame_free(frame.data);
05489 
05490       jb_reset(pvt->jb);
05491    }
05492 #else
05493    memset(&pvt->history, 0, sizeof(pvt->history));
05494    pvt->jitterbuffer = 0;
05495    pvt->jitter = 0;
05496    pvt->historicjitter = 0;
05497 #endif
05498    pvt->lag = 0;
05499    pvt->last = 0;
05500    pvt->lastsent = 0;
05501    pvt->nextpred = 0;
05502    pvt->pingtime = DEFAULT_RETRY_TIME;
05503    ast_mutex_lock(&iaxq.lock);
05504    for (cur = iaxq.head; cur ; cur = cur->next) {
05505       /* We must cancel any packets that would have been transmitted
05506          because now we're talking to someone new.  It's okay, they
05507          were transmitted to someone that didn't care anyway. */
05508       if (callno == cur->callno) 
05509          cur->retries = -1;
05510    }
05511    ast_mutex_unlock(&iaxq.lock);
05512    return 0; 
05513 }
05514 
05515 /*! \brief Acknowledgment received for OUR registration */
05516 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05517 {
05518    struct iax2_registry *reg;
05519    /* Start pessimistic */
05520    char peer[256] = "";
05521    char msgstatus[40];
05522    int refresh = 0;
05523    char ourip[256] = "<Unspecified>";
05524    struct sockaddr_in oldus;
05525    struct sockaddr_in us;
05526    char iabuf[INET_ADDRSTRLEN];
05527    int oldmsgs;
05528 
05529    memset(&us, 0, sizeof(us));
05530    if (ies->apparent_addr)
05531       bcopy(ies->apparent_addr, &us, sizeof(us));
05532    if (ies->username)
05533       ast_copy_string(peer, ies->username, sizeof(peer));
05534    if (ies->refresh)
05535       refresh = ies->refresh;
05536    if (ies->calling_number) {
05537       /* We don't do anything with it really, but maybe we should */
05538    }
05539    reg = iaxs[callno]->reg;
05540    if (!reg) {
05541       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05542       return -1;
05543    }
05544    memcpy(&oldus, &reg->us, sizeof(oldus));
05545    oldmsgs = reg->messages;
05546    if (inaddrcmp(&reg->addr, sin)) {
05547       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05548       return -1;
05549    }
05550    memcpy(&reg->us, &us, sizeof(reg->us));
05551    reg->messages = ies->msgcount;
05552    /* always refresh the registration at the interval requested by the server
05553       we are registering to
05554    */
05555    reg->refresh = refresh;
05556    if (reg->expire > -1)
05557       ast_sched_del(sched, reg->expire);
05558    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05559    if ((inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
05560       if (reg->messages > 65534)
05561          snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
05562       else if (reg->messages > 1)
05563          snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
05564       else if (reg->messages > 0)
05565          snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
05566       else
05567          snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05568       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
05569       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);
05570       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));
05571    }
05572    reg->regstate = REG_STATE_REGISTERED;
05573    return 0;
05574 }
05575 
05576 static int iax2_register(char *value, int lineno)
05577 {
05578    struct iax2_registry *reg;
05579    char copy[256];
05580    char *username, *hostname, *secret;
05581    char *porta;
05582    char *stringp=NULL;
05583    
05584    struct ast_hostent ahp; struct hostent *hp;
05585    if (!value)
05586       return -1;
05587    ast_copy_string(copy, value, sizeof(copy));
05588    stringp=copy;
05589    username = strsep(&stringp, "@");
05590    hostname = strsep(&stringp, "@");
05591    if (!hostname) {
05592       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
05593       return -1;
05594    }
05595    stringp=username;
05596    username = strsep(&stringp, ":");
05597    secret = strsep(&stringp, ":");
05598    stringp=hostname;
05599    hostname = strsep(&stringp, ":");
05600    porta = strsep(&stringp, ":");
05601    
05602    if (porta && !atoi(porta)) {
05603       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05604       return -1;
05605    }
05606    hp = ast_gethostbyname(hostname, &ahp);
05607    if (!hp) {
05608       ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
05609       return -1;
05610    }
05611    reg = malloc(sizeof(struct iax2_registry));
05612    if (reg) {
05613       memset(reg, 0, sizeof(struct iax2_registry));
05614       ast_copy_string(reg->username, username, sizeof(reg->username));
05615       if (secret)
05616          ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05617       reg->expire = -1;
05618       reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05619       reg->addr.sin_family = AF_INET;
05620       memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
05621       reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05622       reg->next = registrations;
05623       reg->callno = 0;
05624       registrations = reg;
05625    } else {
05626       ast_log(LOG_ERROR, "Out of memory\n");
05627       return -1;
05628    }
05629    return 0;
05630 }
05631 
05632 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05633 {
05634    char multi[256];
05635    char *stringp, *ext;
05636    if (!ast_strlen_zero(regcontext)) {
05637       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
05638       stringp = multi;
05639       while((ext = strsep(&stringp, "&"))) {
05640          if (onoff) {
05641             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05642                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype);
05643          } else
05644             ast_context_remove_extension(regcontext, ext, 1, NULL);
05645       }
05646    }
05647 }
05648 static void prune_peers(void);
05649 
05650 static int expire_registry(void *data)
05651 {
05652    struct iax2_peer *p = data;
05653 
05654    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05655    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05656       realtime_update_peer(p->name, &p->addr, 0);
05657    /* Reset the address */
05658    memset(&p->addr, 0, sizeof(p->addr));
05659    /* Reset expire notice */
05660    p->expire = -1;
05661    /* Reset expiry value */
05662    p->expiry = min_reg_expire;
05663    if (!ast_test_flag(p, IAX_TEMPONLY))
05664       ast_db_del("IAX/Registry", p->name);
05665    register_peer_exten(p, 0);
05666    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05667    if (iax2_regfunk)
05668       iax2_regfunk(p->name, 0);
05669 
05670    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05671       ast_set_flag(p, IAX_DELME);
05672       prune_peers();
05673    }
05674 
05675    return 0;
05676 }
05677 
05678 
05679 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05680 
05681 static void reg_source_db(struct iax2_peer *p)
05682 {
05683    char data[80];
05684    struct in_addr in;
05685    char iabuf[INET_ADDRSTRLEN];
05686    char *c, *d;
05687    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05688       c = strchr(data, ':');
05689       if (c) {
05690          *c = '\0';
05691          c++;
05692          if (inet_aton(data, &in)) {
05693             d = strchr(c, ':');
05694             if (d) {
05695                *d = '\0';
05696                d++;
05697                if (option_verbose > 2)
05698                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05699                   ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d));
05700                iax2_poke_peer(p, 0);
05701                p->expiry = atoi(d);
05702                memset(&p->addr, 0, sizeof(p->addr));
05703                p->addr.sin_family = AF_INET;
05704                p->addr.sin_addr = in;
05705                p->addr.sin_port = htons(atoi(c));
05706                if (p->expire > -1)
05707                   ast_sched_del(sched, p->expire);
05708                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05709                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05710                if (iax2_regfunk)
05711                   iax2_regfunk(p->name, 1);
05712                register_peer_exten(p, 1);
05713             }              
05714                
05715          }
05716       }
05717    }
05718 }
05719 
05720 static int update_registry(char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05721 {
05722    /* Called from IAX thread only, with proper iaxsl lock */
05723    struct iax_ie_data ied;
05724    struct iax2_peer *p;
05725    int msgcount;
05726    char data[80];
05727    char iabuf[INET_ADDRSTRLEN];
05728    int version;
05729 
05730    memset(&ied, 0, sizeof(ied));
05731 
05732    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05733    if (!(p = find_peer(name, 1))) {
05734       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05735       return -1;
05736    }
05737 
05738    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05739       if (sin->sin_addr.s_addr) {
05740          time_t nowtime;
05741          time(&nowtime);
05742          realtime_update_peer(name, sin, nowtime);
05743       } else
05744          realtime_update_peer(name, sin, 0);
05745    }
05746    if (inaddrcmp(&p->addr, sin)) {
05747       if (iax2_regfunk)
05748          iax2_regfunk(p->name, 1);
05749       /* Stash the IP address from which they registered */
05750       memcpy(&p->addr, sin, sizeof(p->addr));
05751       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05752       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05753          ast_db_put("IAX/Registry", p->name, data);
05754          if  (option_verbose > 2)
05755             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05756                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
05757          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05758          register_peer_exten(p, 1);
05759          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05760       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05761          if  (option_verbose > 2)
05762             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05763                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05764          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05765          register_peer_exten(p, 0);
05766          ast_db_del("IAX/Registry", p->name);
05767          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05768       }
05769       /* Update the host */
05770       /* Verify that the host is really there */
05771       iax2_poke_peer(p, callno);
05772    }     
05773    /* Store socket fd */
05774    p->sockfd = fd;
05775    /* Setup the expiry */
05776    if (p->expire > -1)
05777       ast_sched_del(sched, p->expire);
05778    /* treat an unspecified refresh interval as the minimum */
05779    if (!refresh)
05780       refresh = min_reg_expire;
05781    if (refresh > max_reg_expire) {
05782       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05783          p->name, max_reg_expire, refresh);
05784       p->expiry = max_reg_expire;
05785    } else if (refresh < min_reg_expire) {
05786       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05787          p->name, min_reg_expire, refresh);
05788       p->expiry = min_reg_expire;
05789    } else {
05790       p->expiry = refresh;
05791    }
05792    if (p->expiry && sin->sin_addr.s_addr)
05793       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05794    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05795    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05796    if (sin->sin_addr.s_addr) {
05797       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05798       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05799       if (!ast_strlen_zero(p->mailbox)) {
05800          if (ast_test_flag(p, IAX_MESSAGEDETAIL)) {
05801             int new, old;
05802             ast_app_messagecount(p->mailbox, &new, &old);
05803             if (new > 255)
05804                new = 255;
05805             if (old > 255)
05806                old = 255;
05807             msgcount = (old << 8) | new;
05808          } else {
05809             msgcount = ast_app_has_voicemail(p->mailbox, NULL);
05810             if (msgcount)
05811                msgcount = 65535;
05812          }
05813          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05814       }
05815       if (ast_test_flag(p, IAX_HASCALLERID)) {
05816          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05817          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05818       }
05819    }
05820    version = iax_check_version(devtype);
05821    if (version) 
05822       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05823    if (ast_test_flag(p, IAX_TEMPONLY))
05824       destroy_peer(p);
05825    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05826 }
05827 
05828 static int registry_authrequest(char *name, int callno)
05829 {
05830    struct iax_ie_data ied;
05831    struct iax2_peer *p;
05832    /* SLD: third call to find_peer in registration */
05833    p = find_peer(name, 1);
05834    if (p) {
05835       memset(&ied, 0, sizeof(ied));
05836       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05837       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05838          /* Build the challenge */
05839          snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand());
05840          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05841       }
05842       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05843       if (ast_test_flag(p, IAX_TEMPONLY))
05844          destroy_peer(p);
05845       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05846    } 
05847    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05848    return 0;
05849 }
05850 
05851 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
05852 {
05853    struct iax2_registry *reg;
05854    /* Start pessimistic */
05855    struct iax_ie_data ied;
05856    char peer[256] = "";
05857    char iabuf[INET_ADDRSTRLEN];
05858    char challenge[256] = "";
05859    int res;
05860    int authmethods = 0;
05861    if (ies->authmethods)
05862       authmethods = ies->authmethods;
05863    if (ies->username)
05864       ast_copy_string(peer, ies->username, sizeof(peer));
05865    if (ies->challenge)
05866       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05867    memset(&ied, 0, sizeof(ied));
05868    reg = iaxs[callno]->reg;
05869    if (reg) {
05870          if (inaddrcmp(&reg->addr, sin)) {
05871             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05872             return -1;
05873          }
05874          if (ast_strlen_zero(reg->secret)) {
05875             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05876             reg->regstate = REG_STATE_NOAUTH;
05877             return -1;
05878          }
05879          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05880          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05881          if (reg->secret[0] == '[') {
05882             char tmpkey[256];
05883             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05884             tmpkey[strlen(tmpkey) - 1] = '\0';
05885             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05886          } else
05887             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05888          if (!res) {
05889             reg->regstate = REG_STATE_AUTHSENT;
05890             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05891          } else
05892             return -1;
05893          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05894    } else   
05895       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05896    return -1;
05897 }
05898 
05899 static int stop_stuff(int callno)
05900 {
05901       if (iaxs[callno]->lagid > -1)
05902          ast_sched_del(sched, iaxs[callno]->lagid);
05903       iaxs[callno]->lagid = -1;
05904       if (iaxs[callno]->pingid > -1)
05905          ast_sched_del(sched, iaxs[callno]->pingid);
05906       iaxs[callno]->pingid = -1;
05907       if (iaxs[callno]->autoid > -1)
05908          ast_sched_del(sched, iaxs[callno]->autoid);
05909       iaxs[callno]->autoid = -1;
05910       if (iaxs[callno]->initid > -1)
05911          ast_sched_del(sched, iaxs[callno]->initid);
05912       iaxs[callno]->initid = -1;
05913       if (iaxs[callno]->authid > -1)
05914          ast_sched_del(sched, iaxs[callno]->authid);
05915       iaxs[callno]->authid = -1;
05916 #ifdef NEWJB
05917       if (iaxs[callno]->jbid > -1)
05918          ast_sched_del(sched, iaxs[callno]->jbid);
05919       iaxs[callno]->jbid = -1;
05920 #endif
05921       return 0;
05922 }
05923 
05924 static int auth_reject(void *nothing)
05925 {
05926    /* Called from IAX thread only, without iaxs lock */
05927    int callno = (int)(long)(nothing);
05928    struct iax_ie_data ied;
05929    ast_mutex_lock(&iaxsl[callno]);
05930    if (iaxs[callno]) {
05931       iaxs[callno]->authid = -1;
05932       memset(&ied, 0, sizeof(ied));
05933       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05934          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05935          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05936       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05937          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05938          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05939       }
05940       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05941    }
05942    ast_mutex_unlock(&iaxsl[callno]);
05943    return 0;
05944 }
05945 
05946 static int auth_fail(int callno, int failcode)
05947 {
05948    /* Schedule sending the authentication failure in one second, to prevent
05949       guessing */
05950    ast_mutex_lock(&iaxsl[callno]);
05951    iaxs[callno]->authfail = failcode;
05952    if (delayreject) {
05953       if (iaxs[callno]->authid > -1)
05954          ast_sched_del(sched, iaxs[callno]->authid);
05955       iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05956    } else
05957       auth_reject((void *)(long)callno);
05958    ast_mutex_unlock(&iaxsl[callno]);
05959    return 0;
05960 }
05961 
05962 static int auto_hangup(void *nothing)
05963 {
05964    /* Called from IAX thread only, without iaxs lock */
05965    int callno = (int)(long)(nothing);
05966    struct iax_ie_data ied;
05967    ast_mutex_lock(&iaxsl[callno]);
05968    if (iaxs[callno]) {
05969       iaxs[callno]->autoid = -1;
05970       memset(&ied, 0, sizeof(ied));
05971       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05972       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05973       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05974    }
05975    ast_mutex_unlock(&iaxsl[callno]);
05976    return 0;
05977 }
05978 
05979 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
05980 {
05981    struct iax_ie_data ied;
05982    /* Auto-hangup with 30 seconds of inactivity */
05983    if (iaxs[callno]->autoid > -1)
05984       ast_sched_del(sched, iaxs[callno]->autoid);
05985    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05986    memset(&ied, 0, sizeof(ied));
05987    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05988    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05989    dp->flags |= CACHE_FLAG_TRANSMITTED;
05990 }
05991 
05992 static int iax2_vnak(int callno)
05993 {
05994    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05995 }
05996 
05997 static void vnak_retransmit(int callno, int last)
05998 {
05999    struct iax_frame *f;
06000    ast_mutex_lock(&iaxq.lock);
06001    f = iaxq.head;
06002    while(f) {
06003       /* Send a copy immediately */
06004       if ((f->callno == callno) && iaxs[f->callno] &&
06005          (f->oseqno >= last)) {
06006          send_packet(f);
06007       }
06008       f = f->next;
06009    }
06010    ast_mutex_unlock(&iaxq.lock);
06011 }
06012 
06013 static int iax2_poke_peer_s(void *data)
06014 {
06015    struct iax2_peer *peer = data;
06016    peer->pokeexpire = -1;
06017    iax2_poke_peer(peer, 0);
06018    return 0;
06019 }
06020 
06021 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06022 {
06023    int res = 0;
06024    struct iax_frame *fr;
06025    struct ast_iax2_meta_hdr *meta;
06026    struct ast_iax2_meta_trunk_hdr *mth;
06027    int calls = 0;
06028    
06029    /* Point to frame */
06030    fr = (struct iax_frame *)tpeer->trunkdata;
06031    /* Point to meta data */
06032    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06033    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06034    if (tpeer->trunkdatalen) {
06035       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06036       meta->zeros = 0;
06037       meta->metacmd = IAX_META_TRUNK;
06038       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06039          meta->cmddata = IAX_META_TRUNK_MINI;
06040       else
06041          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06042       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06043       /* And the rest of the ast_iax2 header */
06044       fr->direction = DIRECTION_OUTGRESS;
06045       fr->retrans = -1;
06046       fr->transfer = 0;
06047       /* Any appropriate call will do */
06048       fr->data = fr->afdata;
06049       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06050       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06051       calls = tpeer->calls;
06052 #if 0
06053       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));
06054 #endif      
06055       /* Reset transmit trunk side data */
06056       tpeer->trunkdatalen = 0;
06057       tpeer->calls = 0;
06058    }
06059    if (res < 0)
06060       return res;
06061    return calls;
06062 }
06063 
06064 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06065 {
06066    /* Drop when trunk is about 5 seconds idle */
06067    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06068       return 1;
06069    return 0;
06070 }
06071 
06072 static int timing_read(int *id, int fd, short events, void *cbdata)
06073 {
06074    char buf[1024];
06075    int res;
06076    char iabuf[INET_ADDRSTRLEN];
06077    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06078    int processed = 0;
06079    int totalcalls = 0;
06080 #ifdef ZT_TIMERACK
06081    int x = 1;
06082 #endif
06083    struct timeval now;
06084    if (iaxtrunkdebug)
06085       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06086    gettimeofday(&now, NULL);
06087    if (events & AST_IO_PRI) {
06088 #ifdef ZT_TIMERACK
06089       /* Great, this is a timing interface, just call the ioctl */
06090       if (ioctl(fd, ZT_TIMERACK, &x)) 
06091          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06092       res = 0;
06093 #endif      
06094    } else {
06095       /* Read and ignore from the pseudo channel for timing */
06096       res = read(fd, buf, sizeof(buf));
06097       if (res < 1) {
06098          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06099          ast_mutex_unlock(&peerl.lock);
06100          return 1;
06101       }
06102    }
06103    /* For each peer that supports trunking... */
06104    ast_mutex_lock(&tpeerlock);
06105    tpeer = tpeers;
06106    while(tpeer) {
06107       processed++;
06108       res = 0;
06109       ast_mutex_lock(&tpeer->lock);
06110       /* We can drop a single tpeer per pass.  That makes all this logic
06111          substantially easier */
06112       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06113          /* Take it out of the list, but don't free it yet, because it
06114             could be in use */
06115          if (prev)
06116             prev->next = tpeer->next;
06117          else
06118             tpeers = tpeer->next;
06119          drop = tpeer;
06120       } else {
06121          res = send_trunk(tpeer, &now);
06122          if (iaxtrunkdebug)
06123             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);
06124       }     
06125       totalcalls += res;   
06126       res = 0;
06127       ast_mutex_unlock(&tpeer->lock);
06128       prev = tpeer;
06129       tpeer = tpeer->next;
06130    }
06131    ast_mutex_unlock(&tpeerlock);
06132    if (drop) {
06133       ast_mutex_lock(&drop->lock);
06134       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06135          because by the time they could get tpeerlock, we've already grabbed it */
06136       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));
06137       free(drop->trunkdata);
06138       ast_mutex_unlock(&drop->lock);
06139       ast_mutex_destroy(&drop->lock);
06140       free(drop);
06141       
06142    }
06143    if (iaxtrunkdebug)
06144       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06145    iaxtrunkdebug =0;
06146    return 1;
06147 }
06148 
06149 struct dpreq_data {
06150    int callno;
06151    char context[AST_MAX_EXTENSION];
06152    char callednum[AST_MAX_EXTENSION];
06153    char *callerid;
06154 };
06155 
06156 static void dp_lookup(int callno, char *context, char *callednum, char *callerid, int skiplock)
06157 {
06158    unsigned short dpstatus = 0;
06159    struct iax_ie_data ied1;
06160    int mm;
06161 
06162    memset(&ied1, 0, sizeof(ied1));
06163    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06164    /* Must be started */
06165    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06166       dpstatus = IAX_DPSTATUS_EXISTS;
06167    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06168       dpstatus = IAX_DPSTATUS_CANEXIST;
06169    } else {
06170       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06171    }
06172    if (ast_ignore_pattern(context, callednum))
06173       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06174    if (mm)
06175       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06176    if (!skiplock)
06177       ast_mutex_lock(&iaxsl[callno]);
06178    if (iaxs[callno]) {
06179       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06180       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06181       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06182       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06183    }
06184    if (!skiplock)
06185       ast_mutex_unlock(&iaxsl[callno]);
06186 }
06187 
06188 static void *dp_lookup_thread(void *data)
06189 {
06190    /* Look up for dpreq */
06191    struct dpreq_data *dpr = data;
06192    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06193    if (dpr->callerid)
06194       free(dpr->callerid);
06195    free(dpr);
06196    return NULL;
06197 }
06198 
06199 static void spawn_dp_lookup(int callno, char *context, char *callednum, char *callerid)
06200 {
06201    pthread_t newthread;
06202    struct dpreq_data *dpr;
06203    dpr = malloc(sizeof(struct dpreq_data));
06204    if (dpr) {
06205       memset(dpr, 0, sizeof(struct dpreq_data));
06206       dpr->callno = callno;
06207       ast_copy_string(dpr->context, context, sizeof(dpr->context));
06208       ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06209       if (callerid)
06210          dpr->callerid = strdup(callerid);
06211       if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) {
06212          ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06213       }
06214    } else
06215       ast_log(LOG_WARNING, "Out of memory!\n");
06216 }
06217 
06218 struct iax_dual {
06219    struct ast_channel *chan1;
06220    struct ast_channel *chan2;
06221 };
06222 
06223 static void *iax_park_thread(void *stuff)
06224 {
06225    struct ast_channel *chan1, *chan2;
06226    struct iax_dual *d;
06227    struct ast_frame *f;
06228    int ext;
06229    int res;
06230    d = stuff;
06231    chan1 = d->chan1;
06232    chan2 = d->chan2;
06233    free(d);
06234    f = ast_read(chan1);
06235    if (f)
06236       ast_frfree(f);
06237    res = ast_park_call(chan1, chan2, 0, &ext);
06238    ast_hangup(chan2);
06239    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06240    return NULL;
06241 }
06242 
06243 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06244 {
06245    struct iax_dual *d;
06246    struct ast_channel *chan1m, *chan2m;
06247    pthread_t th;
06248    chan1m = ast_channel_alloc(0);
06249    chan2m = ast_channel_alloc(0);
06250    if (chan2m && chan1m) {
06251       snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
06252       /* Make formats okay */
06253       chan1m->readformat = chan1->readformat;
06254       chan1m->writeformat = chan1->writeformat;
06255       ast_channel_masquerade(chan1m, chan1);
06256       /* Setup the extensions and such */
06257       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06258       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06259       chan1m->priority = chan1->priority;
06260       
06261       /* We make a clone of the peer channel too, so we can play
06262          back the announcement */
06263       snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name);
06264       /* Make formats okay */
06265       chan2m->readformat = chan2->readformat;
06266       chan2m->writeformat = chan2->writeformat;
06267       ast_channel_masquerade(chan2m, chan2);
06268       /* Setup the extensions and such */
06269       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06270       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06271       chan2m->priority = chan2->priority;
06272       if (ast_do_masquerade(chan2m)) {
06273          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06274          ast_hangup(chan2m);
06275          return -1;
06276       }
06277    } else {
06278       if (chan1m)
06279          ast_hangup(chan1m);
06280       if (chan2m)
06281          ast_hangup(chan2m);
06282       return -1;
06283    }
06284    d = malloc(sizeof(struct iax_dual));
06285    if (d) {
06286       memset(d, 0, sizeof(*d));
06287       d->chan1 = chan1m;
06288       d->chan2 = chan2m;
06289       if (!ast_pthread_create(&th, NULL, iax_park_thread, d))
06290          return 0;
06291       free(d);
06292    }
06293    return -1;
06294 }
06295 
06296 
06297 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06298 
06299 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06300 {
06301    unsigned int ourver;
06302    char rsi[80];
06303    snprintf(rsi, sizeof(rsi), "si-%s", si);
06304    if (iax_provision_version(&ourver, rsi, 1))
06305       return 0;
06306    if (option_debug)
06307       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06308    if (ourver != ver) 
06309       iax2_provision(sin, sockfd, NULL, rsi, 1);
06310    return 0;
06311 }
06312 
06313 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06314 {
06315 #ifdef NEWJB
06316    jb_info stats;
06317    jb_getinfo(pvt->jb, &stats);
06318    
06319    memset(iep, 0, sizeof(*iep));
06320 
06321    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06322    if(stats.frames_in == 0) stats.frames_in = 1;
06323    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06324    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06325    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06326    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06327    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06328 #else
06329    memset(iep, 0, sizeof(*iep));
06330    iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter);
06331    iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received);
06332    if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 
06333       iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0);
06334    else
06335       iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min);
06336    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped);
06337    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */
06338    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
06339 #endif
06340 }
06341 
06342 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06343 {
06344    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06345    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06346    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06347    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06348    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06349    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06350    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06351 }
06352 
06353 static int socket_read(int *id, int fd, short events, void *cbdata)
06354 {
06355    struct sockaddr_in sin;
06356    int res;
06357    int updatehistory=1;
06358    int new = NEW_PREVENT;
06359    unsigned char buf[4096]; 
06360    void *ptr;
06361    socklen_t len = sizeof(sin);
06362    int dcallno = 0;
06363    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
06364    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
06365    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf;
06366    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf;
06367    struct ast_iax2_meta_trunk_hdr *mth;
06368    struct ast_iax2_meta_trunk_entry *mte;
06369    struct ast_iax2_meta_trunk_mini *mtm;
06370    struct iax_frame *fr;
06371    struct iax_frame *cur;
06372    char iabuf[INET_ADDRSTRLEN];
06373    struct ast_frame f;
06374    struct ast_channel *c;
06375    struct iax2_dpcache *dp;
06376    struct iax2_peer *peer;
06377    struct iax2_trunk_peer *tpeer;
06378    struct timeval rxtrunktime;
06379    struct iax_ies ies;
06380    struct iax_ie_data ied0, ied1;
06381    int format;
06382    int exists;
06383    int minivid = 0;
06384    unsigned int ts;
06385    char empty[32]="";      /* Safety measure */
06386    struct iax_frame *duped_fr;
06387    char host_pref_buf[128];
06388    char caller_pref_buf[128];
06389    struct ast_codec_pref pref;
06390    char *using_prefs = "mine";
06391 
06392    /* allocate an iax_frame with 4096 bytes of data buffer */
06393    fr = alloca(sizeof(*fr) + 4096);
06394    fr->callno = 0;
06395    
06396    res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len);
06397    if (res < 0) {
06398       if (errno != ECONNREFUSED)
06399          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06400       handle_error();
06401       return 1;
06402    }
06403    if(test_losspct) { /* simulate random loss condition */
06404       if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct) 
06405          return 1;
06406  
06407    }
06408    if (res < sizeof(*mh)) {
06409       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06410       return 1;
06411    }
06412    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06413       if (res < sizeof(*vh)) {
06414          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));
06415          return 1;
06416       }
06417 
06418       /* This is a video frame, get call number */
06419       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06420       minivid = 1;
06421    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06422       unsigned char metatype;
06423 
06424       if (res < sizeof(*meta)) {
06425          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));
06426          return 1;
06427       }
06428 
06429       /* This is a meta header */
06430       switch(meta->metacmd) {
06431       case IAX_META_TRUNK:
06432          if (res < (sizeof(*meta) + sizeof(*mth))) {
06433             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06434                sizeof(*meta) + sizeof(*mth));
06435             return 1;
06436          }
06437          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06438          ts = ntohl(mth->ts);
06439          metatype = meta->cmddata;
06440          res -= (sizeof(*meta) + sizeof(*mth));
06441          ptr = mth->data;
06442          tpeer = find_tpeer(&sin, fd);
06443          if (!tpeer) {
06444             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));
06445             return 1;
06446          }
06447          tpeer->trunkact = ast_tvnow();
06448          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06449             tpeer->rxtrunktime = tpeer->trunkact;
06450          rxtrunktime = tpeer->rxtrunktime;
06451          ast_mutex_unlock(&tpeer->lock);
06452          while(res >= sizeof(*mte)) {
06453             /* Process channels */
06454             unsigned short callno, trunked_ts, len;
06455 
06456             if (metatype == IAX_META_TRUNK_MINI) {
06457                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06458                ptr += sizeof(*mtm);
06459                res -= sizeof(*mtm);
06460                len = ntohs(mtm->len);
06461                callno = ntohs(mtm->mini.callno);
06462                trunked_ts = ntohs(mtm->mini.ts);
06463             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06464                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06465                ptr += sizeof(*mte);
06466                res -= sizeof(*mte);
06467                len = ntohs(mte->len);
06468                callno = ntohs(mte->callno);
06469                trunked_ts = 0;
06470             } else {
06471                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));
06472                break;
06473             }
06474             /* Stop if we don't have enough data */
06475             if (len > res)
06476                break;
06477             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06478             if (fr->callno) {
06479                ast_mutex_lock(&iaxsl[fr->callno]);
06480                /* If it's a valid call, deliver the contents.  If not, we
06481                   drop it, since we don't have a scallno to use for an INVAL */
06482                /* Process as a mini frame */
06483                f.frametype = AST_FRAME_VOICE;
06484                if (iaxs[fr->callno]) {
06485                   if (iaxs[fr->callno]->voiceformat > 0) {
06486                      f.subclass = iaxs[fr->callno]->voiceformat;
06487                      f.datalen = len;
06488                      if (f.datalen >= 0) {
06489                         if (f.datalen)
06490                            f.data = ptr;
06491                         else
06492                            f.data = NULL;
06493                         if(trunked_ts) {
06494                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06495                         } else
06496                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06497                         /* Don't pass any packets until we're started */
06498                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06499                            /* Common things */
06500                            f.src = "IAX2";
06501                            f.mallocd = 0;
06502                            f.offset = 0;
06503                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06504                               f.samples = ast_codec_get_samples(&f);
06505                            else
06506                               f.samples = 0;
06507                            fr->outoforder = 0;
06508                            iax_frame_wrap(fr, &f);
06509 #ifdef BRIDGE_OPTIMIZATION
06510                            if (iaxs[fr->callno]->bridgecallno) {
06511                               forward_delivery(fr);
06512                            } else {
06513                               duped_fr = iaxfrdup2(fr);
06514                               if (duped_fr) {
06515                                  schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06516                               }
06517                            }
06518 #else
06519                            duped_fr = iaxfrdup2(fr);
06520                            if (duped_fr) {
06521                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06522                            }
06523 #endif
06524                            if (iaxs[fr->callno]->last < fr->ts) {
06525                               iaxs[fr->callno]->last = fr->ts;
06526 #if 1
06527                               if (option_debug)
06528                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06529 #endif
06530                            }
06531                         }
06532                      } else {
06533                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06534                      }
06535                   } else {
06536                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06537                      iax2_vnak(fr->callno);
06538                   }
06539                }
06540                ast_mutex_unlock(&iaxsl[fr->callno]);
06541             }
06542             ptr += len;
06543             res -= len;
06544          }
06545          
06546       }
06547       return 1;
06548    }
06549 
06550 #ifdef DEBUG_SUPPORT
06551    if (iaxdebug && (res >= sizeof(*fh)))
06552       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06553 #endif
06554    if ((res >= sizeof(*fh)) && ntohs(mh->callno) & IAX_FLAG_FULL) {
06555       if (res < sizeof(*fh)) {
06556          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));
06557          return 1;
06558       }
06559 
06560       /* Get the destination call number */
06561       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06562       /* Retrieve the type and subclass */
06563       f.frametype = fh->type;
06564       if (f.frametype == AST_FRAME_VIDEO) {
06565          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06566       } else {
06567          f.subclass = uncompress_subclass(fh->csub);
06568       }
06569       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06570                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06571                          (f.subclass == IAX_COMMAND_REGREL)))
06572          new = NEW_ALLOW;
06573    } else {
06574       /* Don't know anything about it yet */
06575       f.frametype = AST_FRAME_NULL;
06576       f.subclass = 0;
06577    }
06578 
06579    if (!fr->callno)
06580       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06581 
06582    if (fr->callno > 0) 
06583       ast_mutex_lock(&iaxsl[fr->callno]);
06584 
06585    if (!fr->callno || !iaxs[fr->callno]) {
06586       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06587          frame, reply with an inval */
06588       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06589          /* We can only raw hangup control frames */
06590          if (((f.subclass != IAX_COMMAND_INVAL) &&
06591              (f.subclass != IAX_COMMAND_TXCNT) &&
06592              (f.subclass != IAX_COMMAND_TXACC) &&
06593              (f.subclass != IAX_COMMAND_FWDOWNL))||
06594              (f.frametype != AST_FRAME_IAX))
06595             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06596             fd);
06597       }
06598       if (fr->callno > 0) 
06599          ast_mutex_unlock(&iaxsl[fr->callno]);
06600       return 1;
06601    }
06602    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06603       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06604          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06605          ast_mutex_unlock(&iaxsl[fr->callno]);
06606          return 1;
06607       }
06608 #ifdef DEBUG_SUPPORT
06609       else if (iaxdebug)
06610          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06611 #endif
06612    }
06613 
06614    /* count this frame */
06615    iaxs[fr->callno]->frames_received++;
06616 
06617    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06618       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06619       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06620       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06621    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06622       if (option_debug  && iaxdebug)
06623          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06624       /* Check if it's out of order (and not an ACK or INVAL) */
06625       fr->oseqno = fh->oseqno;
06626       fr->iseqno = fh->iseqno;
06627       fr->ts = ntohl(fh->ts);
06628 #ifdef IAXTESTS
06629       if (test_resync) {
06630          if (option_debug)
06631             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06632          fr->ts += test_resync;
06633       }
06634 #endif /* IAXTESTS */
06635 #if 0
06636       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06637            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06638                         (f.subclass == IAX_COMMAND_NEW ||
06639                          f.subclass == IAX_COMMAND_AUTHREQ ||
06640                          f.subclass == IAX_COMMAND_ACCEPT ||
06641                          f.subclass == IAX_COMMAND_REJECT))      ) )
06642 #endif
06643       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06644          updatehistory = 0;
06645       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06646          (iaxs[fr->callno]->iseqno ||
06647             ((f.subclass != IAX_COMMAND_TXCNT) &&
06648             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06649             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06650             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06651             (f.subclass != IAX_COMMAND_TXACC)) ||
06652             (f.frametype != AST_FRAME_IAX))) {
06653          if (
06654           ((f.subclass != IAX_COMMAND_ACK) &&
06655            (f.subclass != IAX_COMMAND_INVAL) &&
06656            (f.subclass != IAX_COMMAND_TXCNT) &&
06657            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06658            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06659            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06660            (f.subclass != IAX_COMMAND_TXACC) &&
06661            (f.subclass != IAX_COMMAND_VNAK)) ||
06662            (f.frametype != AST_FRAME_IAX)) {
06663             /* If it's not an ACK packet, it's out of order. */
06664             if (option_debug)
06665                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06666                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06667             if (iaxs[fr->callno]->iseqno > fr->oseqno) {
06668                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06669                if ((f.frametype != AST_FRAME_IAX) || 
06670                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06671                   if (option_debug)
06672                      ast_log(LOG_DEBUG, "Acking anyway\n");
06673                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06674                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06675                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06676                }
06677             } else {
06678                /* Send a VNAK requesting retransmission */
06679                iax2_vnak(fr->callno);
06680             }
06681             ast_mutex_unlock(&iaxsl[fr->callno]);
06682             return 1;
06683          }
06684       } else {
06685          /* Increment unless it's an ACK or VNAK */
06686          if (((f.subclass != IAX_COMMAND_ACK) &&
06687              (f.subclass != IAX_COMMAND_INVAL) &&
06688              (f.subclass != IAX_COMMAND_TXCNT) &&
06689              (f.subclass != IAX_COMMAND_TXACC) &&
06690             (f.subclass != IAX_COMMAND_VNAK)) ||
06691              (f.frametype != AST_FRAME_IAX))
06692             iaxs[fr->callno]->iseqno++;
06693       }
06694       /* A full frame */
06695       if (res < sizeof(*fh)) {
06696          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06697          ast_mutex_unlock(&iaxsl[fr->callno]);
06698          return 1;
06699       }
06700       f.datalen = res - sizeof(*fh);
06701 
06702       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
06703          from the real peer, not the transfer peer */
06704       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06705           ((f.subclass != IAX_COMMAND_INVAL) ||
06706            (f.frametype != AST_FRAME_IAX))) {
06707          unsigned char x;
06708          /* XXX This code is not very efficient.  Surely there is a better way which still
06709                 properly handles boundary conditions? XXX */
06710          /* First we have to qualify that the ACKed value is within our window */
06711          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
06712             if (fr->iseqno == x)
06713                break;
06714          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
06715             /* The acknowledgement is within our window.  Time to acknowledge everything
06716                that it says to */
06717             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
06718                /* Ack the packet with the given timestamp */
06719                if (option_debug && iaxdebug)
06720                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06721                ast_mutex_lock(&iaxq.lock);
06722                for (cur = iaxq.head; cur ; cur = cur->next) {
06723                   /* If it's our call, and our timestamp, mark -1 retries */
06724                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
06725                      cur->retries = -1;
06726                      /* Destroy call if this is the end */
06727                      if (cur->final) { 
06728                         if (iaxdebug && option_debug)
06729                            ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
06730                         iax2_destroy_nolock(fr->callno);
06731                      }
06732                   }
06733                }
06734                ast_mutex_unlock(&iaxq.lock);
06735             }
06736             /* Note how much we've received acknowledgement for */
06737             if (iaxs[fr->callno])
06738                iaxs[fr->callno]->rseqno = fr->iseqno;
06739             else {
06740                /* Stop processing now */
06741                ast_mutex_unlock(&iaxsl[fr->callno]);
06742                return 1;
06743             }
06744          } else
06745             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
06746       }
06747       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06748          ((f.frametype != AST_FRAME_IAX) || 
06749           ((f.subclass != IAX_COMMAND_TXACC) &&
06750            (f.subclass != IAX_COMMAND_TXCNT)))) {
06751          /* Only messages we accept from a transfer host are TXACC and TXCNT */
06752          ast_mutex_unlock(&iaxsl[fr->callno]);
06753          return 1;
06754       }
06755 
06756       if (f.datalen) {
06757          if (f.frametype == AST_FRAME_IAX) {
06758             if (iax_parse_ies(&ies, buf + sizeof(*fh), f.datalen)) {
06759                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
06760                ast_mutex_unlock(&iaxsl[fr->callno]);
06761                return 1;
06762             }
06763             f.data = NULL;
06764          } else
06765             f.data = buf + sizeof(*fh);
06766       } else {
06767          if (f.frametype == AST_FRAME_IAX)
06768             f.data = NULL;
06769          else
06770             f.data = empty;
06771          memset(&ies, 0, sizeof(ies));
06772       }
06773       if (f.frametype == AST_FRAME_VOICE) {
06774          if (f.subclass != iaxs[fr->callno]->voiceformat) {
06775                iaxs[fr->callno]->voiceformat = f.subclass;
06776                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06777                if (iaxs[fr->callno]->owner) {
06778                   int orignative;
06779 retryowner:
06780                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
06781                      ast_mutex_unlock(&iaxsl[fr->callno]);
06782                      usleep(1);
06783                      ast_mutex_lock(&iaxsl[fr->callno]);
06784                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
06785                   }
06786                   if (iaxs[fr->callno]) {
06787                      if (iaxs[fr->callno]->owner) {
06788                         orignative = iaxs[fr->callno]->owner->nativeformats;
06789                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
06790                         if (iaxs[fr->callno]->owner->readformat)
06791                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
06792                         iaxs[fr->callno]->owner->nativeformats = orignative;
06793                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
06794                      }
06795                   } else {
06796                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06797                      ast_mutex_unlock(&iaxsl[fr->callno]);
06798                      return 1;
06799                   }
06800                }
06801          }
06802       }
06803       if (f.frametype == AST_FRAME_VIDEO) {
06804          if (f.subclass != iaxs[fr->callno]->videoformat) {
06805             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06806             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
06807          }
06808       }
06809       if (f.frametype == AST_FRAME_IAX) {
06810          if (iaxs[fr->callno]->initid > -1) {
06811             /* Don't auto congest anymore since we've gotten something usefulb ack */
06812             ast_sched_del(sched, iaxs[fr->callno]->initid);
06813             iaxs[fr->callno]->initid = -1;
06814          }
06815          /* Handle the IAX pseudo frame itself */
06816          if (option_debug && iaxdebug)
06817             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06818 
06819                         /* Update last ts unless the frame's timestamp originated with us. */
06820          if (iaxs[fr->callno]->last < fr->ts &&
06821                             f.subclass != IAX_COMMAND_ACK &&
06822                             f.subclass != IAX_COMMAND_PONG &&
06823                             f.subclass != IAX_COMMAND_LAGRP) {
06824             iaxs[fr->callno]->last = fr->ts;
06825             if (option_debug && iaxdebug)
06826                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06827          }
06828 
06829          switch(f.subclass) {
06830          case IAX_COMMAND_ACK:
06831             /* Do nothing */
06832             break;
06833          case IAX_COMMAND_QUELCH:
06834             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06835                     /* Generate Manager Hold event, if necessary*/
06836                if (iaxs[fr->callno]->owner) {
06837                   manager_event(EVENT_FLAG_CALL, "Hold",
06838                      "Channel: %s\r\n"
06839                      "Uniqueid: %s\r\n",
06840                      iaxs[fr->callno]->owner->name, 
06841                      iaxs[fr->callno]->owner->uniqueid);
06842                }
06843 
06844                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
06845                if (ies.musiconhold) {
06846                   if (iaxs[fr->callno]->owner &&
06847                      ast_bridged_channel(iaxs[fr->callno]->owner))
06848                         ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL);
06849                }
06850             }
06851             break;
06852          case IAX_COMMAND_UNQUELCH:
06853             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06854                     /* Generate Manager Unhold event, if necessary*/
06855                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
06856                   manager_event(EVENT_FLAG_CALL, "Unhold",
06857                      "Channel: %s\r\n"
06858                      "Uniqueid: %s\r\n",
06859                      iaxs[fr->callno]->owner->name, 
06860                      iaxs[fr->callno]->owner->uniqueid);
06861                }
06862 
06863                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
06864                if (iaxs[fr->callno]->owner &&
06865                   ast_bridged_channel(iaxs[fr->callno]->owner))
06866                      ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner));
06867             }
06868             break;
06869          case IAX_COMMAND_TXACC:
06870             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
06871                /* Ack the packet with the given timestamp */
06872                ast_mutex_lock(&iaxq.lock);
06873                for (cur = iaxq.head; cur ; cur = cur->next) {
06874                   /* Cancel any outstanding txcnt's */
06875                   if ((fr->callno == cur->callno) && (cur->transfer))
06876                      cur->retries = -1;
06877                }
06878                ast_mutex_unlock(&iaxq.lock);
06879                memset(&ied1, 0, sizeof(ied1));
06880                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
06881                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06882                iaxs[fr->callno]->transferring = TRANSFER_READY;
06883             }
06884             break;
06885          case IAX_COMMAND_NEW:
06886             /* Ignore if it's already up */
06887             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06888                break;
06889             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06890                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06891             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
06892             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
06893                fr->callno = make_trunk(fr->callno, 1);
06894             }
06895             /* For security, always ack immediately */
06896             if (delayreject)
06897                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06898             if (check_access(fr->callno, &sin, &ies)) {
06899                /* They're not allowed on */
06900                auth_fail(fr->callno, IAX_COMMAND_REJECT);
06901                if (authdebug)
06902                   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);
06903                break;
06904             }
06905             /* This might re-enter the IAX code and need the lock */
06906             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
06907                ast_mutex_unlock(&iaxsl[fr->callno]);
06908                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
06909                ast_mutex_lock(&iaxsl[fr->callno]);
06910             } else
06911                exists = 0;
06912             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
06913                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
06914                   memset(&ied0, 0, sizeof(ied0));
06915                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
06916                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
06917                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06918                   if (authdebug)
06919                      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);
06920                } else {
06921                   /* Select an appropriate format */
06922 
06923                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06924                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06925                         using_prefs = "reqonly";
06926                      } else {
06927                         using_prefs = "disabled";
06928                      }
06929                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
06930                      memset(&pref, 0, sizeof(pref));
06931                      strcpy(caller_pref_buf, "disabled");
06932                      strcpy(host_pref_buf, "disabled");
06933                   } else {
06934                      using_prefs = "mine";
06935                      /* If the information elements are in here... use them */
06936                      if (ies.codec_prefs)
06937                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
06938                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06939                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
06940                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06941                            pref = iaxs[fr->callno]->rprefs;
06942                            using_prefs = "caller";
06943                         } else {
06944                            pref = iaxs[fr->callno]->prefs;
06945                         }
06946                      } else
06947                         pref = iaxs[fr->callno]->prefs;
06948                      
06949                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
06950                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
06951                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
06952                   }
06953                   if (!format) {
06954                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06955                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
06956                      if (!format) {
06957                         memset(&ied0, 0, sizeof(ied0));
06958                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06959                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06960                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06961                         if (authdebug) {
06962                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06963                               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);
06964                            else 
06965                               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);
06966                         }
06967                      } else {
06968                         /* Pick one... */
06969                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06970                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
06971                               format = 0;
06972                         } else {
06973                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06974                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
06975                               memset(&pref, 0, sizeof(pref));
06976                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06977                               strcpy(caller_pref_buf,"disabled");
06978                               strcpy(host_pref_buf,"disabled");
06979                            } else {
06980                               using_prefs = "mine";
06981                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06982                                  /* Do the opposite of what we tried above. */
06983                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06984                                     pref = iaxs[fr->callno]->prefs;                       
06985                                  } else {
06986                                     pref = iaxs[fr->callno]->rprefs;
06987                                     using_prefs = "caller";
06988                                  }
06989                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
06990                            
06991                               } else /* if no codec_prefs IE do it the old way */
06992                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
06993                            }
06994                         }
06995 
06996                         if (!format) {
06997                            memset(&ied0, 0, sizeof(ied0));
06998                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06999                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07000                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07001                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07002                            if (authdebug)
07003                               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);
07004                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07005                            break;
07006                         }
07007                      }
07008                   }
07009                   if (format) {
07010                      /* No authentication required, let them in */
07011                      memset(&ied1, 0, sizeof(ied1));
07012                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07013                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07014                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07015                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07016                         if (option_verbose > 2) 
07017                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07018                                     "%srequested format = %s,\n"
07019                                     "%srequested prefs = %s,\n"
07020                                     "%sactual format = %s,\n"
07021                                     "%shost prefs = %s,\n"
07022                                     "%spriority = %s\n",
07023                                     ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
07024                                     VERBOSE_PREFIX_4,
07025                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07026                                     VERBOSE_PREFIX_4,
07027                                     caller_pref_buf,
07028                                     VERBOSE_PREFIX_4,
07029                                     ast_getformatname(format), 
07030                                     VERBOSE_PREFIX_4,
07031                                     host_pref_buf, 
07032                                     VERBOSE_PREFIX_4,
07033                                     using_prefs);
07034                         
07035                         if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07036                            iax2_destroy_nolock(fr->callno);
07037                      } else {
07038                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07039                         /* If this is a TBD call, we're ready but now what...  */
07040                         if (option_verbose > 2)
07041                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07042                      }
07043                   }
07044                }
07045                break;
07046             }
07047             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07048                merge_encryption(iaxs[fr->callno],ies.encmethods);
07049             else
07050                iaxs[fr->callno]->encmethods = 0;
07051             if (!authenticate_request(iaxs[fr->callno]))
07052                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07053             break;
07054          case IAX_COMMAND_DPREQ:
07055             /* Request status in the dialplan */
07056             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07057                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07058                if (iaxcompat) {
07059                   /* Spawn a thread for the lookup */
07060                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07061                } else {
07062                   /* Just look it up */
07063                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07064                }
07065             }
07066             break;
07067          case IAX_COMMAND_HANGUP:
07068             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07069             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07070             /* Set hangup cause according to remote */
07071             if (ies.causecode && iaxs[fr->callno]->owner)
07072                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07073             /* Send ack immediately, before we destroy */
07074             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07075             iax2_destroy_nolock(fr->callno);
07076             break;
07077          case IAX_COMMAND_REJECT:
07078             memset(&f, 0, sizeof(f));
07079             f.frametype = AST_FRAME_CONTROL;
07080             f.subclass = AST_CONTROL_CONGESTION;
07081 
07082             /* Set hangup cause according to remote */
07083             if (ies.causecode && iaxs[fr->callno]->owner)
07084                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07085 
07086             iax2_queue_frame(fr->callno, &f);
07087             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07088                /* Send ack immediately, before we destroy */
07089                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07090                iax2_destroy_nolock(fr->callno);
07091                break;
07092             }
07093             if (iaxs[fr->callno]->owner) {
07094                if (authdebug)
07095                   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>");
07096             }
07097             ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno);
07098             /* Send ack immediately, before we destroy */
07099             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07100             iaxs[fr->callno]->error = EPERM;
07101             iax2_destroy_nolock(fr->callno);
07102             break;
07103          case IAX_COMMAND_TRANSFER:
07104             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07105                if (!strcmp(ies.called_number, ast_parking_ext())) {
07106                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07107                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07108                   } else
07109                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07110                } else {
07111                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07112                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07113                         ies.called_number, iaxs[fr->callno]->context);
07114                   else
07115                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07116                         ies.called_number, iaxs[fr->callno]->context);
07117                }
07118             } else
07119                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07120             break;
07121          case IAX_COMMAND_ACCEPT:
07122             /* Ignore if call is already up or needs authentication or is a TBD */
07123             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07124                break;
07125             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07126                /* Send ack immediately, before we destroy */
07127                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07128                iax2_destroy_nolock(fr->callno);
07129                break;
07130             }
07131             if (ies.format) {
07132                iaxs[fr->callno]->peerformat = ies.format;
07133             } else {
07134                if (iaxs[fr->callno]->owner)
07135                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07136                else
07137                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07138             }
07139             if (option_verbose > 2)
07140                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));
07141             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07142                memset(&ied0, 0, sizeof(ied0));
07143                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07144                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07145                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07146                if (authdebug)
07147                   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);
07148             } else {
07149                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07150                if (iaxs[fr->callno]->owner) {
07151                   /* Switch us to use a compatible format */
07152                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07153                   if (option_verbose > 2)
07154                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07155 retryowner2:
07156                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07157                      ast_mutex_unlock(&iaxsl[fr->callno]);
07158                      usleep(1);
07159                      ast_mutex_lock(&iaxsl[fr->callno]);
07160                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07161                   }
07162                   
07163                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07164                      /* Setup read/write formats properly. */
07165                      if (iaxs[fr->callno]->owner->writeformat)
07166                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07167                      if (iaxs[fr->callno]->owner->readformat)
07168                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07169                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07170                   }
07171                }
07172             }
07173             ast_mutex_lock(&dpcache_lock);
07174             dp = iaxs[fr->callno]->dpentries;
07175             while(dp) {
07176                if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07177                   iax2_dprequest(dp, fr->callno);
07178                }
07179                dp = dp->peer;
07180             }
07181             ast_mutex_unlock(&dpcache_lock);
07182             break;
07183          case IAX_COMMAND_POKE:
07184             /* Send back a pong packet with the original timestamp */
07185             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07186             break;
07187          case IAX_COMMAND_PING:
07188 #ifdef BRIDGE_OPTIMIZATION
07189             if (iaxs[fr->callno]->bridgecallno) {
07190                /* If we're in a bridged call, just forward this */
07191                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1);
07192             } else {
07193                struct iax_ie_data pingied;
07194                construct_rr(iaxs[fr->callno], &pingied);
07195                /* Send back a pong packet with the original timestamp */
07196                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07197             }
07198 #else          
07199             {
07200                struct iax_ie_data pingied;
07201                construct_rr(iaxs[fr->callno], &pingied);
07202             /* Send back a pong packet with the original timestamp */
07203                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07204             }
07205 #endif         
07206             break;
07207          case IAX_COMMAND_PONG:
07208 #ifdef BRIDGE_OPTIMIZATION
07209             if (iaxs[fr->callno]->bridgecallno) {
07210                /* Forward to the other side of the bridge */
07211                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07212             } else {
07213                /* Calculate ping time */
07214                iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07215             }
07216 #else
07217             /* Calculate ping time */
07218             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07219 #endif
07220             /* save RR info */
07221             save_rr(fr, &ies);
07222 
07223             if (iaxs[fr->callno]->peerpoke) {
07224                peer = iaxs[fr->callno]->peerpoke;
07225                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07226                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07227                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07228                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07229                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07230                   }
07231                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07232                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07233                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07234                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07235                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07236                   }
07237                }
07238                peer->lastms = iaxs[fr->callno]->pingtime;
07239                if (peer->smoothing && (peer->lastms > -1))
07240                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07241                else if (peer->smoothing && peer->lastms < 0)
07242                   peer->historicms = (0 + peer->historicms) / 2;
07243                else              
07244                   peer->historicms = iaxs[fr->callno]->pingtime;
07245 
07246                if (peer->pokeexpire > -1)
07247                   ast_sched_del(sched, peer->pokeexpire);
07248                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07249                iax2_destroy_nolock(fr->callno);
07250                peer->callno = 0;
07251                /* Try again eventually */
07252                   ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms);
07253                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07254                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07255                else
07256                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07257             }
07258             break;
07259          case IAX_COMMAND_LAGRQ:
07260          case IAX_COMMAND_LAGRP:
07261 #ifdef BRIDGE_OPTIMIZATION
07262             if (iaxs[fr->callno]->bridgecallno) {
07263                forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1);
07264             } else {
07265 #endif            
07266                f.src = "LAGRQ";
07267                f.mallocd = 0;
07268                f.offset = 0;
07269                f.samples = 0;
07270                iax_frame_wrap(fr, &f);
07271                if(f.subclass == IAX_COMMAND_LAGRQ) {
07272                    /* Received a LAGRQ - echo back a LAGRP */
07273                    fr->af.subclass = IAX_COMMAND_LAGRP;
07274                    iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07275                } else {
07276                    /* Received LAGRP in response to our LAGRQ */
07277                    unsigned int ts;
07278                    /* This is a reply we've been given, actually measure the difference */
07279                    ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07280                    iaxs[fr->callno]->lag = ts - fr->ts;
07281                    if (option_debug && iaxdebug)
07282                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07283                         ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07284                }
07285 #ifdef BRIDGE_OPTIMIZATION
07286             }
07287 #endif            
07288             break;
07289          case IAX_COMMAND_AUTHREQ:
07290             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07291                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>");
07292                break;
07293             }
07294             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07295                ast_log(LOG_WARNING, 
07296                   "I don't know how to authenticate %s to %s\n", 
07297                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr));
07298             }
07299             break;
07300          case IAX_COMMAND_AUTHREP:
07301             /* For security, always ack immediately */
07302             if (delayreject)
07303                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07304             /* Ignore once we've started */
07305             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07306                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>");
07307                break;
07308             }
07309             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07310                if (authdebug)
07311                   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);
07312                memset(&ied0, 0, sizeof(ied0));
07313                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07314                break;
07315             }
07316             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07317                /* This might re-enter the IAX code and need the lock */
07318                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07319             } else
07320                exists = 0;
07321             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07322                if (authdebug)
07323                   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);
07324                memset(&ied0, 0, sizeof(ied0));
07325                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07326                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07327                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07328             } else {
07329                /* Select an appropriate format */
07330                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07331                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07332                      using_prefs = "reqonly";
07333                   } else {
07334                      using_prefs = "disabled";
07335                   }
07336                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07337                   memset(&pref, 0, sizeof(pref));
07338                   strcpy(caller_pref_buf, "disabled");
07339                   strcpy(host_pref_buf, "disabled");
07340                } else {
07341                   using_prefs = "mine";
07342                   if (ies.codec_prefs)
07343                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07344                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07345                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07346                         pref = iaxs[fr->callno]->rprefs;
07347                         using_prefs = "caller";
07348                      } else {
07349                         pref = iaxs[fr->callno]->prefs;
07350                      }
07351                   } else /* if no codec_prefs IE do it the old way */
07352                      pref = iaxs[fr->callno]->prefs;
07353                
07354                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07355                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07356                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07357                }
07358                if (!format) {
07359                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07360                      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);
07361                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07362                   }
07363                   if (!format) {
07364                      if (authdebug) {
07365                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07366                            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);
07367                         else
07368                            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);
07369                      }
07370                      memset(&ied0, 0, sizeof(ied0));
07371                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07372                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07373                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07374                   } else {
07375                      /* Pick one... */
07376                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07377                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07378                            format = 0;
07379                      } else {
07380                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07381                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07382                            memset(&pref, 0, sizeof(pref));
07383                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07384                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07385                            strcpy(caller_pref_buf,"disabled");
07386                            strcpy(host_pref_buf,"disabled");
07387                         } else {
07388                            using_prefs = "mine";
07389                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07390                               /* Do the opposite of what we tried above. */
07391                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07392                                  pref = iaxs[fr->callno]->prefs;                 
07393                               } else {
07394                                  pref = iaxs[fr->callno]->rprefs;
07395                                  using_prefs = "caller";
07396                               }
07397                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07398                            } else /* if no codec_prefs IE do it the old way */
07399                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07400                         }
07401                      }
07402                      if (!format) {
07403                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07404                         if (authdebug) {
07405                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07406                               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);
07407                            else
07408                               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);
07409                         }
07410                         memset(&ied0, 0, sizeof(ied0));
07411                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07412                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07413                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07414                      }
07415                   }
07416                }
07417                if (format) {
07418                   /* Authentication received */
07419                   memset(&ied1, 0, sizeof(ied1));
07420                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07421                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07422                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07423                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07424                      if (option_verbose > 2) 
07425                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07426                                  "%srequested format = %s,\n"
07427                                  "%srequested prefs = %s,\n"
07428                                  "%sactual format = %s,\n"
07429                                  "%shost prefs = %s,\n"
07430                                  "%spriority = %s\n", 
07431                                  ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
07432                                  VERBOSE_PREFIX_4,
07433                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07434                                  VERBOSE_PREFIX_4,
07435                                  caller_pref_buf,
07436                                  VERBOSE_PREFIX_4,
07437                                  ast_getformatname(format),
07438                                  VERBOSE_PREFIX_4,
07439                                  host_pref_buf,
07440                                  VERBOSE_PREFIX_4,
07441                                  using_prefs);
07442 
07443                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07444                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07445                         iax2_destroy_nolock(fr->callno);
07446                   } else {
07447                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07448                      /* If this is a TBD call, we're ready but now what...  */
07449                      if (option_verbose > 2)
07450                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07451                   }
07452                }
07453             }
07454             break;
07455          case IAX_COMMAND_DIAL:
07456             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07457                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07458                ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten)); 
07459                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07460                   if (authdebug)
07461                      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);
07462                   memset(&ied0, 0, sizeof(ied0));
07463                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07464                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07465                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07466                } else {
07467                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07468                   if (option_verbose > 2) 
07469                      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);
07470                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07471                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07472                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07473                      iax2_destroy_nolock(fr->callno);
07474                }
07475             }
07476             break;
07477          case IAX_COMMAND_INVAL:
07478             iaxs[fr->callno]->error = ENOTCONN;
07479             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07480             iax2_destroy_nolock(fr->callno);
07481             if (option_debug)
07482                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07483             break;
07484          case IAX_COMMAND_VNAK:
07485             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07486             /* Force retransmission */
07487             vnak_retransmit(fr->callno, fr->iseqno);
07488             break;
07489          case IAX_COMMAND_REGREQ:
07490          case IAX_COMMAND_REGREL:
07491             /* For security, always ack immediately */
07492             if (delayreject)
07493                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07494             if (register_verify(fr->callno, &sin, &ies)) {
07495                /* Send delayed failure */
07496                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07497                break;
07498             }
07499             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)) {
07500                if (f.subclass == IAX_COMMAND_REGREL)
07501                   memset(&sin, 0, sizeof(sin));
07502                if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
07503                   ast_log(LOG_WARNING, "Registry error\n");
07504                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07505                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07506                break;
07507             }
07508             registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
07509             break;
07510          case IAX_COMMAND_REGACK:
07511             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
07512                ast_log(LOG_WARNING, "Registration failure\n");
07513             /* Send ack immediately, before we destroy */
07514             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07515             iax2_destroy_nolock(fr->callno);
07516             break;
07517          case IAX_COMMAND_REGREJ:
07518             if (iaxs[fr->callno]->reg) {
07519                if (authdebug) {
07520                   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));
07521                   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>");
07522                }
07523                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07524             }
07525             /* Send ack immediately, before we destroy */
07526             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07527             iax2_destroy_nolock(fr->callno);
07528             break;
07529          case IAX_COMMAND_REGAUTH:
07530             /* Authentication request */
07531             if (registry_rerequest(&ies, fr->callno, &sin)) {
07532                memset(&ied0, 0, sizeof(ied0));
07533                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07534                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07535                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07536             }
07537             break;
07538          case IAX_COMMAND_TXREJ:
07539             iaxs[fr->callno]->transferring = 0;
07540             if (option_verbose > 2) 
07541                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07542             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07543             if (iaxs[fr->callno]->bridgecallno) {
07544                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07545                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07546                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07547                }
07548             }
07549             break;
07550          case IAX_COMMAND_TXREADY:
07551             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07552                iaxs[fr->callno]->transferring = TRANSFER_READY;
07553                if (option_verbose > 2) 
07554                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07555                if (iaxs[fr->callno]->bridgecallno) {
07556                   if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) {
07557                      if (option_verbose > 2) 
07558                         ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07559                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07560 
07561                      /* They're both ready, now release them. */
07562                      iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07563                      iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07564                      ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07565                      ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07566 
07567                      /* Stop doing lag & ping requests */
07568                      stop_stuff(fr->callno);
07569                      stop_stuff(iaxs[fr->callno]->bridgecallno);
07570 
07571                      memset(&ied0, 0, sizeof(ied0));
07572                      memset(&ied1, 0, sizeof(ied1));
07573                      iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07574                      iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07575                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07576                      send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07577 
07578                   }
07579                }
07580             }
07581             break;
07582          case IAX_COMMAND_TXREQ:
07583             try_transfer(iaxs[fr->callno], &ies);
07584             break;
07585          case IAX_COMMAND_TXCNT:
07586             if (iaxs[fr->callno]->transferring)
07587                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07588             break;
07589          case IAX_COMMAND_TXREL:
07590             /* Send ack immediately, rather than waiting until we've changed addresses */
07591             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07592             complete_transfer(fr->callno, &ies);
07593             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
07594             break;   
07595          case IAX_COMMAND_DPREP:
07596             complete_dpreply(iaxs[fr->callno], &ies);
07597             break;
07598          case IAX_COMMAND_UNSUPPORT:
07599             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07600             break;
07601          case IAX_COMMAND_FWDOWNL:
07602             /* Firmware download */
07603             memset(&ied0, 0, sizeof(ied0));
07604             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07605             if (res < 0)
07606                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07607             else if (res > 0)
07608                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07609             else
07610                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07611             break;
07612          default:
07613             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
07614             memset(&ied0, 0, sizeof(ied0));
07615             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07616             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07617          }
07618          /* Don't actually pass these frames along */
07619          if ((f.subclass != IAX_COMMAND_ACK) && 
07620            (f.subclass != IAX_COMMAND_TXCNT) && 
07621            (f.subclass != IAX_COMMAND_TXACC) && 
07622            (f.subclass != IAX_COMMAND_INVAL) &&
07623            (f.subclass != IAX_COMMAND_VNAK)) { 
07624             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07625                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07626          }
07627          ast_mutex_unlock(&iaxsl[fr->callno]);
07628          return 1;
07629       }
07630       /* Unless this is an ACK or INVAL frame, ack it */
07631       if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07632          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07633    } else if (minivid) {
07634       f.frametype = AST_FRAME_VIDEO;
07635       if (iaxs[fr->callno]->videoformat > 0) 
07636          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07637       else {
07638          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07639          iax2_vnak(fr->callno);
07640          ast_mutex_unlock(&iaxsl[fr->callno]);
07641          return 1;
07642       }
07643       f.datalen = res - sizeof(*vh);
07644       if (f.datalen)
07645          f.data = buf + sizeof(*vh);
07646       else
07647          f.data = NULL;
07648 #ifdef IAXTESTS
07649       if (test_resync) {
07650          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff);
07651       } else
07652 #endif /* IAXTESTS */
07653       fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff);
07654    } else {
07655       /* A mini frame */
07656       f.frametype = AST_FRAME_VOICE;
07657       if (iaxs[fr->callno]->voiceformat > 0)
07658          f.subclass = iaxs[fr->callno]->voiceformat;
07659       else {
07660          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07661          iax2_vnak(fr->callno);
07662          ast_mutex_unlock(&iaxsl[fr->callno]);
07663          return 1;
07664       }
07665       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07666       if (f.datalen < 0) {
07667          ast_log(LOG_WARNING, "Datalen < 0?\n");
07668          ast_mutex_unlock(&iaxsl[fr->callno]);
07669          return 1;
07670       }
07671       if (f.datalen)
07672          f.data = buf + sizeof(*mh);
07673       else
07674          f.data = NULL;
07675 #ifdef IAXTESTS
07676       if (test_resync) {
07677          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07678       } else
07679 #endif /* IAXTESTS */
07680       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07681       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
07682    }
07683    /* Don't pass any packets until we're started */
07684    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07685       ast_mutex_unlock(&iaxsl[fr->callno]);
07686       return 1;
07687    }
07688    /* Common things */
07689    f.src = "IAX2";
07690    f.mallocd = 0;
07691    f.offset = 0;
07692    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07693       f.samples = ast_codec_get_samples(&f);
07694       /* We need to byteswap incoming slinear samples from network byte order */
07695       if (f.subclass == AST_FORMAT_SLINEAR)
07696          ast_frame_byteswap_be(&f);
07697    } else
07698       f.samples = 0;
07699    iax_frame_wrap(fr, &f);
07700 
07701    /* If this is our most recent packet, use it as our basis for timestamping */
07702    if (iaxs[fr->callno]->last < fr->ts) {
07703       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
07704       fr->outoforder = 0;
07705    } else {
07706       if (option_debug && iaxdebug)
07707          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);
07708       fr->outoforder = -1;
07709    }
07710 #ifdef BRIDGE_OPTIMIZATION
07711    if (iaxs[fr->callno]->bridgecallno) {
07712       forward_delivery(fr);
07713    } else {
07714       duped_fr = iaxfrdup2(fr);
07715       if (duped_fr) {
07716          schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07717       }
07718    }
07719 #else
07720    duped_fr = iaxfrdup2(fr);
07721    if (duped_fr) {
07722       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07723    }
07724 #endif
07725 
07726    if (iaxs[fr->callno]->last < fr->ts) {
07727       iaxs[fr->callno]->last = fr->ts;
07728 #if 1
07729       if (option_debug && iaxdebug)
07730          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07731 #endif
07732    }
07733 
07734    /* Always run again */
07735    ast_mutex_unlock(&iaxsl[fr->callno]);
07736    return 1;
07737 }
07738 
07739 static int iax2_do_register(struct iax2_registry *reg)
07740 {
07741    struct iax_ie_data ied;
07742    if (option_debug && iaxdebug)
07743       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07744    if (!reg->callno) {
07745       if (option_debug)
07746          ast_log(LOG_DEBUG, "Allocate call number\n");
07747       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07748       if (reg->callno < 1) {
07749          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07750          return -1;
07751       } else if (option_debug)
07752          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07753       iaxs[reg->callno]->reg = reg;
07754    }
07755    /* Schedule the next registration attempt */
07756    if (reg->expire > -1)
07757       ast_sched_del(sched, reg->expire);
07758    /* Setup the next registration a little early */
07759    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07760    /* Send the request */
07761    memset(&ied, 0, sizeof(ied));
07762    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07763    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07764    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07765    reg->regstate = REG_STATE_REGSENT;
07766    return 0;
07767 }
07768 
07769 static char *iax2_prov_complete_template_3rd(char *line, char *word, int pos, int state)
07770 {
07771    if (pos != 3)
07772       return NULL;
07773    return iax_prov_complete_template(line, word, pos, state);
07774 }
07775 
07776 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
07777 {
07778    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07779       is found for template */
07780    struct iax_ie_data provdata;
07781    struct iax_ie_data ied;
07782    unsigned int sig;
07783    struct sockaddr_in sin;
07784    int callno;
07785    struct create_addr_info cai;
07786 
07787    memset(&cai, 0, sizeof(cai));
07788 
07789    if (option_debug)
07790       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07791 
07792    if (iax_provision_build(&provdata, &sig, template, force)) {
07793       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07794       return 0;
07795    }
07796 
07797    if (end) {
07798       memcpy(&sin, end, sizeof(sin));
07799       cai.sockfd = sockfd;
07800    } else if (create_addr(dest, &sin, &cai))
07801       return -1;
07802 
07803    /* Build the rest of the message */
07804    memset(&ied, 0, sizeof(ied));
07805    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07806 
07807    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07808    if (!callno)
07809       return -1;
07810 
07811    ast_mutex_lock(&iaxsl[callno]);
07812    if (iaxs[callno]) {
07813       /* Schedule autodestruct in case they don't ever give us anything back */
07814       if (iaxs[callno]->autoid > -1)
07815          ast_sched_del(sched, iaxs[callno]->autoid);
07816       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07817       ast_set_flag(iaxs[callno], IAX_PROVISION);
07818       /* Got a call number now, so go ahead and send the provisioning information */
07819       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07820    }
07821    ast_mutex_unlock(&iaxsl[callno]);
07822 
07823    return 1;
07824 }
07825 
07826 static char *papp = "IAX2Provision";
07827 static char *psyn = "Provision a calling IAXy with a given template";
07828 static char *pdescrip = 
07829 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
07830 "the calling entity is in fact an IAXy) with the given template or\n"
07831 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
07832 
07833 /*! iax2provision
07834 \ingroup applications
07835 */
07836 static int iax2_prov_app(struct ast_channel *chan, void *data)
07837 {
07838    int res;
07839    char *sdata;
07840    char *opts;
07841    int force =0;
07842    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
07843    char iabuf[INET_ADDRSTRLEN];
07844    if (ast_strlen_zero(data))
07845       data = "default";
07846    sdata = ast_strdupa(data);
07847    opts = strchr(sdata, '|');
07848    if (opts)
07849       *opts='\0';
07850 
07851    if (chan->type != channeltype) {
07852       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
07853       return -1;
07854    } 
07855    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
07856       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
07857       return -1;
07858    }
07859    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
07860    if (option_verbose > 2)
07861       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
07862       ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr),
07863       sdata, res);
07864    return res;
07865 }
07866 
07867 
07868 static int iax2_prov_cmd(int fd, int argc, char *argv[])
07869 {
07870    int force = 0;
07871    int res;
07872    if (argc < 4)
07873       return RESULT_SHOWUSAGE;
07874    if ((argc > 4)) {
07875       if (!strcasecmp(argv[4], "forced"))
07876          force = 1;
07877       else
07878          return RESULT_SHOWUSAGE;
07879    }
07880    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07881    if (res < 0)
07882       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07883    else if (res < 1)
07884       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07885    else
07886       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07887    return RESULT_SUCCESS;
07888 }
07889 
07890 static int iax2_poke_noanswer(void *data)
07891 {
07892    struct iax2_peer *peer = data;
07893    peer->pokeexpire = -1;
07894    if (peer->lastms > -1) {
07895       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07896       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07897       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07898    }
07899    if (peer->callno > 0)
07900       iax2_destroy(peer->callno);
07901    peer->callno = 0;
07902    peer->lastms = -1;
07903    /* Try again quickly */
07904    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07905    return 0;
07906 }
07907 
07908 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
07909 {
07910    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07911       /* IF we have no IP, or this isn't to be monitored, return
07912         imeediately after clearing things out */
07913       peer->lastms = 0;
07914       peer->historicms = 0;
07915       peer->pokeexpire = -1;
07916       peer->callno = 0;
07917       return 0;
07918    }
07919    if (peer->callno > 0) {
07920       ast_log(LOG_NOTICE, "Still have a callno...\n");
07921       iax2_destroy(peer->callno);
07922    }
07923    if (heldcall)
07924       ast_mutex_unlock(&iaxsl[heldcall]);
07925    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
07926    if (heldcall)
07927       ast_mutex_lock(&iaxsl[heldcall]);
07928    if (peer->callno < 1) {
07929       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
07930       return -1;
07931    }
07932    if (peer->pokeexpire > -1)
07933       ast_sched_del(sched, peer->pokeexpire);
07934    /* Speed up retransmission times */
07935    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
07936    iaxs[peer->callno]->peerpoke = peer;
07937    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
07938    
07939    /* If the host is already unreachable then use the unreachable interval instead */
07940    if (peer->lastms < 0) {
07941       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
07942    } else
07943       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
07944 
07945    return 0;
07946 }
07947 
07948 static void free_context(struct iax2_context *con)
07949 {
07950    struct iax2_context *conl;
07951    while(con) {
07952       conl = con;
07953       con = con->next;
07954       free(conl);
07955    }
07956 }
07957 
07958 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
07959 {
07960    int callno;
07961    int res;
07962    int fmt, native;
07963    struct sockaddr_in sin;
07964    struct ast_channel *c;
07965    struct parsed_dial_string pds;
07966    struct create_addr_info cai;
07967    char *tmpstr;
07968 
07969    memset(&pds, 0, sizeof(pds));
07970    tmpstr = ast_strdupa(data);
07971    parse_dial_string(tmpstr, &pds);
07972 
07973    memset(&cai, 0, sizeof(cai));
07974    cai.capability = iax2_capability;
07975 
07976    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07977 
07978    if (!pds.peer) {
07979       ast_log(LOG_WARNING, "No peer given\n");
07980       return NULL;
07981    }
07982           
07983    
07984    /* Populate our address from the given */
07985    if (create_addr(pds.peer, &sin, &cai)) {
07986       *cause = AST_CAUSE_UNREGISTERED;
07987       return NULL;
07988    }
07989 
07990    if (pds.port)
07991       sin.sin_port = htons(atoi(pds.port));
07992 
07993    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07994    if (callno < 1) {
07995       ast_log(LOG_WARNING, "Unable to create call\n");
07996       *cause = AST_CAUSE_CONGESTION;
07997       return NULL;
07998    }
07999 
08000    ast_mutex_lock(&iaxsl[callno]);
08001 
08002    /* If this is a trunk, update it now */
08003    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
08004    if (ast_test_flag(&cai, IAX_TRUNK))
08005       callno = make_trunk(callno, 1);
08006    iaxs[callno]->maxtime = cai.maxtime;
08007    if (cai.found)
08008       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
08009 
08010    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08011 
08012    ast_mutex_unlock(&iaxsl[callno]);
08013 
08014    if (c) {
08015       /* Choose a format we can live with */
08016       if (c->nativeformats & format) 
08017          c->nativeformats &= format;
08018       else {
08019          native = c->nativeformats;
08020          fmt = format;
08021          res = ast_translator_best_choice(&fmt, &native);
08022          if (res < 0) {
08023             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08024                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08025             ast_hangup(c);
08026             return NULL;
08027          }
08028          c->nativeformats = native;
08029       }
08030       c->readformat = ast_best_codec(c->nativeformats);
08031       c->writeformat = c->readformat;
08032    }
08033 
08034    return c;
08035 }
08036 
08037 static void *network_thread(void *ignore)
08038 {
08039    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08040       from the network, and queue them for delivery to the channels */
08041    int res, count;
08042    struct iax_frame *f, *freeme;
08043    if (timingfd > -1)
08044       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08045    for(;;) {
08046       /* Go through the queue, sending messages which have not yet been
08047          sent, and scheduling retransmissions if appropriate */
08048       ast_mutex_lock(&iaxq.lock);
08049       f = iaxq.head;
08050       count = 0;
08051       while(f) {
08052          freeme = NULL;
08053          if (!f->sentyet) {
08054             f->sentyet++;
08055             /* Send a copy immediately -- errors here are ok, so don't bother locking */
08056             if (iaxs[f->callno]) {
08057                send_packet(f);
08058                count++;
08059             } 
08060             if (f->retries < 0) {
08061                /* This is not supposed to be retransmitted */
08062                if (f->prev) 
08063                   f->prev->next = f->next;
08064                else
08065                   iaxq.head = f->next;
08066                if (f->next)
08067                   f->next->prev = f->prev;
08068                else
08069                   iaxq.tail = f->prev;
08070                iaxq.count--;
08071                /* Free the iax frame */
08072                freeme = f;
08073             } else {
08074                /* We need reliable delivery.  Schedule a retransmission */
08075                f->retries++;
08076                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08077             }
08078          }
08079          f = f->next;
08080          if (freeme)
08081             iax_frame_free(freeme);
08082       }
08083       ast_mutex_unlock(&iaxq.lock);
08084       if (count >= 20)
08085          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08086 
08087       /* Now do the IO, and run scheduled tasks */
08088       res = ast_sched_wait(sched);
08089       if ((res > 1000) || (res < 0))
08090          res = 1000;
08091       res = ast_io_wait(io, res);
08092       if (res >= 0) {
08093          if (res >= 20)
08094             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08095          count = ast_sched_runq(sched);
08096          if (count >= 20)
08097             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08098       }
08099    }
08100    return NULL;
08101 }
08102 
08103 static int start_network_thread(void)
08104 {
08105    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
08106 }
08107 
08108 static struct iax2_context *build_context(char *context)
08109 {
08110    struct iax2_context *con = malloc(sizeof(struct iax2_context));
08111    if (con) {
08112       ast_copy_string(con->context, context, sizeof(con->context));
08113       con->next = NULL;
08114    }
08115    return con;
08116 }
08117 
08118 static int get_auth_methods(char *value)
08119 {
08120    int methods = 0;
08121    if (strstr(value, "rsa"))
08122       methods |= IAX_AUTH_RSA;
08123    if (strstr(value, "md5"))
08124       methods |= IAX_AUTH_MD5;
08125    if (strstr(value, "plaintext"))
08126       methods |= IAX_AUTH_PLAINTEXT;
08127    return methods;
08128 }
08129 
08130 
08131 /*--- check_src_ip: Check if address can be used as packet source.
08132  returns:
08133  0  address available
08134  1  address unavailable
08135 -1  error
08136 */
08137 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08138 {
08139    int sd;
08140    int res;
08141    
08142    sd = socket(AF_INET, SOCK_DGRAM, 0);
08143    if (sd < 0) {
08144       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08145       return -1;
08146    }
08147 
08148    res = bind(sd, sa, salen);
08149    if (res < 0) {
08150       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08151       close(sd);
08152       return 1;
08153    }
08154 
08155    close(sd);
08156    return 0;
08157 }
08158 
08159 /*--- peer_set_srcaddr: Parse the "sourceaddress" value,
08160   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08161   not found. */
08162 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08163 {
08164    struct sockaddr_in sin;
08165    int nonlocal = 1;
08166    int port = IAX_DEFAULT_PORTNO;
08167    int sockfd = defaultsockfd;
08168    char *tmp;
08169    char *addr;
08170    char *portstr;
08171 
08172    tmp = ast_strdupa(srcaddr);
08173    if (!tmp) {
08174       ast_log(LOG_WARNING, "Out of memory!\n");
08175       return -1;
08176    }
08177 
08178    addr = strsep(&tmp, ":");
08179    portstr = tmp;
08180 
08181    if (portstr) {
08182       port = atoi(portstr);
08183       if (port < 1)
08184          port = IAX_DEFAULT_PORTNO;
08185    }
08186    
08187    if (!ast_get_ip(&sin, addr)) {
08188       struct ast_netsock *sock;
08189       int res;
08190 
08191       sin.sin_port = 0;
08192       sin.sin_family = AF_INET;
08193       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08194       if (res == 0) {
08195          /* ip address valid. */
08196          sin.sin_port = htons(port);
08197          sock = ast_netsock_find(netsock, &sin);
08198          if (sock) {
08199             sockfd = ast_netsock_sockfd(sock);
08200             nonlocal = 0;
08201          }
08202       }
08203    }
08204       
08205    peer->sockfd = sockfd;
08206 
08207    if (nonlocal) {
08208       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08209          srcaddr, peer->name);
08210       return -1;
08211    } else {
08212       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08213       return 0;
08214    }
08215 }
08216 
08217       
08218 /*--- build_peer: Create peer structure based on configuration */
08219 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, int temponly)
08220 {
08221    struct iax2_peer *peer;
08222    struct iax2_peer *prev;
08223    struct ast_ha *oldha = NULL;
08224    int maskfound=0;
08225    int found=0;
08226    prev = NULL;
08227    ast_mutex_lock(&peerl.lock);
08228    if (!temponly) {
08229       peer = peerl.peers;
08230       while(peer) {
08231          if (!strcmp(peer->name, name)) { 
08232             break;
08233          }
08234          prev = peer;
08235          peer = peer->next;
08236       }
08237    } else
08238       peer = NULL;   
08239    if (peer) {
08240       found++;
08241       oldha = peer->ha;
08242       peer->ha = NULL;
08243       /* Already in the list, remove it and it will be added back (or FREE'd) */
08244       if (prev) {
08245          prev->next = peer->next;
08246       } else {
08247          peerl.peers = peer->next;
08248       }
08249       ast_mutex_unlock(&peerl.lock);
08250    } else {
08251       ast_mutex_unlock(&peerl.lock);
08252       peer = malloc(sizeof(struct iax2_peer));
08253       if (peer) {
08254          memset(peer, 0, sizeof(struct iax2_peer));
08255          peer->expire = -1;
08256          peer->pokeexpire = -1;
08257          peer->sockfd = defaultsockfd;
08258       }
08259    }
08260    if (peer) {
08261       ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08262       peer->encmethods = iax2_encryption;
08263       peer->secret[0] = '\0';
08264       if (!found) {
08265          ast_copy_string(peer->name, name, sizeof(peer->name));
08266          peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08267          peer->expiry = min_reg_expire;
08268       }
08269       peer->prefs = prefs;
08270       peer->capability = iax2_capability;
08271       peer->smoothing = 0;
08272       peer->pokefreqok = DEFAULT_FREQ_OK;
08273       peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08274       peer->context[0] = '\0';
08275       peer->peercontext[0] = '\0';
08276       while(v) {
08277          if (!strcasecmp(v->name, "secret")) {
08278             ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
08279          } else if (!strcasecmp(v->name, "mailbox")) {
08280             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
08281          } else if (!strcasecmp(v->name, "dbsecret")) {
08282             ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
08283          } else if (!strcasecmp(v->name, "mailboxdetail")) {
08284             ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 
08285          } else if (!strcasecmp(v->name, "trunk")) {
08286             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08287             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08288                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08289                ast_clear_flag(peer, IAX_TRUNK);
08290             }
08291          } else if (!strcasecmp(v->name, "auth")) {
08292             peer->authmethods = get_auth_methods(v->value);
08293          } else if (!strcasecmp(v->name, "encryption")) {
08294             peer->encmethods = get_encrypt_methods(v->value);
08295          } else if (!strcasecmp(v->name, "notransfer")) {
08296             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08297          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08298             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08299          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08300             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08301          } else if (!strcasecmp(v->name, "host")) {
08302             if (!strcasecmp(v->value, "dynamic")) {
08303                /* They'll register with us */
08304                ast_set_flag(peer, IAX_DYNAMIC); 
08305                if (!found) {
08306                   /* Initialize stuff iff we're not found, otherwise
08307                      we keep going with what we had */
08308                   memset(&peer->addr.sin_addr, 0, 4);
08309                   if (peer->addr.sin_port) {
08310                      /* If we've already got a port, make it the default rather than absolute */
08311                      peer->defaddr.sin_port = peer->addr.sin_port;
08312                      peer->addr.sin_port = 0;
08313                   }
08314                }
08315             } else {
08316                /* Non-dynamic.  Make sure we become that way if we're not */
08317                if (peer->expire > -1)
08318                   ast_sched_del(sched, peer->expire);
08319                peer->expire = -1;
08320                ast_clear_flag(peer, IAX_DYNAMIC);
08321                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08322                   free(peer);
08323                   return NULL;
08324                }
08325                if (!peer->addr.sin_port)
08326                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08327             }
08328             if (!maskfound)
08329                inet_aton("255.255.255.255", &peer->mask);
08330          } else if (!strcasecmp(v->name, "defaultip")) {
08331             if (ast_get_ip(&peer->defaddr, v->value)) {
08332                free(peer);
08333                return NULL;
08334             }
08335          } else if (!strcasecmp(v->name, "sourceaddress")) {
08336             peer_set_srcaddr(peer, v->value);
08337          } else if (!strcasecmp(v->name, "permit") ||
08338                   !strcasecmp(v->name, "deny")) {
08339             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08340          } else if (!strcasecmp(v->name, "mask")) {
08341             maskfound++;
08342             inet_aton(v->value, &peer->mask);
08343          } else if (!strcasecmp(v->name, "context")) {
08344             if (ast_strlen_zero(peer->context))
08345                ast_copy_string(peer->context, v->value, sizeof(peer->context));
08346          } else if (!strcasecmp(v->name, "regexten")) {
08347             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
08348          } else if (!strcasecmp(v->name, "peercontext")) {
08349             if (ast_strlen_zero(peer->peercontext))
08350                ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext));
08351          } else if (!strcasecmp(v->name, "port")) {
08352             if (ast_test_flag(peer, IAX_DYNAMIC))
08353                peer->defaddr.sin_port = htons(atoi(v->value));
08354             else
08355                peer->addr.sin_port = htons(atoi(v->value));
08356          } else if (!strcasecmp(v->name, "username")) {
08357             ast_copy_string(peer->username, v->value, sizeof(peer->username));
08358          } else if (!strcasecmp(v->name, "allow")) {
08359             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08360          } else if (!strcasecmp(v->name, "disallow")) {
08361             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08362          } else if (!strcasecmp(v->name, "callerid")) {
08363             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name),
08364                            peer->cid_num, sizeof(peer->cid_num));
08365             ast_set_flag(peer, IAX_HASCALLERID);   
08366          } else if (!strcasecmp(v->name, "sendani")) {
08367             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08368          } else if (!strcasecmp(v->name, "inkeys")) {
08369             ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys));
08370          } else if (!strcasecmp(v->name, "outkey")) {
08371             ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
08372          } else if (!strcasecmp(v->name, "qualify")) {
08373             if (!strcasecmp(v->value, "no")) {
08374                peer->maxms = 0;
08375             } else if (!strcasecmp(v->value, "yes")) {
08376                peer->maxms = DEFAULT_MAXMS;
08377             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08378                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);
08379                peer->maxms = 0;
08380             }
08381          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08382             peer->smoothing = ast_true(v->value);
08383          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08384             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08385                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);
08386             }
08387          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08388             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08389                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);
08390             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08391          } else if (!strcasecmp(v->name, "timezone")) {
08392             ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag));
08393          }/* else if (strcasecmp(v->name,"type")) */
08394          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08395          v=v->next;
08396       }
08397       if (!peer->authmethods)
08398          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08399       ast_clear_flag(peer, IAX_DELME); 
08400       /* Make sure these are IPv4 addresses */
08401       peer->addr.sin_family = AF_INET;
08402    }
08403    if (oldha)
08404       ast_free_ha(oldha);
08405    return peer;
08406 }
08407 
08408 /*--- build_user: Create in-memory user structure from configuration */
08409 static struct iax2_user *build_user(const char *name, struct ast_variable *v, int temponly)
08410 {
08411    struct iax2_user *prev, *user;
08412    struct iax2_context *con, *conl = NULL;
08413    struct ast_ha *oldha = NULL;
08414    struct iax2_context *oldcon = NULL;
08415    int format;
08416    int oldcurauthreq = 0;
08417    char *varname = NULL, *varval = NULL;
08418    struct ast_variable *tmpvar = NULL;
08419    
08420    prev = NULL;
08421    ast_mutex_lock(&userl.lock);
08422    if (!temponly) {
08423       user = userl.users;
08424       while(user) {
08425          if (!strcmp(user->name, name)) { 
08426             break;
08427          }
08428          prev = user;
08429          user = user->next;
08430       }
08431    } else
08432       user = NULL;
08433    
08434    if (user) {
08435       oldcurauthreq = user->curauthreq;
08436       oldha = user->ha;
08437       oldcon = user->contexts;
08438       user->ha = NULL;
08439       user->contexts = NULL;
08440       /* Already in the list, remove it and it will be added back (or FREE'd) */
08441       if (prev) {
08442          prev->next = user->next;
08443       } else {
08444          userl.users = user->next;
08445       }
08446       ast_mutex_unlock(&userl.lock);
08447    } else {
08448       ast_mutex_unlock(&userl.lock);
08449       user = malloc(sizeof(struct iax2_user));
08450       if (user)
08451          memset(user, 0, sizeof(struct iax2_user));
08452    }
08453    
08454    if (user) {
08455       memset(user, 0, sizeof(struct iax2_user));
08456       user->maxauthreq = maxauthreq;
08457       user->curauthreq = oldcurauthreq;
08458       user->prefs = prefs;
08459       user->capability = iax2_capability;
08460       user->encmethods = iax2_encryption;
08461       ast_copy_string(user->name, name, sizeof(user->name));
08462       ast_copy_string(user->language, language, sizeof(user->language));
08463       ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08464       while(v) {
08465          if (!strcasecmp(v->name, "context")) {
08466             con = build_context(v->value);
08467             if (con) {
08468                if (conl)
08469                   conl->next = con;
08470                else
08471                   user->contexts = con;
08472                conl = con;
08473             }
08474          } else if (!strcasecmp(v->name, "permit") ||
08475                   !strcasecmp(v->name, "deny")) {
08476             user->ha = ast_append_ha(v->name, v->value, user->ha);
08477          } else if (!strcasecmp(v->name, "setvar")) {
08478             varname = ast_strdupa(v->value);
08479             if (varname && (varval = strchr(varname,'='))) {
08480                *varval = '\0';
08481                varval++;
08482                if((tmpvar = ast_variable_new(varname, varval))) {
08483                   tmpvar->next = user->vars; 
08484                   user->vars = tmpvar;
08485                }
08486             }
08487          } else if (!strcasecmp(v->name, "allow")) {
08488             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08489          } else if (!strcasecmp(v->name, "disallow")) {
08490             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08491          } else if (!strcasecmp(v->name, "trunk")) {
08492             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08493             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08494                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08495                ast_clear_flag(user, IAX_TRUNK);
08496             }
08497          } else if (!strcasecmp(v->name, "auth")) {
08498             user->authmethods = get_auth_methods(v->value);
08499          } else if (!strcasecmp(v->name, "encryption")) {
08500             user->encmethods = get_encrypt_methods(v->value);
08501          } else if (!strcasecmp(v->name, "notransfer")) {
08502             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08503          } else if (!strcasecmp(v->name, "codecpriority")) {
08504             if(!strcasecmp(v->value, "caller"))
08505                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08506             else if(!strcasecmp(v->value, "disabled"))
08507                ast_set_flag(user, IAX_CODEC_NOPREFS);
08508             else if(!strcasecmp(v->value, "reqonly")) {
08509                ast_set_flag(user, IAX_CODEC_NOCAP);
08510                ast_set_flag(user, IAX_CODEC_NOPREFS);
08511             }
08512          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08513             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);  
08514          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08515             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);   
08516          } else if (!strcasecmp(v->name, "dbsecret")) {
08517             ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret));
08518          } else if (!strcasecmp(v->name, "secret")) {
08519             if (!ast_strlen_zero(user->secret)) {
08520                strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
08521                strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1);
08522             } else
08523                ast_copy_string(user->secret, v->value, sizeof(user->secret));
08524          } else if (!strcasecmp(v->name, "callerid")) {
08525             ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
08526             ast_set_flag(user, IAX_HASCALLERID);   
08527          } else if (!strcasecmp(v->name, "accountcode")) {
08528             ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
08529          } else if (!strcasecmp(v->name, "language")) {
08530             ast_copy_string(user->language, v->value, sizeof(user->language));
08531          } else if (!strcasecmp(v->name, "amaflags")) {
08532             format = ast_cdr_amaflags2int(v->value);
08533             if (format < 0) {
08534                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08535             } else {
08536                user->amaflags = format;
08537             }
08538          } else if (!strcasecmp(v->name, "inkeys")) {
08539             ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
08540          } else if (!strcasecmp(v->name, "maxauthreq")) {
08541             user->maxauthreq = atoi(v->value);
08542             if (user->maxauthreq < 0)
08543                user->maxauthreq = 0;
08544          }/* else if (strcasecmp(v->name,"type")) */
08545          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08546          v = v->next;
08547       }
08548       if (!user->authmethods) {
08549          if (!ast_strlen_zero(user->secret)) {
08550             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08551             if (!ast_strlen_zero(user->inkeys))
08552                user->authmethods |= IAX_AUTH_RSA;
08553          } else if (!ast_strlen_zero(user->inkeys)) {
08554             user->authmethods = IAX_AUTH_RSA;
08555          } else {
08556             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08557          }
08558       }
08559       ast_clear_flag(user, IAX_DELME);
08560    }
08561    if (oldha)
08562       ast_free_ha(oldha);
08563    if (oldcon)
08564       free_context(oldcon);
08565    return user;
08566 }
08567 
08568 static void delete_users(void)
08569 {
08570    struct iax2_user *user;
08571    struct iax2_peer *peer;
08572    struct iax2_registry *reg, *regl;
08573 
08574    ast_mutex_lock(&userl.lock);
08575    for (user=userl.users;user;) {
08576       ast_set_flag(user, IAX_DELME);
08577       user = user->next;
08578    }
08579    ast_mutex_unlock(&userl.lock);
08580    for (reg = registrations;reg;) {
08581       regl = reg;
08582       reg = reg->next;
08583       if (regl->expire > -1) {
08584          ast_sched_del(sched, regl->expire);
08585       }
08586       if (regl->callno) {
08587          /* XXX Is this a potential lock?  I don't think so, but you never know */
08588          ast_mutex_lock(&iaxsl[regl->callno]);
08589          if (iaxs[regl->callno]) {
08590             iaxs[regl->callno]->reg = NULL;
08591             iax2_destroy_nolock(regl->callno);
08592          }
08593          ast_mutex_unlock(&iaxsl[regl->callno]);
08594       }
08595       free(regl);
08596    }
08597    registrations = NULL;
08598    ast_mutex_lock(&peerl.lock);
08599    for (peer=peerl.peers;peer;) {
08600       /* Assume all will be deleted, and we'll find out for sure later */
08601       ast_set_flag(peer, IAX_DELME);
08602       peer = peer->next;
08603    }
08604    ast_mutex_unlock(&peerl.lock);
08605 }
08606 
08607 static void destroy_user(struct iax2_user *user)
08608 {
08609    ast_free_ha(user->ha);
08610    free_context(user->contexts);
08611    if(user->vars) {
08612       ast_variables_destroy(user->vars);
08613       user->vars = NULL;
08614    }
08615    free(user);
08616 }
08617 
08618 static void prune_users(void)
08619 {
08620    struct iax2_user *user, *usernext, *userlast = NULL;
08621    ast_mutex_lock(&userl.lock);
08622    for (user=userl.users;user;) {
08623       usernext = user->next;
08624       if (ast_test_flag(user, IAX_DELME)) {
08625          destroy_user(user);
08626          if (userlast)
08627             userlast->next = usernext;
08628          else
08629             userl.users = usernext;
08630       } else
08631          userlast = user;
08632       user = usernext;
08633    }
08634    ast_mutex_unlock(&userl.lock);
08635 }
08636 
08637 static void destroy_peer(struct iax2_peer *peer)
08638 {
08639    int x;
08640    ast_free_ha(peer->ha);
08641    for (x=0;x<IAX_MAX_CALLS;x++) {
08642       ast_mutex_lock(&iaxsl[x]);
08643       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
08644          iax2_destroy(x);
08645       }
08646       ast_mutex_unlock(&iaxsl[x]);
08647    }
08648    /* Delete it, it needs to disappear */
08649    if (peer->expire > -1)
08650       ast_sched_del(sched, peer->expire);
08651    if (peer->pokeexpire > -1)
08652       ast_sched_del(sched, peer->pokeexpire);
08653    if (peer->callno > 0)
08654       iax2_destroy(peer->callno);
08655    register_peer_exten(peer, 0);
08656    if (peer->dnsmgr)
08657       ast_dnsmgr_release(peer->dnsmgr);
08658    free(peer);
08659 }
08660 
08661 static void prune_peers(void){
08662    /* Prune peers who still are supposed to be deleted */
08663    struct iax2_peer *peer, *peerlast, *peernext;
08664    ast_mutex_lock(&peerl.lock);
08665    peerlast = NULL;
08666    for (peer=peerl.peers;peer;) {
08667       peernext = peer->next;
08668       if (ast_test_flag(peer, IAX_DELME)) {
08669          destroy_peer(peer);
08670          if (peerlast)
08671             peerlast->next = peernext;
08672          else
08673             peerl.peers = peernext;
08674       } else
08675          peerlast = peer;
08676       peer=peernext;
08677    }
08678    ast_mutex_unlock(&peerl.lock);
08679 }
08680 
08681 static void set_timing(void)
08682 {
08683 #ifdef IAX_TRUNKING
08684    int bs = trunkfreq * 8;
08685    if (timingfd > -1) {
08686       if (
08687 #ifdef ZT_TIMERACK
08688          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08689 #endif         
08690          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08691          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08692    }
08693 #endif
08694 }
08695 
08696 
08697 /*--- set_config: Load configuration */
08698 static int set_config(char *config_file, int reload)
08699 {
08700    struct ast_config *cfg;
08701    int capability=iax2_capability;
08702    struct ast_variable *v;
08703    char *cat;
08704    char *utype;
08705    char *tosval;
08706    int format;
08707    int portno = IAX_DEFAULT_PORTNO;
08708    int  x;
08709    struct iax2_user *user;
08710    struct iax2_peer *peer;
08711    struct ast_netsock *ns;
08712 #if 0
08713    static unsigned short int last_port=0;
08714 #endif
08715 
08716    cfg = ast_config_load(config_file);
08717    
08718    if (!cfg) {
08719       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08720       return -1;
08721    }
08722 
08723    /* Reset global codec prefs */   
08724    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08725    
08726    /* Reset Global Flags */
08727    memset(&globalflags, 0, sizeof(globalflags));
08728    ast_set_flag(&globalflags, IAX_RTUPDATE);
08729 
08730 #ifdef SO_NO_CHECK
08731    nochecksums = 0;
08732 #endif
08733 
08734    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08735    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08736 
08737    maxauthreq = 0;
08738 
08739    v = ast_variable_browse(cfg, "general");
08740 
08741    /* Seed initial tos value */
08742    tosval = ast_variable_retrieve(cfg, "general", "tos");
08743    if (tosval) {
08744       if (ast_str2tos(tosval, &tos))
08745          ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n");
08746    }
08747    while(v) {
08748       if (!strcasecmp(v->name, "bindport")){ 
08749          if (reload)
08750             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
08751          else
08752             portno = atoi(v->value);
08753       } else if (!strcasecmp(v->name, "pingtime")) 
08754          ping_time = atoi(v->value);
08755       else if (!strcasecmp(v->name, "nochecksums")) {
08756 #ifdef SO_NO_CHECK
08757          if (ast_true(v->value))
08758             nochecksums = 1;
08759          else
08760             nochecksums = 0;
08761 #else
08762          if (ast_true(v->value))
08763             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
08764 #endif
08765       }
08766       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
08767          maxjitterbuffer = atoi(v->value);
08768 #ifdef NEWJB
08769       else if (!strcasecmp(v->name, "resyncthreshold")) 
08770          resyncthreshold = atoi(v->value);
08771       else if (!strcasecmp(v->name, "maxjitterinterps")) 
08772          maxjitterinterps = atoi(v->value);
08773 #endif
08774       else if (!strcasecmp(v->name, "jittershrinkrate")) 
08775          jittershrinkrate = atoi(v->value);
08776       else if (!strcasecmp(v->name, "maxexcessbuffer")) 
08777          max_jitter_buffer = atoi(v->value);
08778       else if (!strcasecmp(v->name, "minexcessbuffer")) 
08779          min_jitter_buffer = atoi(v->value);
08780       else if (!strcasecmp(v->name, "lagrqtime")) 
08781          lagrq_time = atoi(v->value);
08782       else if (!strcasecmp(v->name, "dropcount")) 
08783          iax2_dropcount = atoi(v->value);
08784       else if (!strcasecmp(v->name, "maxregexpire")) 
08785          max_reg_expire = atoi(v->value);
08786       else if (!strcasecmp(v->name, "minregexpire")) 
08787          min_reg_expire = atoi(v->value);
08788       else if (!strcasecmp(v->name, "bindaddr")) {
08789          if (reload) {
08790             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
08791          } else {
08792             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
08793                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
08794             } else {
08795                if (option_verbose > 1) {
08796                   if (strchr(v->value, ':'))
08797                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
08798                   else
08799                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
08800                }
08801                if (defaultsockfd < 0) 
08802                   defaultsockfd = ast_netsock_sockfd(ns);
08803                ast_netsock_unref(ns);
08804             }
08805          }
08806       } else if (!strcasecmp(v->name, "authdebug"))
08807          authdebug = ast_true(v->value);
08808       else if (!strcasecmp(v->name, "encryption"))
08809          iax2_encryption = get_encrypt_methods(v->value);
08810       else if (!strcasecmp(v->name, "notransfer"))
08811          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
08812       else if (!strcasecmp(v->name, "codecpriority")) {
08813          if(!strcasecmp(v->value, "caller"))
08814             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
08815          else if(!strcasecmp(v->value, "disabled"))
08816             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08817          else if(!strcasecmp(v->value, "reqonly")) {
08818             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
08819             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08820          }
08821       } else if (!strcasecmp(v->name, "jitterbuffer"))
08822          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
08823       else if (!strcasecmp(v->name, "forcejitterbuffer"))
08824          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
08825       else if (!strcasecmp(v->name, "delayreject"))
08826          delayreject = ast_true(v->value);
08827       else if (!strcasecmp(v->name, "mailboxdetail"))
08828          ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL);   
08829       else if (!strcasecmp(v->name, "rtcachefriends"))
08830          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
08831       else if (!strcasecmp(v->name, "rtignoreregexpire"))
08832          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
08833       else if (!strcasecmp(v->name, "rtupdate"))
08834          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
08835       else if (!strcasecmp(v->name, "trunktimestamps"))
08836          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
08837       else if (!strcasecmp(v->name, "rtautoclear")) {
08838          int i = atoi(v->value);
08839          if(i > 0)
08840             global_rtautoclear = i;
08841          else
08842             i = 0;
08843          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
08844       } else if (!strcasecmp(v->name, "trunkfreq")) {
08845          trunkfreq = atoi(v->value);
08846          if (trunkfreq < 10)
08847             trunkfreq = 10;
08848       } else if (!strcasecmp(v->name, "autokill")) {
08849          if (sscanf(v->value, "%d", &x) == 1) {
08850             if (x >= 0)
08851                autokill = x;
08852             else
08853                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
08854          } else if (ast_true(v->value)) {
08855             autokill = DEFAULT_MAXMS;
08856          } else {
08857             autokill = 0;
08858          }
08859       } else if (!strcasecmp(v->name, "bandwidth")) {
08860          if (!strcasecmp(v->value, "low")) {
08861             capability = IAX_CAPABILITY_LOWBANDWIDTH;
08862          } else if (!strcasecmp(v->value, "medium")) {
08863             capability = IAX_CAPABILITY_MEDBANDWIDTH;
08864          } else if (!strcasecmp(v->value, "high")) {
08865             capability = IAX_CAPABILITY_FULLBANDWIDTH;
08866          } else
08867             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
08868       } else if (!strcasecmp(v->name, "allow")) {
08869          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
08870       } else if (!strcasecmp(v->name, "disallow")) {
08871          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
08872       } else if (!strcasecmp(v->name, "register")) {
08873          iax2_register(v->value, v->lineno);
08874       } else if (!strcasecmp(v->name, "iaxcompat")) {
08875          iaxcompat = ast_true(v->value);
08876       } else if (!strcasecmp(v->name, "regcontext")) {
08877          ast_copy_string(regcontext, v->value, sizeof(regcontext));
08878          /* Create context if it doesn't exist already */
08879          if (!ast_context_find(regcontext))
08880             ast_context_create(NULL, regcontext, channeltype);
08881       } else if (!strcasecmp(v->name, "tos")) {
08882          if (ast_str2tos(v->value, &tos))
08883             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
08884       } else if (!strcasecmp(v->name, "accountcode")) {
08885          ast_copy_string(accountcode, v->value, sizeof(accountcode));
08886       } else if (!strcasecmp(v->name, "amaflags")) {
08887          format = ast_cdr_amaflags2int(v->value);
08888          if (format < 0) {
08889             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08890          } else {
08891             amaflags = format;
08892          }
08893       } else if (!strcasecmp(v->name, "language")) {
08894                         ast_copy_string(language, v->value, sizeof(language));
08895       } else if (!strcasecmp(v->name, "maxauthreq")) {
08896          maxauthreq = atoi(v->value);
08897          if (maxauthreq < 0)
08898             maxauthreq = 0;
08899       } /*else if (strcasecmp(v->name,"type")) */
08900       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08901       v = v->next;
08902    }
08903    
08904    if (defaultsockfd < 0) {
08905       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
08906          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
08907       } else {
08908          if (option_verbose > 1)
08909             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
08910          defaultsockfd = ast_netsock_sockfd(ns);
08911          ast_netsock_unref(ns);
08912       }
08913    }
08914    
08915    if (min_reg_expire > max_reg_expire) {
08916       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
08917          min_reg_expire, max_reg_expire, max_reg_expire);
08918       min_reg_expire = max_reg_expire;
08919    }
08920    iax2_capability = capability;
08921    cat = ast_category_browse(cfg, NULL);
08922    while(cat) {
08923       if (strcasecmp(cat, "general")) {
08924          utype = ast_variable_retrieve(cfg, cat, "type");
08925          if (utype) {
08926             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
08927                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
08928                if (user) {
08929                   ast_mutex_lock(&userl.lock);
08930                   user->next = userl.users;
08931                   userl.users = user;
08932                   ast_mutex_unlock(&userl.lock);
08933                }
08934             }
08935             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
08936                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
08937                if (peer) {
08938                   ast_mutex_lock(&peerl.lock);
08939                   peer->next = peerl.peers;
08940                   peerl.peers = peer;
08941                   ast_mutex_unlock(&peerl.lock);
08942                   if (ast_test_flag(peer, IAX_DYNAMIC))
08943                      reg_source_db(peer);
08944                }
08945             } else if (strcasecmp(utype, "user")) {
08946                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
08947             }
08948          } else
08949             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
08950       }
08951       cat = ast_category_browse(cfg, cat);
08952    }
08953    ast_config_destroy(cfg);
08954    set_timing();
08955    return capability;
08956 }
08957 
08958 static int reload_config(void)
08959 {
08960    char *config = "iax.conf";
08961    struct iax2_registry *reg;
08962    struct iax2_peer *peer;
08963    ast_copy_string(accountcode, "", sizeof(accountcode));
08964    ast_copy_string(language, "", sizeof(language));
08965    amaflags = 0;
08966    delayreject = 0;
08967    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
08968    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
08969    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
08970    delete_users();
08971    set_config(config,1);
08972    prune_peers();
08973    prune_users();
08974    for (reg = registrations; reg; reg = reg->next)
08975       iax2_do_register(reg);
08976    /* Qualify hosts, too */
08977    ast_mutex_lock(&peerl.lock);
08978    for (peer = peerl.peers; peer; peer = peer->next)
08979       iax2_poke_peer(peer, 0);
08980    ast_mutex_unlock(&peerl.lock);
08981    reload_firmware();
08982    iax_provision_reload();
08983    return 0;
08984 }
08985 
08986 static int iax2_reload(int fd, int argc, char *argv[])
08987 {
08988    return reload_config();
08989 }
08990 
08991 int reload(void)
08992 {
08993    return reload_config();
08994 }
08995 
08996 static int cache_get_callno_locked(const char *data)
08997 {
08998    struct sockaddr_in sin;
08999    int x;
09000    int callno;
09001    struct iax_ie_data ied;
09002    struct create_addr_info cai;
09003    struct parsed_dial_string pds;
09004    char *tmpstr;
09005 
09006    for (x=0; x<IAX_MAX_CALLS; x++) {
09007       /* Look for an *exact match* call.  Once a call is negotiated, it can only
09008          look up entries for a single context */
09009       if (!ast_mutex_trylock(&iaxsl[x])) {
09010          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09011             return x;
09012          ast_mutex_unlock(&iaxsl[x]);
09013       }
09014    }
09015 
09016    /* No match found, we need to create a new one */
09017 
09018    memset(&cai, 0, sizeof(cai));
09019    memset(&ied, 0, sizeof(ied));
09020    memset(&pds, 0, sizeof(pds));
09021 
09022    tmpstr = ast_strdupa(data);
09023    parse_dial_string(tmpstr, &pds);
09024 
09025    /* Populate our address from the given */
09026    if (create_addr(pds.peer, &sin, &cai))
09027       return -1;
09028 
09029    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09030       pds.peer, pds.username, pds.password, pds.context);
09031 
09032    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09033    if (callno < 1) {
09034       ast_log(LOG_WARNING, "Unable to create call\n");
09035       return -1;
09036    }
09037 
09038    ast_mutex_lock(&iaxsl[callno]);
09039    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
09040    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09041 
09042    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09043    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09044    /* the string format is slightly different from a standard dial string,
09045       because the context appears in the 'exten' position
09046    */
09047    if (pds.exten)
09048       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09049    if (pds.username)
09050       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09051    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09052    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09053    /* Keep password handy */
09054    if (pds.password)
09055       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
09056    if (pds.key)
09057       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
09058    /* Start the call going */
09059    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09060 
09061    return callno;
09062 }
09063 
09064 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
09065 {
09066    struct iax2_dpcache *dp, *prev = NULL, *next;
09067    struct timeval tv;
09068    int x;
09069    int com[2];
09070    int timeout;
09071    int old=0;
09072    int outfd;
09073    int abort;
09074    int callno;
09075    struct ast_channel *c;
09076    struct ast_frame *f;
09077    gettimeofday(&tv, NULL);
09078    dp = dpcache;
09079    while(dp) {
09080       next = dp->next;
09081       /* Expire old caches */
09082       if (ast_tvcmp(tv, dp->expiry) > 0) {
09083             /* It's expired, let it disappear */
09084             if (prev)
09085                prev->next = dp->next;
09086             else
09087                dpcache = dp->next;
09088             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09089                /* Free memory and go again */
09090                free(dp);
09091             } else {
09092                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);
09093             }
09094             dp = next;
09095             continue;
09096       }
09097       /* We found an entry that matches us! */
09098       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
09099          break;
09100       prev = dp;
09101       dp = next;
09102    }
09103    if (!dp) {
09104       /* No matching entry.  Create a new one. */
09105       /* First, can we make a callno? */
09106       callno = cache_get_callno_locked(data);
09107       if (callno < 0) {
09108          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09109          return NULL;
09110       }
09111       dp = malloc(sizeof(struct iax2_dpcache));
09112       if (!dp) {
09113          ast_mutex_unlock(&iaxsl[callno]);
09114          return NULL;
09115       }
09116       memset(dp, 0, sizeof(struct iax2_dpcache));
09117       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09118       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09119       gettimeofday(&dp->expiry, NULL);
09120       dp->orig = dp->expiry;
09121       /* Expires in 30 mins by default */
09122       dp->expiry.tv_sec += iaxdefaultdpcache;
09123       dp->next = dpcache;
09124       dp->flags = CACHE_FLAG_PENDING;
09125       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09126          dp->waiters[x] = -1;
09127       dpcache = dp;
09128       dp->peer = iaxs[callno]->dpentries;
09129       iaxs[callno]->dpentries = dp;
09130       /* Send the request if we're already up */
09131       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09132          iax2_dprequest(dp, callno);
09133       ast_mutex_unlock(&iaxsl[callno]);
09134    }
09135    /* By here we must have a dp */
09136    if (dp->flags & CACHE_FLAG_PENDING) {
09137       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09138          for a reply to come back so long as it's pending */
09139       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09140          /* Find an empty slot */
09141          if (dp->waiters[x] < 0)
09142             break;
09143       }
09144       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09145          ast_log(LOG_WARNING, "No more waiter positions available\n");
09146          return NULL;
09147       }
09148       if (pipe(com)) {
09149          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09150          return NULL;
09151       }
09152       dp->waiters[x] = com[1];
09153       /* Okay, now we wait */
09154       timeout = iaxdefaulttimeout * 1000;
09155       /* Temporarily unlock */
09156       ast_mutex_unlock(&dpcache_lock);
09157       /* Defer any dtmf */
09158       if (chan)
09159          old = ast_channel_defer_dtmf(chan);
09160       abort = 0;
09161       while(timeout) {
09162          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09163          if (outfd > -1) {
09164             break;
09165          }
09166          if (c) {
09167             f = ast_read(c);
09168             if (f)
09169                ast_frfree(f);
09170             else {
09171                /* Got hung up on, abort! */
09172                break;
09173                abort = 1;
09174             }
09175          }
09176       }
09177       if (!timeout) {
09178          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09179       }
09180       ast_mutex_lock(&dpcache_lock);
09181       dp->waiters[x] = -1;
09182       close(com[1]);
09183       close(com[0]);
09184       if (abort) {
09185          /* Don't interpret anything, just abort.  Not sure what th epoint
09186            of undeferring dtmf on a hung up channel is but hey whatever */
09187          if (!old && chan)
09188             ast_channel_undefer_dtmf(chan);
09189          return NULL;
09190       }
09191       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09192          /* Now to do non-independent analysis the results of our wait */
09193          if (dp->flags & CACHE_FLAG_PENDING) {
09194             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09195                pending.  Don't let it take as long to timeout. */
09196             dp->flags &= ~CACHE_FLAG_PENDING;
09197             dp->flags |= CACHE_FLAG_TIMEOUT;
09198             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09199                systems without leaving it unavailable once the server comes back online */
09200             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09201             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09202                if (dp->waiters[x] > -1)
09203                   write(dp->waiters[x], "asdf", 4);
09204          }
09205       }
09206       /* Our caller will obtain the rest */
09207       if (!old && chan)
09208          ast_channel_undefer_dtmf(chan);
09209    }
09210    return dp;  
09211 }
09212 
09213 /*--- iax2_exists: Part of the IAX2 switch interface ---*/
09214 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09215 {
09216    struct iax2_dpcache *dp;
09217    int res = 0;
09218 #if 0
09219    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09220 #endif
09221    if ((priority != 1) && (priority != 2))
09222       return 0;
09223    ast_mutex_lock(&dpcache_lock);
09224    dp = find_cache(chan, data, context, exten, priority);
09225    if (dp) {
09226       if (dp->flags & CACHE_FLAG_EXISTS)
09227          res= 1;
09228    }
09229    ast_mutex_unlock(&dpcache_lock);
09230    if (!dp) {
09231       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09232    }
09233    return res;
09234 }
09235 
09236 /*--- iax2_canmatch: part of the IAX2 dial plan switch interface */
09237 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09238 {
09239    int res = 0;
09240    struct iax2_dpcache *dp;
09241 #if 0
09242    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09243 #endif
09244    if ((priority != 1) && (priority != 2))
09245       return 0;
09246    ast_mutex_lock(&dpcache_lock);
09247    dp = find_cache(chan, data, context, exten, priority);
09248    if (dp) {
09249       if (dp->flags & CACHE_FLAG_CANEXIST)
09250          res= 1;
09251    }
09252    ast_mutex_unlock(&dpcache_lock);
09253    if (!dp) {
09254       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09255    }
09256    return res;
09257 }
09258 
09259 /*--- iax2_matchmore: Part of the IAX2 Switch interface */
09260 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09261 {
09262    int res = 0;
09263    struct iax2_dpcache *dp;
09264 #if 0
09265    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09266 #endif
09267    if ((priority != 1) && (priority != 2))
09268       return 0;
09269    ast_mutex_lock(&dpcache_lock);
09270    dp = find_cache(chan, data, context, exten, priority);
09271    if (dp) {
09272       if (dp->flags & CACHE_FLAG_MATCHMORE)
09273          res= 1;
09274    }
09275    ast_mutex_unlock(&dpcache_lock);
09276    if (!dp) {
09277       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09278    }
09279    return res;
09280 }
09281 
09282 /*--- iax2_exec: Execute IAX2 dialplan switch */
09283 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
09284 {
09285    char odata[256];
09286    char req[256];
09287    char *ncontext;
09288    char *dialstatus;
09289    struct iax2_dpcache *dp;
09290    struct ast_app *dial;
09291 #if 0
09292    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);
09293 #endif
09294    if (priority == 2) {
09295       /* Indicate status, can be overridden in dialplan */
09296       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09297       if (dialstatus) {
09298          dial = pbx_findapp(dialstatus);
09299          if (dial) 
09300             pbx_exec(chan, dial, "", newstack);
09301       }
09302       return -1;
09303    } else if (priority != 1)
09304       return -1;
09305    ast_mutex_lock(&dpcache_lock);
09306    dp = find_cache(chan, data, context, exten, priority);
09307    if (dp) {
09308       if (dp->flags & CACHE_FLAG_EXISTS) {
09309          ast_copy_string(odata, data, sizeof(odata));
09310          ncontext = strchr(odata, '/');
09311          if (ncontext) {
09312             *ncontext = '\0';
09313             ncontext++;
09314             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09315          } else {
09316             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09317          }
09318          if (option_verbose > 2)
09319             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09320       } else {
09321          ast_mutex_unlock(&dpcache_lock);
09322          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09323          return -1;
09324       }
09325    }
09326    ast_mutex_unlock(&dpcache_lock);
09327    dial = pbx_findapp("Dial");
09328    if (dial) {
09329       return pbx_exec(chan, dial, req, newstack);
09330    } else {
09331       ast_log(LOG_WARNING, "No dial application registered\n");
09332    }
09333    return -1;
09334 }
09335 
09336 static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
09337 {
09338    char *ret = NULL;
09339    struct iax2_peer *peer;
09340    char *peername, *colname;
09341    char iabuf[INET_ADDRSTRLEN];
09342 
09343    if (!(peername = ast_strdupa(data))) {
09344       ast_log(LOG_ERROR, "Memory Error!\n");
09345       return ret;
09346    }
09347 
09348    /* if our channel, return the IP address of the endpoint of current channel */
09349    if (!strcmp(peername,"CURRENTCHANNEL")) {
09350            unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09351       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
09352       return buf;
09353    }
09354 
09355    if ((colname = strchr(peername, ':'))) {
09356       *colname = '\0';
09357       colname++;
09358    } else {
09359       colname = "ip";
09360    }
09361    if (!(peer = find_peer(peername, 1)))
09362       return ret;
09363 
09364    if (!strcasecmp(colname, "ip")) {
09365       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09366    } else  if (!strcasecmp(colname, "status")) {
09367       peer_status(peer, buf, len); 
09368    } else  if (!strcasecmp(colname, "mailbox")) {
09369       ast_copy_string(buf, peer->mailbox, len);
09370    } else  if (!strcasecmp(colname, "context")) {
09371       ast_copy_string(buf, peer->context, len);
09372    } else  if (!strcasecmp(colname, "expire")) {
09373       snprintf(buf, len, "%d", peer->expire);
09374    } else  if (!strcasecmp(colname, "dynamic")) {
09375       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09376    } else  if (!strcasecmp(colname, "callerid_name")) {
09377       ast_copy_string(buf, peer->cid_name, len);
09378    } else  if (!strcasecmp(colname, "callerid_num")) {
09379       ast_copy_string(buf, peer->cid_num, len);
09380    } else  if (!strcasecmp(colname, "codecs")) {
09381       ast_getformatname_multiple(buf, len -1, peer->capability);
09382    } else  if (!strncasecmp(colname, "codec[", 6)) {
09383       char *codecnum, *ptr;
09384       int index = 0, codec = 0;
09385       
09386       codecnum = strchr(colname, '[');
09387       *codecnum = '\0';
09388       codecnum++;
09389       if ((ptr = strchr(codecnum, ']'))) {
09390          *ptr = '\0';
09391       }
09392       index = atoi(codecnum);
09393       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09394          ast_copy_string(buf, ast_getformatname(codec), len);
09395       }
09396    }
09397    ret = buf;
09398 
09399    return ret;
09400 }
09401 
09402 struct ast_custom_function iaxpeer_function = {
09403     .name = "IAXPEER",
09404     .synopsis = "Gets IAX peer information",
09405     .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[:item])",
09406     .read = function_iaxpeer,
09407    .desc = "If peername specified, valid items are:\n"
09408    "- ip (default)          The IP address.\n"
09409    "- status                The peer's status (if qualify=yes)\n"
09410    "- mailbox               The configured mailbox.\n"
09411    "- context               The configured context.\n"
09412    "- expire                The epoch time of the next expire.\n"
09413    "- dynamic               Is it dynamic? (yes/no).\n"
09414    "- callerid_name         The configured Caller ID name.\n"
09415    "- callerid_num          The configured Caller ID number.\n"
09416    "- codecs                The configured codecs.\n"
09417    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
09418    "\n"
09419    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
09420    "\n"
09421 };
09422 
09423 
09424 /*--- iax2_devicestate: Part of the device state notification system ---*/
09425 static int iax2_devicestate(void *data) 
09426 {
09427    struct parsed_dial_string pds;
09428    char *tmp = ast_strdupa(data);
09429    struct iax2_peer *p;
09430    int res = AST_DEVICE_INVALID;
09431 
09432    memset(&pds, 0, sizeof(pds));
09433    parse_dial_string(tmp, &pds);
09434    if (!pds.peer || ast_strlen_zero(pds.peer))
09435       return res;
09436    
09437    if (option_debug > 2)
09438       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09439 
09440    /* SLD: FIXME: second call to find_peer during registration */
09441    if (!(p = find_peer(pds.peer, 1)))
09442       return res;
09443 
09444    res = AST_DEVICE_UNAVAILABLE;
09445    if (option_debug > 2) 
09446       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09447          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09448    
09449    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09450        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09451       /* Peer is registered, or have default IP address
09452          and a valid registration */
09453       if (p->historicms == 0 || p->historicms <= p->maxms)
09454          /* let the core figure out whether it is in use or not */
09455          res = AST_DEVICE_UNKNOWN;  
09456    }
09457 
09458    if (ast_test_flag(p, IAX_TEMPONLY))
09459       destroy_peer(p);
09460 
09461    return res;
09462 }
09463 
09464 static struct ast_switch iax2_switch = 
09465 {
09466    name:          "IAX2",
09467    description:      "IAX Remote Dialplan Switch",
09468    exists:        iax2_exists,
09469    canmatch:      iax2_canmatch,
09470    exec:       iax2_exec,
09471    matchmore:     iax2_matchmore,
09472 };
09473 
09474 static char show_stats_usage[] =
09475 "Usage: iax show stats\n"
09476 "       Display statistics on IAX channel driver.\n";
09477 
09478 static char show_cache_usage[] =
09479 "Usage: iax show cache\n"
09480 "       Display currently cached IAX Dialplan results.\n";
09481 
09482 static char show_peer_usage[] =
09483 "Usage: iax show peer <name>\n"
09484 "       Display details on specific IAX peer\n";
09485 
09486 static char prune_realtime_usage[] =
09487 "Usage: iax2 prune realtime [<peername>|all]\n"
09488 "       Prunes object(s) from the cache\n";
09489 
09490 static char iax2_reload_usage[] =
09491 "Usage: iax2 reload\n"
09492 "       Reloads IAX configuration from iax.conf\n";
09493 
09494 static char show_prov_usage[] =
09495 "Usage: iax2 provision <host> <template> [forced]\n"
09496 "       Provisions the given peer or IP address using a template\n"
09497 "       matching either 'template' or '*' if the template is not\n"
09498 "       found.  If 'forced' is specified, even empty provisioning\n"
09499 "       fields will be provisioned as empty fields.\n";
09500 
09501 static char show_users_usage[] = 
09502 "Usage: iax2 show users [like <pattern>]\n"
09503 "       Lists all known IAX2 users.\n"
09504 "       Optional regular expression pattern is used to filter the user list.\n";
09505 
09506 static char show_channels_usage[] = 
09507 "Usage: iax2 show channels\n"
09508 "       Lists all currently active IAX channels.\n";
09509 
09510 static char show_netstats_usage[] = 
09511 "Usage: iax2 show netstats\n"
09512 "       Lists network status for all currently active IAX channels.\n";
09513 
09514 static char show_peers_usage[] = 
09515 "Usage: iax2 show peers [registered] [like <pattern>]\n"
09516 "       Lists all known IAX2 peers.\n"
09517 "       Optional 'registered' argument lists only peers with known addresses.\n"
09518 "       Optional regular expression pattern is used to filter the peer list.\n";
09519 
09520 static char show_firmware_usage[] = 
09521 "Usage: iax2 show firmware\n"
09522 "       Lists all known IAX firmware images.\n";
09523 
09524 static char show_reg_usage[] =
09525 "Usage: iax2 show registry\n"
09526 "       Lists all registration requests and status.\n";
09527 
09528 static char debug_usage[] = 
09529 "Usage: iax2 debug\n"
09530 "       Enables dumping of IAX packets for debugging purposes\n";
09531 
09532 static char no_debug_usage[] = 
09533 "Usage: iax2 no debug\n"
09534 "       Disables dumping of IAX packets for debugging purposes\n";
09535 
09536 static char debug_trunk_usage[] =
09537 "Usage: iax2 trunk debug\n"
09538 "       Requests current status of IAX trunking\n";
09539 
09540 static char no_debug_trunk_usage[] =
09541 "Usage: iax2 no trunk debug\n"
09542 "       Requests current status of IAX trunking\n";
09543 
09544 static char debug_jb_usage[] =
09545 "Usage: iax2 jb debug\n"
09546 "       Enables jitterbuffer debugging information\n";
09547 
09548 static char no_debug_jb_usage[] =
09549 "Usage: iax2 no jb debug\n"
09550 "       Disables jitterbuffer debugging information\n";
09551 
09552 static char iax2_test_losspct_usage[] =
09553 "Usage: iax2 test losspct <percentage>\n"
09554 "       For testing, throws away <percentage> percent of incoming packets\n";
09555 
09556 #ifdef IAXTESTS
09557 static char iax2_test_late_usage[] =
09558 "Usage: iax2 test late <ms>\n"
09559 "       For testing, count the next frame as <ms> ms late\n";
09560 
09561 static char iax2_test_resync_usage[] =
09562 "Usage: iax2 test resync <ms>\n"
09563 "       For testing, adjust all future frames by <ms> ms\n";
09564 
09565 static char iax2_test_jitter_usage[] =
09566 "Usage: iax2 test jitter <ms> <pct>\n"
09567 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
09568 #endif /* IAXTESTS */
09569 
09570 static struct ast_cli_entry iax2_cli[] = {
09571    { { "iax2", "set", "jitter", NULL }, iax2_set_jitter,
09572      "Sets IAX jitter buffer", jitter_usage },
09573    { { "iax2", "show", "stats", NULL }, iax2_show_stats,
09574      "Display IAX statistics", show_stats_usage },
09575    { { "iax2", "show", "cache", NULL }, iax2_show_cache,
09576      "Display IAX cached dialplan", show_cache_usage },
09577    { { "iax2", "show", "peer", NULL }, iax2_show_peer,
09578      "Show details on specific IAX peer", show_peer_usage, complete_iax2_show_peer },
09579    { { "iax2", "prune", "realtime", NULL }, iax2_prune_realtime,
09580      "Prune a cached realtime lookup", prune_realtime_usage, complete_iax2_show_peer },
09581    { { "iax2", "reload", NULL }, iax2_reload,
09582      "Reload IAX configuration", iax2_reload_usage },
09583    { { "iax2", "show", "users", NULL }, iax2_show_users,
09584      "Show defined IAX users", show_users_usage },
09585    { { "iax2", "show", "firmware", NULL }, iax2_show_firmware,
09586      "Show available IAX firmwares", show_firmware_usage },
09587    { { "iax2", "show", "channels", NULL }, iax2_show_channels,
09588      "Show active IAX channels", show_channels_usage },
09589    { { "iax2", "show", "netstats", NULL }, iax2_show_netstats,
09590      "Show active IAX channel netstats", show_netstats_usage },
09591    { { "iax2", "show", "peers", NULL }, iax2_show_peers,
09592      "Show defined IAX peers", show_peers_usage },
09593    { { "iax2", "show", "registry", NULL }, iax2_show_registry,
09594      "Show IAX registration status", show_reg_usage },
09595    { { "iax2", "debug", NULL }, iax2_do_debug,
09596      "Enable IAX debugging", debug_usage },
09597    { { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug,
09598      "Enable IAX trunk debugging", debug_trunk_usage },
09599    { { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug,
09600      "Enable IAX jitterbuffer debugging", debug_jb_usage },
09601    { { "iax2", "no", "debug", NULL }, iax2_no_debug,
09602      "Disable IAX debugging", no_debug_usage },
09603    { { "iax2", "no", "trunk", "debug", NULL }, iax2_no_trunk_debug,
09604      "Disable IAX trunk debugging", no_debug_trunk_usage },
09605    { { "iax2", "no", "jb", "debug", NULL }, iax2_no_jb_debug,
09606      "Disable IAX jitterbuffer debugging", no_debug_jb_usage },
09607    { { "iax2", "test", "losspct", NULL }, iax2_test_losspct,
09608      "Set IAX2 incoming frame loss percentage", iax2_test_losspct_usage },
09609    { { "iax2", "provision", NULL }, iax2_prov_cmd,
09610      "Provision an IAX device", show_prov_usage, iax2_prov_complete_template_3rd },
09611 #ifdef IAXTESTS
09612    { { "iax2", "test", "late", NULL }, iax2_test_late,
09613      "Test the receipt of a late frame", iax2_test_late_usage },
09614    { { "iax2", "test", "resync", NULL }, iax2_test_resync,
09615      "Test a resync in received timestamps", iax2_test_resync_usage },
09616    { { "iax2", "test", "jitter", NULL }, iax2_test_jitter,
09617      "Simulates jitter for testing", iax2_test_jitter_usage },
09618 #endif /* IAXTESTS */
09619 };
09620 
09621 static int __unload_module(void)
09622 {
09623    int x;
09624    /* Cancel the network thread, close the net socket */
09625    if (netthreadid != AST_PTHREADT_NULL) {
09626       pthread_cancel(netthreadid);
09627       pthread_join(netthreadid, NULL);
09628    }
09629    ast_netsock_release(netsock);
09630    for (x=0;x<IAX_MAX_CALLS;x++)
09631       if (iaxs[x])
09632          iax2_destroy(x);
09633    ast_manager_unregister( "IAXpeers" );
09634    ast_manager_unregister( "IAXnetstats" );
09635    ast_unregister_application(papp);
09636    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09637    ast_unregister_switch(&iax2_switch);
09638    ast_channel_unregister(&iax2_tech);
09639    delete_users();
09640    iax_provision_unload();
09641    sched_context_destroy(sched);
09642    return 0;
09643 }
09644 
09645 int unload_module()
09646 {
09647    ast_mutex_destroy(&iaxq.lock);
09648    ast_mutex_destroy(&userl.lock);
09649    ast_mutex_destroy(&peerl.lock);
09650    ast_mutex_destroy(&waresl.lock);
09651    ast_custom_function_unregister(&iaxpeer_function);
09652    return __unload_module();
09653 }
09654 
09655 
09656 /*--- load_module: Load IAX2 module, load configuraiton ---*/
09657 int load_module(void)
09658 {
09659    char *config = "iax.conf";
09660    int res = 0;
09661    int x;
09662    struct iax2_registry *reg;
09663    struct iax2_peer *peer;
09664    
09665    ast_custom_function_register(&iaxpeer_function);
09666 
09667    iax_set_output(iax_debug_output);
09668    iax_set_error(iax_error_output);
09669 #ifdef NEWJB
09670    jb_setoutput(jb_error_output, jb_warning_output, NULL);
09671 #endif
09672    
09673 #ifdef IAX_TRUNKING
09674 #ifdef ZT_TIMERACK
09675    timingfd = open("/dev/zap/timer", O_RDWR);
09676    if (timingfd < 0)
09677 #endif
09678       timingfd = open("/dev/zap/pseudo", O_RDWR);
09679    if (timingfd < 0) 
09680       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
09681 #endif      
09682 
09683    memset(iaxs, 0, sizeof(iaxs));
09684 
09685    for (x=0;x<IAX_MAX_CALLS;x++)
09686       ast_mutex_init(&iaxsl[x]);
09687    
09688    io = io_context_create();
09689    sched = sched_context_create();
09690    
09691    if (!io || !sched) {
09692       ast_log(LOG_ERROR, "Out of memory\n");
09693       return -1;
09694    }
09695 
09696    netsock = ast_netsock_list_alloc();
09697    if (!netsock) {
09698       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
09699       return -1;
09700    }
09701    ast_netsock_init(netsock);
09702 
09703    ast_mutex_init(&iaxq.lock);
09704    ast_mutex_init(&userl.lock);
09705    ast_mutex_init(&peerl.lock);
09706    ast_mutex_init(&waresl.lock);
09707    
09708    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09709 
09710    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
09711    
09712    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
09713    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
09714 
09715    set_config(config, 0);
09716 
09717    if (ast_channel_register(&iax2_tech)) {
09718       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
09719       __unload_module();
09720       return -1;
09721    }
09722 
09723    if (ast_register_switch(&iax2_switch)) 
09724       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
09725 
09726    res = start_network_thread();
09727    if (!res) {
09728       if (option_verbose > 1) 
09729          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
09730    } else {
09731       ast_log(LOG_ERROR, "Unable to start network thread\n");
09732       ast_netsock_release(netsock);
09733    }
09734 
09735    for (reg = registrations; reg; reg = reg->next)
09736       iax2_do_register(reg);
09737    ast_mutex_lock(&peerl.lock);
09738    for (peer = peerl.peers; peer; peer = peer->next) {
09739       if (peer->sockfd < 0)
09740          peer->sockfd = defaultsockfd;
09741       iax2_poke_peer(peer, 0);
09742    }
09743    ast_mutex_unlock(&peerl.lock);
09744    reload_firmware();
09745    iax_provision_reload();
09746    return res;
09747 }
09748 
09749 char *description()
09750 {
09751    return (char *) desc;
09752 }
09753 
09754 int usecount()
09755 {
09756    return usecnt;
09757 }
09758 
09759 char *key()
09760 {
09761    return ASTERISK_GPL_KEY;
09762 }

Generated on Fri Sep 29 11:12:26 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7