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

Generated on Mon Mar 20 08:25:39 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1