Sun Aug 6 15:02:30 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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

Generated on Sun Aug 6 15:02:31 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2