Sat Mar 24 23:26:01 2007

Asterisk developer's documentation


chan_iax2.c

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

Generated on Sat Mar 24 23:26:01 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6