Fri May 26 01:45:29 2006

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \par See also
00024  * \arg \ref Config_iax
00025  *
00026  * \ingroup channel_drivers
00027  */
00028 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <sys/types.h>
00032 #include <sys/mman.h>
00033 #include <dirent.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <arpa/inet.h>
00037 #include <netinet/in_systm.h>
00038 #include <netinet/ip.h>
00039 #include <sys/time.h>
00040 #include <sys/signal.h>
00041 #include <signal.h>
00042 #include <string.h>
00043 #include <strings.h>
00044 #include <errno.h>
00045 #include <unistd.h>
00046 #include <netdb.h>
00047 #include <fcntl.h>
00048 #include <sys/stat.h>
00049 #include <regex.h>
00050 #ifdef IAX_TRUNKING
00051 #include <sys/ioctl.h>
00052 #ifdef __linux__
00053 #include <linux/zaptel.h>
00054 #else
00055 #include <zaptel.h>
00056 #endif /* __linux__ */
00057 #endif
00058 
00059 #include "asterisk.h"
00060 
00061 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 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       /* This is a video frame, get call number */
06326       fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06327       minivid = 1;
06328    } else if (meta->zeros == 0) {
06329       unsigned char metatype;
06330       /* This is a meta header */
06331       switch(meta->metacmd) {
06332       case IAX_META_TRUNK:
06333          if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) {
06334             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr));
06335             return 1;
06336          }
06337          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06338          ts = ntohl(mth->ts);
06339          metatype = meta->cmddata;
06340          res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr));
06341          ptr = mth->data;
06342          tpeer = find_tpeer(&sin, fd);
06343          if (!tpeer) {
06344             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));
06345             return 1;
06346          }
06347          tpeer->trunkact = ast_tvnow();
06348          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06349             tpeer->rxtrunktime = tpeer->trunkact;
06350          rxtrunktime = tpeer->rxtrunktime;
06351          ast_mutex_unlock(&tpeer->lock);
06352          while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) {
06353             /* Process channels */
06354             unsigned short callno, trunked_ts, len;
06355 
06356             if(metatype == IAX_META_TRUNK_MINI) {
06357                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06358                ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06359                res -= sizeof(struct ast_iax2_meta_trunk_mini);
06360                len = ntohs(mtm->len);
06361                callno = ntohs(mtm->mini.callno);
06362                trunked_ts = ntohs(mtm->mini.ts);
06363             } else if ( metatype == IAX_META_TRUNK_SUPERMINI ) {
06364                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06365                ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06366                res -= sizeof(struct ast_iax2_meta_trunk_entry);
06367                len = ntohs(mte->len);
06368                callno = ntohs(mte->callno);
06369                trunked_ts = 0;
06370             } else {
06371                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));
06372                break;
06373             }
06374             /* Stop if we don't have enough data */
06375             if (len > res)
06376                break;
06377             fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06378             if (fr.callno) {
06379                ast_mutex_lock(&iaxsl[fr.callno]);
06380                /* If it's a valid call, deliver the contents.  If not, we
06381                   drop it, since we don't have a scallno to use for an INVAL */
06382                /* Process as a mini frame */
06383                f.frametype = AST_FRAME_VOICE;
06384                if (iaxs[fr.callno]) {
06385                   if (iaxs[fr.callno]->voiceformat > 0) {
06386                      f.subclass = iaxs[fr.callno]->voiceformat;
06387                      f.datalen = len;
06388                      if (f.datalen >= 0) {
06389                         if (f.datalen)
06390                            f.data = ptr;
06391                         else
06392                            f.data = NULL;
06393                         if(trunked_ts) {
06394                            fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06395                         } else
06396                            fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts);
06397                         /* Don't pass any packets until we're started */
06398                         if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) {
06399                            /* Common things */
06400                            f.src = "IAX2";
06401                            f.mallocd = 0;
06402                            f.offset = 0;
06403                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06404                               f.samples = ast_codec_get_samples(&f);
06405                            else
06406                               f.samples = 0;
06407                            fr.outoforder = 0;
06408                            iax_frame_wrap(&fr, &f);
06409 #ifdef BRIDGE_OPTIMIZATION
06410                            if (iaxs[fr.callno]->bridgecallno) {
06411                               forward_delivery(&fr);
06412                            } else {
06413                               duped_fr = iaxfrdup2(&fr);
06414                               if (duped_fr) {
06415                                  schedule_delivery(duped_fr, updatehistory, 1, &fr.ts);
06416                               }
06417                            }
06418 #else
06419                            duped_fr = iaxfrdup2(&fr);
06420                            if (duped_fr) {
06421                               schedule_delivery(duped_fr, updatehistory, 1, &fr.ts);
06422                            }
06423 #endif
06424                            if (iaxs[fr.callno]->last < fr.ts) {
06425                               iaxs[fr.callno]->last = fr.ts;
06426 #if 1
06427                               if (option_debug)
06428                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts);
06429 #endif
06430                            }
06431                         }
06432                      } else {
06433                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06434                      }
06435                   } else {
06436                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06437                      iax2_vnak(fr.callno);
06438                   }
06439                }
06440                ast_mutex_unlock(&iaxsl[fr.callno]);
06441             }
06442             ptr += len;
06443             res -= len;
06444          }
06445          
06446       }
06447       return 1;
06448    }
06449 #ifdef DEBUG_SUPPORT
06450    if (iaxdebug)
06451       iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr));
06452 #endif
06453    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06454       /* Get the destination call number */
06455       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06456       /* Retrieve the type and subclass */
06457       f.frametype = fh->type;
06458       if (f.frametype == AST_FRAME_VIDEO) {
06459          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06460       } else {
06461          f.subclass = uncompress_subclass(fh->csub);
06462       }
06463       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06464                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06465                          (f.subclass == IAX_COMMAND_REGREL)))
06466          new = NEW_ALLOW;
06467    } else {
06468       /* Don't know anything about it yet */
06469       f.frametype = AST_FRAME_NULL;
06470       f.subclass = 0;
06471    }
06472 
06473    if (!fr.callno)
06474       fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06475 
06476    if (fr.callno > 0) 
06477       ast_mutex_lock(&iaxsl[fr.callno]);
06478 
06479    if (!fr.callno || !iaxs[fr.callno]) {
06480       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06481          frame, reply with an inval */
06482       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06483          /* We can only raw hangup control frames */
06484          if (((f.subclass != IAX_COMMAND_INVAL) &&
06485              (f.subclass != IAX_COMMAND_TXCNT) &&
06486              (f.subclass != IAX_COMMAND_TXACC) &&
06487              (f.subclass != IAX_COMMAND_FWDOWNL))||
06488              (f.frametype != AST_FRAME_IAX))
06489             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06490             fd);
06491       }
06492       if (fr.callno > 0) 
06493          ast_mutex_unlock(&iaxsl[fr.callno]);
06494       return 1;
06495    }
06496    if (ast_test_flag(iaxs[fr.callno], IAX_ENCRYPTED)) {
06497       if (decrypt_frame(fr.callno, fh, &f, &res)) {
06498          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06499          ast_mutex_unlock(&iaxsl[fr.callno]);
06500          return 1;
06501       }
06502 #ifdef DEBUG_SUPPORT
06503       else if (iaxdebug)
06504          iax_showframe(NULL, fh, 3, &sin, res - sizeof(struct ast_iax2_full_hdr));
06505 #endif
06506    }
06507 
06508    /* count this frame */
06509    iaxs[fr.callno]->frames_received++;
06510 
06511    if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid &&
06512       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06513       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06514       iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06515    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06516       if (option_debug  && iaxdebug)
06517          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06518       /* Check if it's out of order (and not an ACK or INVAL) */
06519       fr.oseqno = fh->oseqno;
06520       fr.iseqno = fh->iseqno;
06521       fr.ts = ntohl(fh->ts);
06522 #ifdef IAXTESTS
06523       if (test_resync) {
06524          if (option_debug)
06525             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr.ts, fr.ts + test_resync);
06526          fr.ts += test_resync;
06527       }
06528 #endif /* IAXTESTS */
06529 #if 0
06530       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06531            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06532                         (f.subclass == IAX_COMMAND_NEW ||
06533                          f.subclass == IAX_COMMAND_AUTHREQ ||
06534                          f.subclass == IAX_COMMAND_ACCEPT ||
06535                          f.subclass == IAX_COMMAND_REJECT))      ) )
06536 #endif
06537       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06538          updatehistory = 0;
06539       if ((iaxs[fr.callno]->iseqno != fr.oseqno) &&
06540          (iaxs[fr.callno]->iseqno ||
06541             ((f.subclass != IAX_COMMAND_TXCNT) &&
06542             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06543             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06544             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06545             (f.subclass != IAX_COMMAND_TXACC)) ||
06546             (f.frametype != AST_FRAME_IAX))) {
06547          if (
06548           ((f.subclass != IAX_COMMAND_ACK) &&
06549            (f.subclass != IAX_COMMAND_INVAL) &&
06550            (f.subclass != IAX_COMMAND_TXCNT) &&
06551            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06552            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06553            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06554            (f.subclass != IAX_COMMAND_TXACC) &&
06555            (f.subclass != IAX_COMMAND_VNAK)) ||
06556            (f.frametype != AST_FRAME_IAX)) {
06557             /* If it's not an ACK packet, it's out of order. */
06558             if (option_debug)
06559                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06560                iaxs[fr.callno]->iseqno, fr.oseqno, f.frametype, f.subclass);
06561             if (iaxs[fr.callno]->iseqno > fr.oseqno) {
06562                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06563                if ((f.frametype != AST_FRAME_IAX) || 
06564                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06565                   if (option_debug)
06566                      ast_log(LOG_DEBUG, "Acking anyway\n");
06567                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06568                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06569                   send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
06570                }
06571             } else {
06572                /* Send a VNAK requesting retransmission */
06573                iax2_vnak(fr.callno);
06574             }
06575             ast_mutex_unlock(&iaxsl[fr.callno]);
06576             return 1;
06577          }
06578       } else {
06579          /* Increment unless it's an ACK or VNAK */
06580          if (((f.subclass != IAX_COMMAND_ACK) &&
06581              (f.subclass != IAX_COMMAND_INVAL) &&
06582              (f.subclass != IAX_COMMAND_TXCNT) &&
06583              (f.subclass != IAX_COMMAND_TXACC) &&
06584             (f.subclass != IAX_COMMAND_VNAK)) ||
06585              (f.frametype != AST_FRAME_IAX))
06586             iaxs[fr.callno]->iseqno++;
06587       }
06588       /* A full frame */
06589       if (res < sizeof(struct ast_iax2_full_hdr)) {
06590          ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_full_hdr));
06591          ast_mutex_unlock(&iaxsl[fr.callno]);
06592          return 1;
06593       }
06594       f.datalen = res - sizeof(struct ast_iax2_full_hdr);
06595 
06596       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
06597          from the real peer, not the transfer peer */
06598       if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 
06599           ((f.subclass != IAX_COMMAND_INVAL) ||
06600            (f.frametype != AST_FRAME_IAX))) {
06601          unsigned char x;
06602          /* XXX This code is not very efficient.  Surely there is a better way which still
06603                 properly handles boundary conditions? XXX */
06604          /* First we have to qualify that the ACKed value is within our window */
06605          for (x=iaxs[fr.callno]->rseqno; x != iaxs[fr.callno]->oseqno; x++)
06606             if (fr.iseqno == x)
06607                break;
06608          if ((x != iaxs[fr.callno]->oseqno) || (iaxs[fr.callno]->oseqno == fr.iseqno)) {
06609             /* The acknowledgement is within our window.  Time to acknowledge everything
06610                that it says to */
06611             for (x=iaxs[fr.callno]->rseqno; x != fr.iseqno; x++) {
06612                /* Ack the packet with the given timestamp */
06613                if (option_debug && iaxdebug)
06614                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06615                ast_mutex_lock(&iaxq.lock);
06616                for (cur = iaxq.head; cur ; cur = cur->next) {
06617                   /* If it's our call, and our timestamp, mark -1 retries */
06618                   if ((fr.callno == cur->callno) && (x == cur->oseqno)) {
06619                      cur->retries = -1;
06620                      /* Destroy call if this is the end */
06621                      if (cur->final) { 
06622                         if (iaxdebug && option_debug)
06623                            ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr.callno);
06624                         iax2_destroy_nolock(fr.callno);
06625                      }
06626                   }
06627                }
06628                ast_mutex_unlock(&iaxq.lock);
06629             }
06630             /* Note how much we've received acknowledgement for */
06631             if (iaxs[fr.callno])
06632                iaxs[fr.callno]->rseqno = fr.iseqno;
06633             else {
06634                /* Stop processing now */
06635                ast_mutex_unlock(&iaxsl[fr.callno]);
06636                return 1;
06637             }
06638          } else
06639             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno);
06640       }
06641       if (inaddrcmp(&sin, &iaxs[fr.callno]->addr) && 
06642          ((f.frametype != AST_FRAME_IAX) || 
06643           ((f.subclass != IAX_COMMAND_TXACC) &&
06644            (f.subclass != IAX_COMMAND_TXCNT)))) {
06645          /* Only messages we accept from a transfer host are TXACC and TXCNT */
06646          ast_mutex_unlock(&iaxsl[fr.callno]);
06647          return 1;
06648       }
06649 
06650       if (f.datalen) {
06651          if (f.frametype == AST_FRAME_IAX) {
06652             if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
06653                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
06654                ast_mutex_unlock(&iaxsl[fr.callno]);
06655                return 1;
06656             }
06657             f.data = NULL;
06658          } else
06659             f.data = buf + sizeof(struct ast_iax2_full_hdr);
06660       } else {
06661          if (f.frametype == AST_FRAME_IAX)
06662             f.data = NULL;
06663          else
06664             f.data = empty;
06665          memset(&ies, 0, sizeof(ies));
06666       }
06667       if (f.frametype == AST_FRAME_VOICE) {
06668          if (f.subclass != iaxs[fr.callno]->voiceformat) {
06669                iaxs[fr.callno]->voiceformat = f.subclass;
06670                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06671                if (iaxs[fr.callno]->owner) {
06672                   int orignative;
06673 retryowner:
06674                   if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) {
06675                      ast_mutex_unlock(&iaxsl[fr.callno]);
06676                      usleep(1);
06677                      ast_mutex_lock(&iaxsl[fr.callno]);
06678                      if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner;
06679                   }
06680                   if (iaxs[fr.callno]) {
06681                      if (iaxs[fr.callno]->owner) {
06682                         orignative = iaxs[fr.callno]->owner->nativeformats;
06683                         iaxs[fr.callno]->owner->nativeformats = f.subclass;
06684                         if (iaxs[fr.callno]->owner->readformat)
06685                            ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat);
06686                         iaxs[fr.callno]->owner->nativeformats = orignative;
06687                         ast_mutex_unlock(&iaxs[fr.callno]->owner->lock);
06688                      }
06689                   } else {
06690                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06691                      ast_mutex_unlock(&iaxsl[fr.callno]);
06692                      return 1;
06693                   }
06694                }
06695          }
06696       }
06697       if (f.frametype == AST_FRAME_VIDEO) {
06698          if (f.subclass != iaxs[fr.callno]->videoformat) {
06699             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06700             iaxs[fr.callno]->videoformat = f.subclass & ~0x1;
06701          }
06702       }
06703       if (f.frametype == AST_FRAME_IAX) {
06704          if (iaxs[fr.callno]->initid > -1) {
06705             /* Don't auto congest anymore since we've gotten something usefulb ack */
06706             ast_sched_del(sched, iaxs[fr.callno]->initid);
06707             iaxs[fr.callno]->initid = -1;
06708          }
06709          /* Handle the IAX pseudo frame itself */
06710          if (option_debug && iaxdebug)
06711             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06712 
06713                         /* Update last ts unless the frame's timestamp originated with us. */
06714          if (iaxs[fr.callno]->last < fr.ts &&
06715                             f.subclass != IAX_COMMAND_ACK &&
06716                             f.subclass != IAX_COMMAND_PONG &&
06717                             f.subclass != IAX_COMMAND_LAGRP) {
06718             iaxs[fr.callno]->last = fr.ts;
06719             if (option_debug && iaxdebug)
06720                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts);
06721          }
06722 
06723          switch(f.subclass) {
06724          case IAX_COMMAND_ACK:
06725             /* Do nothing */
06726             break;
06727          case IAX_COMMAND_QUELCH:
06728             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) {
06729                     /* Generate Manager Hold event, if necessary*/
06730                if (iaxs[fr.callno]->owner) {
06731                   manager_event(EVENT_FLAG_CALL, "Hold",
06732                      "Channel: %s\r\n"
06733                      "Uniqueid: %s\r\n",
06734                      iaxs[fr.callno]->owner->name, 
06735                      iaxs[fr.callno]->owner->uniqueid);
06736                }
06737 
06738                ast_set_flag(iaxs[fr.callno], IAX_QUELCH);
06739                if (ies.musiconhold) {
06740                   if (iaxs[fr.callno]->owner &&
06741                      ast_bridged_channel(iaxs[fr.callno]->owner))
06742                         ast_moh_start(ast_bridged_channel(iaxs[fr.callno]->owner), NULL);
06743                }
06744             }
06745             break;
06746          case IAX_COMMAND_UNQUELCH:
06747             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) {
06748                     /* Generate Manager Unhold event, if necessary*/
06749                if (iaxs[fr.callno]->owner && ast_test_flag(iaxs[fr.callno], IAX_QUELCH)) {
06750                   manager_event(EVENT_FLAG_CALL, "Unhold",
06751                      "Channel: %s\r\n"
06752                      "Uniqueid: %s\r\n",
06753                      iaxs[fr.callno]->owner->name, 
06754                      iaxs[fr.callno]->owner->uniqueid);
06755                }
06756 
06757                ast_clear_flag(iaxs[fr.callno], IAX_QUELCH);
06758                if (iaxs[fr.callno]->owner &&
06759                   ast_bridged_channel(iaxs[fr.callno]->owner))
06760                      ast_moh_stop(ast_bridged_channel(iaxs[fr.callno]->owner));
06761             }
06762             break;
06763          case IAX_COMMAND_TXACC:
06764             if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) {
06765                /* Ack the packet with the given timestamp */
06766                ast_mutex_lock(&iaxq.lock);
06767                for (cur = iaxq.head; cur ; cur = cur->next) {
06768                   /* Cancel any outstanding txcnt's */
06769                   if ((fr.callno == cur->callno) && (cur->transfer))
06770                      cur->retries = -1;
06771                }
06772                ast_mutex_unlock(&iaxq.lock);
06773                memset(&ied1, 0, sizeof(ied1));
06774                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->callno);
06775                send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06776                iaxs[fr.callno]->transferring = TRANSFER_READY;
06777             }
06778             break;
06779          case IAX_COMMAND_NEW:
06780             /* Ignore if it's already up */
06781             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06782                break;
06783             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06784                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06785             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
06786             if (ast_test_flag(iaxs[fr.callno], IAX_TRUNK)) {
06787                fr.callno = make_trunk(fr.callno, 1);
06788             }
06789             /* For security, always ack immediately */
06790             if (delayreject)
06791                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
06792             if (check_access(fr.callno, &sin, &ies)) {
06793                /* They're not allowed on */
06794                auth_fail(fr.callno, IAX_COMMAND_REJECT);
06795                if (authdebug)
06796                   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);
06797                break;
06798             }
06799             /* This might re-enter the IAX code and need the lock */
06800             if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) {
06801                ast_mutex_unlock(&iaxsl[fr.callno]);
06802                exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num);
06803                ast_mutex_lock(&iaxsl[fr.callno]);
06804             } else
06805                exists = 0;
06806             if (ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) {
06807                if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
06808                   memset(&ied0, 0, sizeof(ied0));
06809                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
06810                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
06811                   send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06812                   if (authdebug)
06813                      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);
06814                } else {
06815                   /* Select an appropriate format */
06816 
06817                   if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) {
06818                      if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) {
06819                         using_prefs = "reqonly";
06820                      } else {
06821                         using_prefs = "disabled";
06822                      }
06823                      format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability;
06824                      memset(&pref, 0, sizeof(pref));
06825                      strcpy(caller_pref_buf, "disabled");
06826                      strcpy(host_pref_buf, "disabled");
06827                   } else {
06828                      using_prefs = "mine";
06829                      if(ies.codec_prefs) {
06830                         ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0);
06831                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
06832                         if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
06833                            pref = rpref;
06834                            using_prefs = "caller";
06835                         } else {
06836                            pref = iaxs[fr.callno]->prefs;
06837                         }
06838                      } else
06839                         pref = iaxs[fr.callno]->prefs;
06840                   
06841                      format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0);
06842                      ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1);
06843                      ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
06844                   }
06845                   if (!format) {
06846                      if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP))
06847                         format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability;
06848                      if (!format) {
06849                         memset(&ied0, 0, sizeof(ied0));
06850                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06851                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06852                         send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06853                         if (authdebug) {
06854                            if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP))
06855                               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);
06856                            else 
06857                               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);
06858                         }
06859                      } else {
06860                         /* Pick one... */
06861                         if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) {
06862                            if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability))
06863                               format = 0;
06864                         } else {
06865                            if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) {
06866                               using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
06867                               memset(&pref, 0, sizeof(pref));
06868                               format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);
06869                               strcpy(caller_pref_buf,"disabled");
06870                               strcpy(host_pref_buf,"disabled");
06871                            } else {
06872                               using_prefs = "mine";
06873                               if(ies.codec_prefs) {
06874                                  /* Do the opposite of what we tried above. */
06875                                  if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
06876                                     pref = iaxs[fr.callno]->prefs;                        
06877                                  } else {
06878                                     pref = rpref;
06879                                     using_prefs = "caller";
06880                                  }
06881                                  format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1);
06882                            
06883                               } else /* if no codec_prefs IE do it the old way */
06884                                  format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);   
06885                            }
06886                         }
06887 
06888                         if (!format) {
06889                            memset(&ied0, 0, sizeof(ied0));
06890                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06891                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06892                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);
06893                            send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06894                            if (authdebug)
06895                               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);
06896                            ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); 
06897                            break;
06898                         }
06899                      }
06900                   }
06901                   if (format) {
06902                      /* No authentication required, let them in */
06903                      memset(&ied1, 0, sizeof(ied1));
06904                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
06905                      send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
06906                      if (strcmp(iaxs[fr.callno]->exten, "TBD")) {
06907                         ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
06908                         if (option_verbose > 2) 
06909                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
06910                                     "%srequested format = %s,\n"
06911                                     "%srequested prefs = %s,\n"
06912                                     "%sactual format = %s,\n"
06913                                     "%shost prefs = %s,\n"
06914                                     "%spriority = %s\n",
06915                                     ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
06916                                     VERBOSE_PREFIX_4,
06917                                     ast_getformatname(iaxs[fr.callno]->peerformat), 
06918                                     VERBOSE_PREFIX_4,
06919                                     caller_pref_buf,
06920                                     VERBOSE_PREFIX_4,
06921                                     ast_getformatname(format), 
06922                                     VERBOSE_PREFIX_4,
06923                                     host_pref_buf, 
06924                                     VERBOSE_PREFIX_4,
06925                                     using_prefs);
06926                         
06927                         if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format)))
06928                            iax2_destroy_nolock(fr.callno);
06929                      } else {
06930                         ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD);
06931                         /* If this is a TBD call, we're ready but now what...  */
06932                         if (option_verbose > 2)
06933                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
06934                      }
06935                   }
06936                }
06937                break;
06938             }
06939             if (iaxs[fr.callno]->authmethods & IAX_AUTH_MD5)
06940                merge_encryption(iaxs[fr.callno],ies.encmethods);
06941             else
06942                iaxs[fr.callno]->encmethods = 0;
06943             authenticate_request(iaxs[fr.callno]);
06944             ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED);
06945             break;
06946          case IAX_COMMAND_DPREQ:
06947             /* Request status in the dialplan */
06948             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD) &&
06949                !ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED) && ies.called_number) {
06950                if (iaxcompat) {
06951                   /* Spawn a thread for the lookup */
06952                   spawn_dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num);
06953                } else {
06954                   /* Just look it up */
06955                   dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num, 1);
06956                }
06957             }
06958             break;
06959          case IAX_COMMAND_HANGUP:
06960             ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE);
06961             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno);
06962             /* Set hangup cause according to remote */
06963             if (ies.causecode && iaxs[fr.callno]->owner)
06964                iaxs[fr.callno]->owner->hangupcause = ies.causecode;
06965             /* Send ack immediately, before we destroy */
06966             send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
06967             iax2_destroy_nolock(fr.callno);
06968             break;
06969          case IAX_COMMAND_REJECT:
06970             memset(&f, 0, sizeof(f));
06971             f.frametype = AST_FRAME_CONTROL;
06972             f.subclass = AST_CONTROL_CONGESTION;
06973 
06974             /* Set hangup cause according to remote */
06975             if (ies.causecode && iaxs[fr.callno]->owner)
06976                iaxs[fr.callno]->owner->hangupcause = ies.causecode;
06977 
06978             iax2_queue_frame(fr.callno, &f);
06979             if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) {
06980                /* Send ack immediately, before we destroy */
06981                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
06982                iax2_destroy_nolock(fr.callno);
06983                break;
06984             }
06985             if (iaxs[fr.callno]->owner) {
06986                if (authdebug)
06987                   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>");
06988             }
06989             ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno);
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             iaxs[fr.callno]->error = EPERM;
06993             iax2_destroy_nolock(fr.callno);
06994             break;
06995          case IAX_COMMAND_TRANSFER:
06996             if (iaxs[fr.callno]->owner && ast_bridged_channel(iaxs[fr.callno]->owner) && ies.called_number) {
06997                if (!strcmp(ies.called_number, ast_parking_ext())) {
06998                   if (iax_park(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->owner)) {
06999                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name);
07000                   } else
07001                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name);
07002                } else {
07003                   if (ast_async_goto(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->context, ies.called_number, 1))
07004                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 
07005                         ies.called_number, iaxs[fr.callno]->context);
07006                   else
07007                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, 
07008                         ies.called_number, iaxs[fr.callno]->context);
07009                }
07010             } else
07011                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr.callno);
07012             break;
07013          case IAX_COMMAND_ACCEPT:
07014             /* Ignore if call is already up or needs authentication or is a TBD */
07015             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07016                break;
07017             if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) {
07018                /* Send ack immediately, before we destroy */
07019                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07020                iax2_destroy_nolock(fr.callno);
07021                break;
07022             }
07023             if (ies.format) {
07024                iaxs[fr.callno]->peerformat = ies.format;
07025             } else {
07026                if (iaxs[fr.callno]->owner)
07027                   iaxs[fr.callno]->peerformat = iaxs[fr.callno]->owner->nativeformats;
07028                else
07029                   iaxs[fr.callno]->peerformat = iaxs[fr.callno]->capability;
07030             }
07031             if (option_verbose > 2)
07032                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));
07033             if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) {
07034                memset(&ied0, 0, sizeof(ied0));
07035                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07036                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07037                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07038                if (authdebug)
07039                   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);
07040             } else {
07041                ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
07042                if (iaxs[fr.callno]->owner) {
07043                   /* Switch us to use a compatible format */
07044                   iaxs[fr.callno]->owner->nativeformats = iaxs[fr.callno]->peerformat;
07045                   if (option_verbose > 2)
07046                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr.callno]->owner->nativeformats));
07047 retryowner2:
07048                   if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) {
07049                      ast_mutex_unlock(&iaxsl[fr.callno]);
07050                      usleep(1);
07051                      ast_mutex_lock(&iaxsl[fr.callno]);
07052                      if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner2;
07053                   }
07054                   
07055                   if (iaxs[fr.callno] && iaxs[fr.callno]->owner) {
07056                      /* Setup read/write formats properly. */
07057                      if (iaxs[fr.callno]->owner->writeformat)
07058                         ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat);  
07059                      if (iaxs[fr.callno]->owner->readformat)
07060                         ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); 
07061                      ast_mutex_unlock(&iaxs[fr.callno]->owner->lock);
07062                   }
07063                }
07064             }
07065             ast_mutex_lock(&dpcache_lock);
07066             dp = iaxs[fr.callno]->dpentries;
07067             while(dp) {
07068                if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07069                   iax2_dprequest(dp, fr.callno);
07070                }
07071                dp = dp->peer;
07072             }
07073             ast_mutex_unlock(&dpcache_lock);
07074             break;
07075          case IAX_COMMAND_POKE:
07076             /* Send back a pong packet with the original timestamp */
07077             send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
07078             break;
07079          case IAX_COMMAND_PING:
07080 #ifdef BRIDGE_OPTIMIZATION
07081             if (iaxs[fr.callno]->bridgecallno) {
07082                /* If we're in a bridged call, just forward this */
07083                forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr.ts, NULL, 0, -1);
07084             } else {
07085                struct iax_ie_data pingied;
07086                construct_rr(iaxs[fr.callno], &pingied);
07087                /* Send back a pong packet with the original timestamp */
07088                send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1);
07089             }
07090 #else          
07091             {
07092                struct iax_ie_data pingied;
07093                construct_rr(iaxs[fr.callno], &pingied);
07094             /* Send back a pong packet with the original timestamp */
07095                send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1);
07096             }
07097 #endif         
07098             break;
07099          case IAX_COMMAND_PONG:
07100 #ifdef BRIDGE_OPTIMIZATION
07101             if (iaxs[fr.callno]->bridgecallno) {
07102                /* Forward to the other side of the bridge */
07103                forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
07104             } else {
07105                /* Calculate ping time */
07106                iaxs[fr.callno]->pingtime =  calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts;
07107             }
07108 #else
07109             /* Calculate ping time */
07110             iaxs[fr.callno]->pingtime =  calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts;
07111 #endif
07112             /* save RR info */
07113             save_rr(&fr, &ies);
07114 
07115             if (iaxs[fr.callno]->peerpoke) {
07116                peer = iaxs[fr.callno]->peerpoke;
07117                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07118                   if (iaxs[fr.callno]->pingtime <= peer->maxms) {
07119                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr.callno]->pingtime);
07120                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 
07121                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07122                   }
07123                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07124                   if (iaxs[fr.callno]->pingtime > peer->maxms) {
07125                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr.callno]->pingtime);
07126                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); 
07127                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07128                   }
07129                }
07130                peer->lastms = iaxs[fr.callno]->pingtime;
07131                if (peer->smoothing && (peer->lastms > -1))
07132                   peer->historicms = (iaxs[fr.callno]->pingtime + peer->historicms) / 2;
07133                else if (peer->smoothing && peer->lastms < 0)
07134                   peer->historicms = (0 + peer->historicms) / 2;
07135                else              
07136                   peer->historicms = iaxs[fr.callno]->pingtime;
07137 
07138                if (peer->pokeexpire > -1)
07139                   ast_sched_del(sched, peer->pokeexpire);
07140                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07141                iax2_destroy_nolock(fr.callno);
07142                peer->callno = 0;
07143                /* Try again eventually */
07144                   ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms);
07145                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07146                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07147                else
07148                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07149             }
07150             break;
07151          case IAX_COMMAND_LAGRQ:
07152          case IAX_COMMAND_LAGRP:
07153 #ifdef BRIDGE_OPTIMIZATION
07154             if (iaxs[fr.callno]->bridgecallno) {
07155                forward_command(iaxs[fr.callno], AST_FRAME_IAX, f.subclass, fr.ts, NULL, 0, -1);
07156             } else {
07157 #endif            
07158                f.src = "LAGRQ";
07159                f.mallocd = 0;
07160                f.offset = 0;
07161                f.samples = 0;
07162                iax_frame_wrap(&fr, &f);
07163                if(f.subclass == IAX_COMMAND_LAGRQ) {
07164                    /* Received a LAGRQ - echo back a LAGRP */
07165                    fr.af.subclass = IAX_COMMAND_LAGRP;
07166                    iax2_send(iaxs[fr.callno], &fr.af, fr.ts, -1, 0, 0, 0);
07167                } else {
07168                    /* Received LAGRP in response to our LAGRQ */
07169                    unsigned int ts;
07170                    /* This is a reply we've been given, actually measure the difference */
07171                    ts = calc_timestamp(iaxs[fr.callno], 0, &fr.af);
07172                    iaxs[fr.callno]->lag = ts - fr.ts;
07173                    if (option_debug && iaxdebug)
07174                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07175                         ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->lag);
07176                }
07177 #ifdef BRIDGE_OPTIMIZATION
07178             }
07179 #endif            
07180             break;
07181          case IAX_COMMAND_AUTHREQ:
07182             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07183                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>");
07184                break;
07185             }
07186             if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) {
07187                ast_log(LOG_WARNING, 
07188                   "I don't know how to authenticate %s to %s\n", 
07189                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr));
07190             }
07191             break;
07192          case IAX_COMMAND_AUTHREP:
07193             /* For security, always ack immediately */
07194             if (delayreject)
07195                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07196             /* Ignore once we've started */
07197             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07198                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>");
07199                break;
07200             }
07201             if (authenticate_verify(iaxs[fr.callno], &ies)) {
07202                if (authdebug)
07203                   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);
07204                memset(&ied0, 0, sizeof(ied0));
07205                auth_fail(fr.callno, IAX_COMMAND_REJECT);
07206                break;
07207             }
07208             if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) {
07209                /* This might re-enter the IAX code and need the lock */
07210                exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num);
07211             } else
07212                exists = 0;
07213             if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
07214                if (authdebug)
07215                   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);
07216                memset(&ied0, 0, sizeof(ied0));
07217                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07218                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07219                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07220             } else {
07221                /* Select an appropriate format */
07222                if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) {
07223                   if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) {
07224                      using_prefs = "reqonly";
07225                   } else {
07226                      using_prefs = "disabled";
07227                   }
07228                   format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability;
07229                   memset(&pref, 0, sizeof(pref));
07230                   strcpy(caller_pref_buf, "disabled");
07231                   strcpy(host_pref_buf, "disabled");
07232                } else {
07233                   using_prefs = "mine";
07234                   if(ies.codec_prefs) {
07235                      /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07236                      ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0);
07237                      if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
07238                         ast_codec_pref_convert(&pref, ies.codec_prefs, 32, 0);
07239                         using_prefs = "caller";
07240                      } else {
07241                         pref = iaxs[fr.callno]->prefs;
07242                      }
07243                   } else /* if no codec_prefs IE do it the old way */
07244                      pref = iaxs[fr.callno]->prefs;
07245                
07246                   format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0);
07247                   ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07248                   ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07249                }
07250                if (!format) {
07251                   if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) {
07252                      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);
07253                      format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability;
07254                   }
07255                   if (!format) {
07256                      if (authdebug) {
07257                         if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) 
07258                            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);
07259                         else
07260                            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);
07261                      }
07262                      memset(&ied0, 0, sizeof(ied0));
07263                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07264                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07265                      send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07266                   } else {
07267                      /* Pick one... */
07268                      if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) {
07269                         if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability))
07270                            format = 0;
07271                      } else {
07272                         if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) {
07273                            using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07274                            memset(&pref, 0, sizeof(pref));
07275                            format = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ?
07276                               iaxs[fr.callno]->peerformat : ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);
07277                            strcpy(caller_pref_buf,"disabled");
07278                            strcpy(host_pref_buf,"disabled");
07279                         } else {
07280                            using_prefs = "mine";
07281                            if(ies.codec_prefs) {
07282                               /* Do the opposite of what we tried above. */
07283                               if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
07284                                  pref = iaxs[fr.callno]->prefs;                  
07285                               } else {
07286                                  pref = rpref;
07287                                  using_prefs = "caller";
07288                               }
07289                               format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1);
07290                            } else /* if no codec_prefs IE do it the old way */
07291                               format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);   
07292                         }
07293                      }
07294                      if (!format) {
07295                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);
07296                         if (authdebug) {
07297                            if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP))
07298                               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);
07299                            else
07300                               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);
07301                         }
07302                         memset(&ied0, 0, sizeof(ied0));
07303                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07304                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07305                         send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07306                      }
07307                   }
07308                }
07309                if (format) {
07310                   /* Authentication received */
07311                   memset(&ied1, 0, sizeof(ied1));
07312                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07313                   send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07314                   if (strcmp(iaxs[fr.callno]->exten, "TBD")) {
07315                      ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
07316                      if (option_verbose > 2) 
07317                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07318                                  "%srequested format = %s,\n"
07319                                  "%srequested prefs = %s,\n"
07320                                  "%sactual format = %s,\n"
07321                                  "%shost prefs = %s,\n"
07322                                  "%spriority = %s\n", 
07323                                  ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
07324                                  VERBOSE_PREFIX_4,
07325                                  ast_getformatname(iaxs[fr.callno]->peerformat),
07326                                  VERBOSE_PREFIX_4,
07327                                  caller_pref_buf,
07328                                  VERBOSE_PREFIX_4,
07329                                  ast_getformatname(format),
07330                                  VERBOSE_PREFIX_4,
07331                                  host_pref_buf,
07332                                  VERBOSE_PREFIX_4,
07333                                  using_prefs);
07334 
07335                      ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
07336                      if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format)))
07337                         iax2_destroy_nolock(fr.callno);
07338                   } else {
07339                      ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD);
07340                      /* If this is a TBD call, we're ready but now what...  */
07341                      if (option_verbose > 2)
07342                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07343                   }
07344                }
07345             }
07346             break;
07347          case IAX_COMMAND_DIAL:
07348             if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD)) {
07349                ast_clear_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD);
07350                ast_copy_string(iaxs[fr.callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr.callno]->exten));   
07351                if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num)) {
07352                   if (authdebug)
07353                      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);
07354                   memset(&ied0, 0, sizeof(ied0));
07355                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07356                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07357                   send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07358                } else {
07359                   ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
07360                   if (option_verbose > 2) 
07361                      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);
07362                   ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED);
07363                   send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07364                   if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat)))
07365                      iax2_destroy_nolock(fr.callno);
07366                }
07367             }
07368             break;
07369          case IAX_COMMAND_INVAL:
07370             iaxs[fr.callno]->error = ENOTCONN;
07371             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno);
07372             iax2_destroy_nolock(fr.callno);
07373             if (option_debug)
07374                ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno);
07375             break;
07376          case IAX_COMMAND_VNAK:
07377             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07378             /* Force retransmission */
07379             vnak_retransmit(fr.callno, fr.iseqno);
07380             break;
07381          case IAX_COMMAND_REGREQ:
07382          case IAX_COMMAND_REGREL:
07383             /* For security, always ack immediately */
07384             if (delayreject)
07385                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07386             if (register_verify(fr.callno, &sin, &ies)) {
07387                /* Send delayed failure */
07388                auth_fail(fr.callno, IAX_COMMAND_REGREJ);
07389                break;
07390             }
07391             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)) {
07392                if (f.subclass == IAX_COMMAND_REGREL)
07393                   memset(&sin, 0, sizeof(sin));
07394                if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd, ies.refresh))
07395                   ast_log(LOG_WARNING, "Registry error\n");
07396                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07397                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07398                break;
07399             }
07400             registry_authrequest(iaxs[fr.callno]->peer, fr.callno);
07401             break;
07402          case IAX_COMMAND_REGACK:
07403             if (iax2_ack_registry(&ies, &sin, fr.callno)) 
07404                ast_log(LOG_WARNING, "Registration failure\n");
07405             /* Send ack immediately, before we destroy */
07406             send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07407             iax2_destroy_nolock(fr.callno);
07408             break;
07409          case IAX_COMMAND_REGREJ:
07410             if (iaxs[fr.callno]->reg) {
07411                if (authdebug) {
07412                   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));
07413                   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>");
07414                }
07415                iaxs[fr.callno]->reg->regstate = REG_STATE_REJECTED;
07416             }
07417             /* Send ack immediately, before we destroy */
07418             send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07419             iax2_destroy_nolock(fr.callno);
07420             break;
07421          case IAX_COMMAND_REGAUTH:
07422             /* Authentication request */
07423             if (registry_rerequest(&ies, fr.callno, &sin)) {
07424                memset(&ied0, 0, sizeof(ied0));
07425                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07426                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07427                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07428             }
07429             break;
07430          case IAX_COMMAND_TXREJ:
07431             iaxs[fr.callno]->transferring = 0;
07432             if (option_verbose > 2) 
07433                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>");
07434             memset(&iaxs[fr.callno]->transfer, 0, sizeof(iaxs[fr.callno]->transfer));
07435             if (iaxs[fr.callno]->bridgecallno) {
07436                if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring) {
07437                   iaxs[iaxs[fr.callno]->bridgecallno]->transferring = 0;
07438                   send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07439                }
07440             }
07441             break;
07442          case IAX_COMMAND_TXREADY:
07443             if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) {
07444                iaxs[fr.callno]->transferring = TRANSFER_READY;
07445                if (option_verbose > 2) 
07446                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>");
07447                if (iaxs[fr.callno]->bridgecallno) {
07448                   if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring == TRANSFER_READY) {
07449                      if (option_verbose > 2) 
07450                         ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>",
07451                               iaxs[iaxs[fr.callno]->bridgecallno]->owner ? iaxs[iaxs[fr.callno]->bridgecallno]->owner->name : "<Unknown>");
07452 
07453                      /* They're both ready, now release them. */
07454                      iaxs[iaxs[fr.callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07455                      iaxs[fr.callno]->transferring = TRANSFER_RELEASED;
07456                      ast_set_flag(iaxs[iaxs[fr.callno]->bridgecallno], IAX_ALREADYGONE);
07457                      ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE);
07458 
07459                      /* Stop doing lag & ping requests */
07460                      stop_stuff(fr.callno);
07461                      stop_stuff(iaxs[fr.callno]->bridgecallno);
07462 
07463                      memset(&ied0, 0, sizeof(ied0));
07464                      memset(&ied1, 0, sizeof(ied1));
07465                      iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr.callno]->bridgecallno]->peercallno);
07466                      iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->peercallno);
07467                      send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07468                      send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07469 
07470                   }
07471                }
07472             }
07473             break;
07474          case IAX_COMMAND_TXREQ:
07475             try_transfer(iaxs[fr.callno], &ies);
07476             break;
07477          case IAX_COMMAND_TXCNT:
07478             if (iaxs[fr.callno]->transferring)
07479                send_command_transfer(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07480             break;
07481          case IAX_COMMAND_TXREL:
07482             /* Send ack immediately, rather than waiting until we've changed addresses */
07483             send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07484             complete_transfer(fr.callno, &ies);
07485             stop_stuff(fr.callno);  /* for attended transfer to work with libiax */
07486             break;   
07487          case IAX_COMMAND_DPREP:
07488             complete_dpreply(iaxs[fr.callno], &ies);
07489             break;
07490          case IAX_COMMAND_UNSUPPORT:
07491             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07492             break;
07493          case IAX_COMMAND_FWDOWNL:
07494             /* Firmware download */
07495             memset(&ied0, 0, sizeof(ied0));
07496             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07497             if (res < 0)
07498                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07499             else if (res > 0)
07500                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07501             else
07502                send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07503             break;
07504          default:
07505             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno);
07506             memset(&ied0, 0, sizeof(ied0));
07507             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07508             send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07509          }
07510          /* Don't actually pass these frames along */
07511          if ((f.subclass != IAX_COMMAND_ACK) && 
07512            (f.subclass != IAX_COMMAND_TXCNT) && 
07513            (f.subclass != IAX_COMMAND_TXACC) && 
07514            (f.subclass != IAX_COMMAND_INVAL) &&
07515            (f.subclass != IAX_COMMAND_VNAK)) { 
07516             if (iaxs[fr.callno] && iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno)
07517                send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07518          }
07519          ast_mutex_unlock(&iaxsl[fr.callno]);
07520          return 1;
07521       }
07522       /* Unless this is an ACK or INVAL frame, ack it */
07523       if (iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno)
07524          send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
07525    } else if (minivid) {
07526       f.frametype = AST_FRAME_VIDEO;
07527       if (iaxs[fr.callno]->videoformat > 0) 
07528          f.subclass = iaxs[fr.callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07529       else {
07530          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07531          iax2_vnak(fr.callno);
07532          ast_mutex_unlock(&iaxsl[fr.callno]);
07533          return 1;
07534       }
07535       f.datalen = res - sizeof(struct ast_iax2_video_hdr);
07536       if (f.datalen)
07537          f.data = buf + sizeof(struct ast_iax2_video_hdr);
07538       else
07539          f.data = NULL;
07540 #ifdef IAXTESTS
07541       if (test_resync) {
07542          fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff);
07543       } else
07544 #endif /* IAXTESTS */
07545       fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff);
07546    } else {
07547       /* A mini frame */
07548       f.frametype = AST_FRAME_VOICE;
07549       if (iaxs[fr.callno]->voiceformat > 0)
07550          f.subclass = iaxs[fr.callno]->voiceformat;
07551       else {
07552          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07553          iax2_vnak(fr.callno);
07554          ast_mutex_unlock(&iaxsl[fr.callno]);
07555          return 1;
07556       }
07557       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07558       if (f.datalen < 0) {
07559          ast_log(LOG_WARNING, "Datalen < 0?\n");
07560          ast_mutex_unlock(&iaxsl[fr.callno]);
07561          return 1;
07562       }
07563       if (f.datalen)
07564          f.data = buf + sizeof(struct ast_iax2_mini_hdr);
07565       else
07566          f.data = NULL;
07567 #ifdef IAXTESTS
07568       if (test_resync) {
07569          fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07570       } else
07571 #endif /* IAXTESTS */
07572       fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07573       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
07574    }
07575    /* Don't pass any packets until we're started */
07576    if (!ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) {
07577       ast_mutex_unlock(&iaxsl[fr.callno]);
07578       return 1;
07579    }
07580    /* Common things */
07581    f.src = "IAX2";
07582    f.mallocd = 0;
07583    f.offset = 0;
07584    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07585       f.samples = ast_codec_get_samples(&f);
07586       /* We need to byteswap incoming slinear samples from network byte order */
07587       if (f.subclass == AST_FORMAT_SLINEAR)
07588          ast_frame_byteswap_be(&f);
07589    } else
07590       f.samples = 0;
07591    iax_frame_wrap(&fr, &f);
07592 
07593    /* If this is our most recent packet, use it as our basis for timestamping */
07594    if (iaxs[fr.callno]->last < fr.ts) {
07595       /*iaxs[fr.callno]->last = fr.ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
07596       fr.outoforder = 0;
07597    } else {
07598       if (option_debug && iaxdebug)
07599          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);
07600       fr.outoforder = -1;
07601    }
07602 #ifdef BRIDGE_OPTIMIZATION
07603    if (iaxs[fr.callno]->bridgecallno) {
07604       forward_delivery(&fr);
07605    } else {
07606       duped_fr = iaxfrdup2(&fr);
07607       if (duped_fr) {
07608          schedule_delivery(duped_fr, updatehistory, 0, &fr.ts);
07609       }
07610    }
07611 #else
07612    duped_fr = iaxfrdup2(&fr);
07613    if (duped_fr) {
07614       schedule_delivery(duped_fr, updatehistory, 0, &fr.ts);
07615    }
07616 #endif
07617 
07618    if (iaxs[fr.callno]->last < fr.ts) {
07619       iaxs[fr.callno]->last = fr.ts;
07620 #if 1
07621       if (option_debug && iaxdebug)
07622          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts);
07623 #endif
07624    }
07625 
07626    /* Always run again */
07627    ast_mutex_unlock(&iaxsl[fr.callno]);
07628    return 1;
07629 }
07630 
07631 static int iax2_do_register(struct iax2_registry *reg)
07632 {
07633    struct iax_ie_data ied;
07634    if (option_debug && iaxdebug)
07635       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07636    if (!reg->callno) {
07637       if (option_debug)
07638          ast_log(LOG_DEBUG, "Allocate call number\n");
07639       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07640       if (reg->callno < 1) {
07641          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07642          return -1;
07643       } else if (option_debug)
07644          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07645       iaxs[reg->callno]->reg = reg;
07646    }
07647    /* Schedule the next registration attempt */
07648    if (reg->expire > -1)
07649       ast_sched_del(sched, reg->expire);
07650    /* Setup the next registration a little early */
07651    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07652    /* Send the request */
07653    memset(&ied, 0, sizeof(ied));
07654    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07655    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07656    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07657    reg->regstate = REG_STATE_REGSENT;
07658    return 0;
07659 }
07660 
07661 static char *iax2_prov_complete_template_3rd(char *line, char *word, int pos, int state)
07662 {
07663    if (pos != 3)
07664       return NULL;
07665    return iax_prov_complete_template(line, word, pos, state);
07666 }
07667 
07668 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
07669 {
07670    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07671       is found for template */
07672    struct iax_ie_data provdata;
07673    struct iax_ie_data ied;
07674    unsigned int sig;
07675    struct sockaddr_in sin;
07676    int callno;
07677    struct create_addr_info cai;
07678 
07679    memset(&cai, 0, sizeof(cai));
07680 
07681    if (option_debug)
07682       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07683 
07684    if (iax_provision_build(&provdata, &sig, template, force)) {
07685       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07686       return 0;
07687    }
07688 
07689    if (end) {
07690       memcpy(&sin, end, sizeof(sin));
07691       cai.sockfd = sockfd;
07692    } else if (create_addr(dest, &sin, &cai))
07693       return -1;
07694 
07695    /* Build the rest of the message */
07696    memset(&ied, 0, sizeof(ied));
07697    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07698 
07699    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07700    if (!callno)
07701       return -1;
07702 
07703    ast_mutex_lock(&iaxsl[callno]);
07704    if (iaxs[callno]) {
07705       /* Schedule autodestruct in case they don't ever give us anything back */
07706       if (iaxs[callno]->autoid > -1)
07707          ast_sched_del(sched, iaxs[callno]->autoid);
07708       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07709       ast_set_flag(iaxs[callno], IAX_PROVISION);
07710       /* Got a call number now, so go ahead and send the provisioning information */
07711       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07712    }
07713    ast_mutex_unlock(&iaxsl[callno]);
07714 
07715    return 1;
07716 }
07717 
07718 static char *papp = "IAX2Provision";
07719 static char *psyn = "Provision a calling IAXy with a given template";
07720 static char *pdescrip = 
07721 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
07722 "the calling entity is in fact an IAXy) with the given template or\n"
07723 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
07724 
07725 /*! iax2provision
07726 \ingroup applications
07727 */
07728 static int iax2_prov_app(struct ast_channel *chan, void *data)
07729 {
07730    int res;
07731    char *sdata;
07732    char *opts;
07733    int force =0;
07734    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
07735    char iabuf[INET_ADDRSTRLEN];
07736    if (ast_strlen_zero(data))
07737       data = "default";
07738    sdata = ast_strdupa(data);
07739    opts = strchr(sdata, '|');
07740    if (opts)
07741       *opts='\0';
07742 
07743    if (chan->type != channeltype) {
07744       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
07745       return -1;
07746    } 
07747    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
07748       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
07749       return -1;
07750    }
07751    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
07752    if (option_verbose > 2)
07753       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
07754       ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr),
07755       sdata, res);
07756    return res;
07757 }
07758 
07759 
07760 static int iax2_prov_cmd(int fd, int argc, char *argv[])
07761 {
07762    int force = 0;
07763    int res;
07764    if (argc < 4)
07765       return RESULT_SHOWUSAGE;
07766    if ((argc > 4)) {
07767       if (!strcasecmp(argv[4], "forced"))
07768          force = 1;
07769       else
07770          return RESULT_SHOWUSAGE;
07771    }
07772    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07773    if (res < 0)
07774       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07775    else if (res < 1)
07776       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07777    else
07778       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07779    return RESULT_SUCCESS;
07780 }
07781 
07782 static int iax2_poke_noanswer(void *data)
07783 {
07784    struct iax2_peer *peer = data;
07785    peer->pokeexpire = -1;
07786    if (peer->lastms > -1) {
07787       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07788       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07789       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07790    }
07791    if (peer->callno > 0)
07792       iax2_destroy(peer->callno);
07793    peer->callno = 0;
07794    peer->lastms = -1;
07795    /* Try again quickly */
07796    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07797    return 0;
07798 }
07799 
07800 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
07801 {
07802    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07803       /* IF we have no IP, or this isn't to be monitored, return
07804         imeediately after clearing things out */
07805       peer->lastms = 0;
07806       peer->historicms = 0;
07807       peer->pokeexpire = -1;
07808       peer->callno = 0;
07809       return 0;
07810    }
07811    if (peer->callno > 0) {
07812       ast_log(LOG_NOTICE, "Still have a callno...\n");
07813       iax2_destroy(peer->callno);
07814    }
07815    if (heldcall)
07816       ast_mutex_unlock(&iaxsl[heldcall]);
07817    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
07818    if (heldcall)
07819       ast_mutex_lock(&iaxsl[heldcall]);
07820    if (peer->callno < 1) {
07821       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
07822       return -1;
07823    }
07824    if (peer->pokeexpire > -1)
07825       ast_sched_del(sched, peer->pokeexpire);
07826    /* Speed up retransmission times */
07827    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
07828    iaxs[peer->callno]->peerpoke = peer;
07829    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
07830    
07831    /* If the host is already unreachable then use the unreachable interval instead */
07832    if (peer->lastms < 0) {
07833       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
07834    } else
07835       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
07836 
07837    return 0;
07838 }
07839 
07840 static void free_context(struct iax2_context *con)
07841 {
07842    struct iax2_context *conl;
07843    while(con) {
07844       conl = con;
07845       con = con->next;
07846       free(conl);
07847    }
07848 }
07849 
07850 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
07851 {
07852    int callno;
07853    int res;
07854    int fmt, native;
07855    struct sockaddr_in sin;
07856    struct ast_channel *c;
07857    struct parsed_dial_string pds;
07858    struct create_addr_info cai;
07859    char *tmpstr;
07860 
07861    memset(&pds, 0, sizeof(pds));
07862    tmpstr = ast_strdupa(data);
07863    parse_dial_string(tmpstr, &pds);
07864 
07865    memset(&cai, 0, sizeof(cai));
07866    cai.capability = iax2_capability;
07867 
07868    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07869 
07870    if (!pds.peer) {
07871       ast_log(LOG_WARNING, "No peer given\n");
07872       return NULL;
07873    }
07874           
07875    
07876    /* Populate our address from the given */
07877    if (create_addr(pds.peer, &sin, &cai)) {
07878       *cause = AST_CAUSE_UNREGISTERED;
07879       return NULL;
07880    }
07881 
07882    if (pds.port)
07883       sin.sin_port = htons(atoi(pds.port));
07884 
07885    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07886    if (callno < 1) {
07887       ast_log(LOG_WARNING, "Unable to create call\n");
07888       *cause = AST_CAUSE_CONGESTION;
07889       return NULL;
07890    }
07891 
07892    ast_mutex_lock(&iaxsl[callno]);
07893 
07894    /* If this is a trunk, update it now */
07895    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
07896    if (ast_test_flag(&cai, IAX_TRUNK))
07897       callno = make_trunk(callno, 1);
07898    iaxs[callno]->maxtime = cai.maxtime;
07899    if (cai.found)
07900       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
07901 
07902    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
07903 
07904    ast_mutex_unlock(&iaxsl[callno]);
07905 
07906    if (c) {
07907       /* Choose a format we can live with */
07908       if (c->nativeformats & format) 
07909          c->nativeformats &= format;
07910       else {
07911          native = c->nativeformats;
07912          fmt = format;
07913          res = ast_translator_best_choice(&fmt, &native);
07914          if (res < 0) {
07915             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
07916                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
07917             ast_hangup(c);
07918             return NULL;
07919          }
07920          c->nativeformats = native;
07921       }
07922       c->readformat = ast_best_codec(c->nativeformats);
07923       c->writeformat = c->readformat;
07924    }
07925 
07926    return c;
07927 }
07928 
07929 static void *network_thread(void *ignore)
07930 {
07931    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
07932       from the network, and queue them for delivery to the channels */
07933    int res, count;
07934    struct iax_frame *f, *freeme;
07935    if (timingfd > -1)
07936       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
07937    for(;;) {
07938       /* Go through the queue, sending messages which have not yet been
07939          sent, and scheduling retransmissions if appropriate */
07940       ast_mutex_lock(&iaxq.lock);
07941       f = iaxq.head;
07942       count = 0;
07943       while(f) {
07944          freeme = NULL;
07945          if (!f->sentyet) {
07946             f->sentyet++;
07947             /* Send a copy immediately -- errors here are ok, so don't bother locking */
07948             if (iaxs[f->callno]) {
07949                send_packet(f);
07950                count++;
07951             } 
07952             if (f->retries < 0) {
07953                /* This is not supposed to be retransmitted */
07954                if (f->prev) 
07955                   f->prev->next = f->next;
07956                else
07957                   iaxq.head = f->next;
07958                if (f->next)
07959                   f->next->prev = f->prev;
07960                else
07961                   iaxq.tail = f->prev;
07962                iaxq.count--;
07963                /* Free the iax frame */
07964                freeme = f;
07965             } else {
07966                /* We need reliable delivery.  Schedule a retransmission */
07967                f->retries++;
07968                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
07969             }
07970          }
07971          f = f->next;
07972          if (freeme)
07973             iax_frame_free(freeme);
07974       }
07975       ast_mutex_unlock(&iaxq.lock);
07976       if (count >= 20)
07977          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
07978 
07979       /* Now do the IO, and run scheduled tasks */
07980       res = ast_sched_wait(sched);
07981       if ((res > 1000) || (res < 0))
07982          res = 1000;
07983       res = ast_io_wait(io, res);
07984       if (res >= 0) {
07985          if (res >= 20)
07986             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
07987          count = ast_sched_runq(sched);
07988          if (count >= 20)
07989             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
07990       }
07991    }
07992    return NULL;
07993 }
07994 
07995 static int start_network_thread(void)
07996 {
07997    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
07998 }
07999 
08000 static struct iax2_context *build_context(char *context)
08001 {
08002    struct iax2_context *con = malloc(sizeof(struct iax2_context));
08003    if (con) {
08004       ast_copy_string(con->context, context, sizeof(con->context));
08005       con->next = NULL;
08006    }
08007    return con;
08008 }
08009 
08010 static int get_auth_methods(char *value)
08011 {
08012    int methods = 0;
08013    if (strstr(value, "rsa"))
08014       methods |= IAX_AUTH_RSA;
08015    if (strstr(value, "md5"))
08016       methods |= IAX_AUTH_MD5;
08017    if (strstr(value, "plaintext"))
08018       methods |= IAX_AUTH_PLAINTEXT;
08019    return methods;
08020 }
08021 
08022 
08023 /*--- check_src_ip: Check if address can be used as packet source.
08024  returns:
08025  0  address available
08026  1  address unavailable
08027 -1  error
08028 */
08029 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08030 {
08031    int sd;
08032    int res;
08033    
08034    sd = socket(AF_INET, SOCK_DGRAM, 0);
08035    if (sd < 0) {
08036       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08037       return -1;
08038    }
08039 
08040    res = bind(sd, sa, salen);
08041    if (res < 0) {
08042       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08043       close(sd);
08044       return 1;
08045    }
08046 
08047    close(sd);
08048    return 0;
08049 }
08050 
08051 /*--- peer_set_srcaddr: Parse the "sourceaddress" value,
08052   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08053   not found. */
08054 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08055 {
08056    struct sockaddr_in sin;
08057    int nonlocal = 1;
08058    int port = IAX_DEFAULT_PORTNO;
08059    int sockfd = defaultsockfd;
08060    char *tmp;
08061    char *addr;
08062    char *portstr;
08063 
08064    tmp = ast_strdupa(srcaddr);
08065    if (!tmp) {
08066       ast_log(LOG_WARNING, "Out of memory!\n");
08067       return -1;
08068    }
08069 
08070    addr = strsep(&tmp, ":");
08071    portstr = tmp;
08072 
08073    if (portstr) {
08074       port = atoi(portstr);
08075       if (port < 1)
08076          port = IAX_DEFAULT_PORTNO;
08077    }
08078    
08079    if (!ast_get_ip(&sin, addr)) {
08080       struct ast_netsock *sock;
08081       int res;
08082 
08083       sin.sin_port = 0;
08084       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08085       if (res == 0) {
08086          /* ip address valid. */
08087          sin.sin_port = htons(port);
08088          sock = ast_netsock_find(netsock, &sin);
08089          if (sock) {
08090             sockfd = ast_netsock_sockfd(sock);
08091             nonlocal = 0;
08092          }
08093       }
08094    }
08095       
08096    peer->sockfd = sockfd;
08097 
08098    if (nonlocal) {
08099       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08100          srcaddr, peer->name);
08101       return -1;
08102    } else {
08103       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08104       return 0;
08105    }
08106 }
08107 
08108       
08109 /*--- build_peer: Create peer structure based on configuration */
08110 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, int temponly)
08111 {
08112    struct iax2_peer *peer;
08113    struct iax2_peer *prev;
08114    struct ast_ha *oldha = NULL;
08115    int maskfound=0;
08116    int found=0;
08117    prev = NULL;
08118    ast_mutex_lock(&peerl.lock);
08119    if (!temponly) {
08120       peer = peerl.peers;
08121       while(peer) {
08122          if (!strcmp(peer->name, name)) { 
08123             break;
08124          }
08125          prev = peer;
08126          peer = peer->next;
08127       }
08128    } else
08129       peer = NULL;   
08130    if (peer) {
08131       found++;
08132       oldha = peer->ha;
08133       peer->ha = NULL;
08134       /* Already in the list, remove it and it will be added back (or FREE'd) */
08135       if (prev) {
08136          prev->next = peer->next;
08137       } else {
08138          peerl.peers = peer->next;
08139       }
08140       ast_mutex_unlock(&peerl.lock);
08141    } else {
08142       ast_mutex_unlock(&peerl.lock);
08143       peer = malloc(sizeof(struct iax2_peer));
08144       if (peer) {
08145          memset(peer, 0, sizeof(struct iax2_peer));
08146          peer->expire = -1;
08147          peer->pokeexpire = -1;
08148          peer->sockfd = defaultsockfd;
08149       }
08150    }
08151    if (peer) {
08152       ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08153       peer->encmethods = iax2_encryption;
08154       peer->secret[0] = '\0';
08155       if (!found) {
08156          ast_copy_string(peer->name, name, sizeof(peer->name));
08157          peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08158          peer->expiry = min_reg_expire;
08159       }
08160       peer->prefs = prefs;
08161       peer->capability = iax2_capability;
08162       peer->smoothing = 0;
08163       peer->pokefreqok = DEFAULT_FREQ_OK;
08164       peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08165       peer->context[0] = '\0';
08166       peer->peercontext[0] = '\0';
08167       while(v) {
08168          if (!strcasecmp(v->name, "secret")) {
08169             if (!ast_strlen_zero(peer->secret)) {
08170                strncpy(peer->secret + strlen(peer->secret), ";", sizeof(peer->secret)-strlen(peer->secret) - 1);
08171                strncpy(peer->secret + strlen(peer->secret), v->value, sizeof(peer->secret)-strlen(peer->secret) - 1);
08172             } else
08173                ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
08174          } else if (!strcasecmp(v->name, "mailbox")) {
08175             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
08176          } else if (!strcasecmp(v->name, "dbsecret")) {
08177             ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
08178          } else if (!strcasecmp(v->name, "mailboxdetail")) {
08179             ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 
08180          } else if (!strcasecmp(v->name, "trunk")) {
08181             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08182             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08183                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08184                ast_clear_flag(peer, IAX_TRUNK);
08185             }
08186          } else if (!strcasecmp(v->name, "auth")) {
08187             peer->authmethods = get_auth_methods(v->value);
08188          } else if (!strcasecmp(v->name, "encryption")) {
08189             peer->encmethods = get_encrypt_methods(v->value);
08190          } else if (!strcasecmp(v->name, "notransfer")) {
08191             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08192          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08193             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08194          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08195             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08196          } else if (!strcasecmp(v->name, "host")) {
08197             if (!strcasecmp(v->value, "dynamic")) {
08198                /* They'll register with us */
08199                ast_set_flag(peer, IAX_DYNAMIC); 
08200                if (!found) {
08201                   /* Initialize stuff iff we're not found, otherwise
08202                      we keep going with what we had */
08203                   memset(&peer->addr.sin_addr, 0, 4);
08204                   if (peer->addr.sin_port) {
08205                      /* If we've already got a port, make it the default rather than absolute */
08206                      peer->defaddr.sin_port = peer->addr.sin_port;
08207                      peer->addr.sin_port = 0;
08208                   }
08209                }
08210             } else {
08211                /* Non-dynamic.  Make sure we become that way if we're not */
08212                if (peer->expire > -1)
08213                   ast_sched_del(sched, peer->expire);
08214                peer->expire = -1;
08215                ast_clear_flag(peer, IAX_DYNAMIC);
08216                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08217                   free(peer);
08218                   return NULL;
08219                }
08220                if (!peer->addr.sin_port)
08221                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08222             }
08223             if (!maskfound)
08224                inet_aton("255.255.255.255", &peer->mask);
08225          } else if (!strcasecmp(v->name, "defaultip")) {
08226             if (ast_get_ip(&peer->defaddr, v->value)) {
08227                free(peer);
08228                return NULL;
08229             }
08230          } else if (!strcasecmp(v->name, "sourceaddress")) {
08231             peer_set_srcaddr(peer, v->value);
08232          } else if (!strcasecmp(v->name, "permit") ||
08233                   !strcasecmp(v->name, "deny")) {
08234             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08235          } else if (!strcasecmp(v->name, "mask")) {
08236             maskfound++;
08237             inet_aton(v->value, &peer->mask);
08238          } else if (!strcasecmp(v->name, "context")) {
08239             if (ast_strlen_zero(peer->context))
08240                ast_copy_string(peer->context, v->value, sizeof(peer->context));
08241          } else if (!strcasecmp(v->name, "regexten")) {
08242             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
08243          } else if (!strcasecmp(v->name, "peercontext")) {
08244             if (ast_strlen_zero(peer->peercontext))
08245                ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext));
08246          } else if (!strcasecmp(v->name, "port")) {
08247             if (ast_test_flag(peer, IAX_DYNAMIC))
08248                peer->defaddr.sin_port = htons(atoi(v->value));
08249             else
08250                peer->addr.sin_port = htons(atoi(v->value));
08251          } else if (!strcasecmp(v->name, "username")) {
08252             ast_copy_string(peer->username, v->value, sizeof(peer->username));
08253          } else if (!strcasecmp(v->name, "allow")) {
08254             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08255          } else if (!strcasecmp(v->name, "disallow")) {
08256             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08257          } else if (!strcasecmp(v->name, "callerid")) {
08258             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name),
08259                            peer->cid_num, sizeof(peer->cid_num));
08260             ast_set_flag(peer, IAX_HASCALLERID);   
08261          } else if (!strcasecmp(v->name, "sendani")) {
08262             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08263          } else if (!strcasecmp(v->name, "inkeys")) {
08264             ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys));
08265          } else if (!strcasecmp(v->name, "outkey")) {
08266             ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
08267          } else if (!strcasecmp(v->name, "qualify")) {
08268             if (!strcasecmp(v->value, "no")) {
08269                peer->maxms = 0;
08270             } else if (!strcasecmp(v->value, "yes")) {
08271                peer->maxms = DEFAULT_MAXMS;
08272             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08273                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);
08274                peer->maxms = 0;
08275             }
08276          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08277             peer->smoothing = ast_true(v->value);
08278          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08279             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08280                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);
08281             }
08282          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08283             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08284                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);
08285             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08286          } else if (!strcasecmp(v->name, "timezone")) {
08287             ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag));
08288          }/* else if (strcasecmp(v->name,"type")) */
08289          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08290          v=v->next;
08291       }
08292       if (!peer->authmethods)
08293          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08294       ast_clear_flag(peer, IAX_DELME); 
08295       /* Make sure these are IPv4 addresses */
08296       peer->addr.sin_family = AF_INET;
08297    }
08298    if (oldha)
08299       ast_free_ha(oldha);
08300    return peer;
08301 }
08302 
08303 /*--- build_user: Create in-memory user structure from configuration */
08304 static struct iax2_user *build_user(const char *name, struct ast_variable *v, int temponly)
08305 {
08306    struct iax2_user *prev, *user;
08307    struct iax2_context *con, *conl = NULL;
08308    struct ast_ha *oldha = NULL;
08309    struct iax2_context *oldcon = NULL;
08310    int format;
08311    char *varname = NULL, *varval = NULL;
08312    struct ast_variable *tmpvar = NULL;
08313    
08314    prev = NULL;
08315    ast_mutex_lock(&userl.lock);
08316    if (!temponly) {
08317       user = userl.users;
08318       while(user) {
08319          if (!strcmp(user->name, name)) { 
08320             break;
08321          }
08322          prev = user;
08323          user = user->next;
08324       }
08325    } else
08326       user = NULL;
08327    
08328    if (user) {
08329       oldha = user->ha;
08330       oldcon = user->contexts;
08331       user->ha = NULL;
08332       user->contexts = NULL;
08333       /* Already in the list, remove it and it will be added back (or FREE'd) */
08334       if (prev) {
08335          prev->next = user->next;
08336       } else {
08337          userl.users = user->next;
08338       }
08339       ast_mutex_unlock(&userl.lock);
08340    } else {
08341       ast_mutex_unlock(&userl.lock);
08342       user = malloc(sizeof(struct iax2_user));
08343       if (user)
08344          memset(user, 0, sizeof(struct iax2_user));
08345    }
08346    
08347    if (user) {
08348       memset(user, 0, sizeof(struct iax2_user));
08349       user->prefs = prefs;
08350       user->capability = iax2_capability;
08351       user->encmethods = iax2_encryption;
08352       ast_copy_string(user->name, name, sizeof(user->name));
08353       ast_copy_string(user->language, language, sizeof(user->language));
08354       ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08355       while(v) {
08356          if (!strcasecmp(v->name, "context")) {
08357             con = build_context(v->value);
08358             if (con) {
08359                if (conl)
08360                   conl->next = con;
08361                else
08362                   user->contexts = con;
08363                conl = con;
08364             }
08365          } else if (!strcasecmp(v->name, "permit") ||
08366                   !strcasecmp(v->name, "deny")) {
08367             user->ha = ast_append_ha(v->name, v->value, user->ha);
08368          } else if (!strcasecmp(v->name, "setvar")) {
08369             varname = ast_strdupa(v->value);
08370             if (varname && (varval = strchr(varname,'='))) {
08371                *varval = '\0';
08372                varval++;
08373                if((tmpvar = ast_variable_new(varname, varval))) {
08374                   tmpvar->next = user->vars; 
08375                   user->vars = tmpvar;
08376                }
08377             }
08378          } else if (!strcasecmp(v->name, "allow")) {
08379             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08380          } else if (!strcasecmp(v->name, "disallow")) {
08381             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08382          } else if (!strcasecmp(v->name, "trunk")) {
08383             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08384             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08385                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08386                ast_clear_flag(user, IAX_TRUNK);
08387             }
08388          } else if (!strcasecmp(v->name, "auth")) {
08389             user->authmethods = get_auth_methods(v->value);
08390          } else if (!strcasecmp(v->name, "encryption")) {
08391             user->encmethods = get_encrypt_methods(v->value);
08392          } else if (!strcasecmp(v->name, "notransfer")) {
08393             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08394          } else if (!strcasecmp(v->name, "codecpriority")) {
08395             if(!strcasecmp(v->value, "caller"))
08396                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08397             else if(!strcasecmp(v->value, "disabled"))
08398                ast_set_flag(user, IAX_CODEC_NOPREFS);
08399             else if(!strcasecmp(v->value, "reqonly")) {
08400                ast_set_flag(user, IAX_CODEC_NOCAP);
08401                ast_set_flag(user, IAX_CODEC_NOPREFS);
08402             }
08403          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08404             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);  
08405          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08406             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);   
08407          } else if (!strcasecmp(v->name, "dbsecret")) {
08408             ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret));
08409          } else if (!strcasecmp(v->name, "secret")) {
08410             if (!ast_strlen_zero(user->secret)) {
08411                strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
08412                strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1);
08413             } else
08414                ast_copy_string(user->secret, v->value, sizeof(user->secret));
08415          } else if (!strcasecmp(v->name, "callerid")) {
08416             ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
08417             ast_set_flag(user, IAX_HASCALLERID);   
08418          } else if (!strcasecmp(v->name, "accountcode")) {
08419             ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
08420          } else if (!strcasecmp(v->name, "language")) {
08421             ast_copy_string(user->language, v->value, sizeof(user->language));
08422          } else if (!strcasecmp(v->name, "amaflags")) {
08423             format = ast_cdr_amaflags2int(v->value);
08424             if (format < 0) {
08425                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08426             } else {
08427                user->amaflags = format;
08428             }
08429          } else if (!strcasecmp(v->name, "inkeys")) {
08430             ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
08431          }/* else if (strcasecmp(v->name,"type")) */
08432          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08433          v = v->next;
08434       }
08435       if (!user->authmethods) {
08436          if (!ast_strlen_zero(user->secret)) {
08437             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08438             if (!ast_strlen_zero(user->inkeys))
08439                user->authmethods |= IAX_AUTH_RSA;
08440          } else if (!ast_strlen_zero(user->inkeys)) {
08441             user->authmethods = IAX_AUTH_RSA;
08442          } else {
08443             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08444          }
08445       }
08446       ast_clear_flag(user, IAX_DELME);
08447    }
08448    if (oldha)
08449       ast_free_ha(oldha);
08450    if (oldcon)
08451       free_context(oldcon);
08452    return user;
08453 }
08454 
08455 static void delete_users(void)
08456 {
08457    struct iax2_user *user;
08458    struct iax2_peer *peer;
08459    struct iax2_registry *reg, *regl;
08460 
08461    ast_mutex_lock(&userl.lock);
08462    for (user=userl.users;user;) {
08463       ast_set_flag(user, IAX_DELME);
08464       user = user->next;
08465    }
08466    ast_mutex_unlock(&userl.lock);
08467    for (reg = registrations;reg;) {
08468       regl = reg;
08469       reg = reg->next;
08470       if (regl->expire > -1) {
08471          ast_sched_del(sched, regl->expire);
08472       }
08473       if (regl->callno) {
08474          /* XXX Is this a potential lock?  I don't think so, but you never know */
08475          ast_mutex_lock(&iaxsl[regl->callno]);
08476          if (iaxs[regl->callno]) {
08477             iaxs[regl->callno]->reg = NULL;
08478             iax2_destroy_nolock(regl->callno);
08479          }
08480          ast_mutex_unlock(&iaxsl[regl->callno]);
08481       }
08482       free(regl);
08483    }
08484    registrations = NULL;
08485    ast_mutex_lock(&peerl.lock);
08486    for (peer=peerl.peers;peer;) {
08487       /* Assume all will be deleted, and we'll find out for sure later */
08488       ast_set_flag(peer, IAX_DELME);
08489       peer = peer->next;
08490    }
08491    ast_mutex_unlock(&peerl.lock);
08492 }
08493 
08494 static void destroy_user(struct iax2_user *user)
08495 {
08496    ast_free_ha(user->ha);
08497    free_context(user->contexts);
08498    if(user->vars) {
08499       ast_variables_destroy(user->vars);
08500       user->vars = NULL;
08501    }
08502    free(user);
08503 }
08504 
08505 static void prune_users(void)
08506 {
08507    struct iax2_user *user, *usernext, *userlast = NULL;
08508    ast_mutex_lock(&userl.lock);
08509    for (user=userl.users;user;) {
08510       usernext = user->next;
08511       if (ast_test_flag(user, IAX_DELME)) {
08512          destroy_user(user);
08513          if (userlast)
08514             userlast->next = usernext;
08515          else
08516             userl.users = usernext;
08517       } else
08518          userlast = user;
08519       user = usernext;
08520    }
08521    ast_mutex_unlock(&userl.lock);
08522 }
08523 
08524 static void destroy_peer(struct iax2_peer *peer)
08525 {
08526    int x;
08527    ast_free_ha(peer->ha);
08528    for (x=0;x<IAX_MAX_CALLS;x++) {
08529       ast_mutex_lock(&iaxsl[x]);
08530       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
08531          iax2_destroy(x);
08532       }
08533       ast_mutex_unlock(&iaxsl[x]);
08534    }
08535    /* Delete it, it needs to disappear */
08536    if (peer->expire > -1)
08537       ast_sched_del(sched, peer->expire);
08538    if (peer->pokeexpire > -1)
08539       ast_sched_del(sched, peer->pokeexpire);
08540    if (peer->callno > 0)
08541       iax2_destroy(peer->callno);
08542    register_peer_exten(peer, 0);
08543    if (peer->dnsmgr)
08544       ast_dnsmgr_release(peer->dnsmgr);
08545    free(peer);
08546 }
08547 
08548 static void prune_peers(void){
08549    /* Prune peers who still are supposed to be deleted */
08550    struct iax2_peer *peer, *peerlast, *peernext;
08551    ast_mutex_lock(&peerl.lock);
08552    peerlast = NULL;
08553    for (peer=peerl.peers;peer;) {
08554       peernext = peer->next;
08555       if (ast_test_flag(peer, IAX_DELME)) {
08556          destroy_peer(peer);
08557          if (peerlast)
08558             peerlast->next = peernext;
08559          else
08560             peerl.peers = peernext;
08561       } else
08562          peerlast = peer;
08563       peer=peernext;
08564    }
08565    ast_mutex_unlock(&peerl.lock);
08566 }
08567 
08568 static void set_timing(void)
08569 {
08570 #ifdef IAX_TRUNKING
08571    int bs = trunkfreq * 8;
08572    if (timingfd > -1) {
08573       if (
08574 #ifdef ZT_TIMERACK
08575          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08576 #endif         
08577          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08578          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08579    }
08580 #endif
08581 }
08582 
08583 
08584 /*--- set_config: Load configuration */
08585 static int set_config(char *config_file, int reload)
08586 {
08587    struct ast_config *cfg;
08588    int capability=iax2_capability;
08589    struct ast_variable *v;
08590    char *cat;
08591    char *utype;
08592    char *tosval;
08593    int format;
08594    int portno = IAX_DEFAULT_PORTNO;
08595    int  x;
08596    struct iax2_user *user;
08597    struct iax2_peer *peer;
08598    struct ast_netsock *ns;
08599 #if 0
08600    static unsigned short int last_port=0;
08601 #endif
08602 
08603    cfg = ast_config_load(config_file);
08604    
08605    if (!cfg) {
08606       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08607       return -1;
08608    }
08609 
08610    /* Reset global codec prefs */   
08611    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08612    
08613    /* Reset Global Flags */
08614    memset(&globalflags, 0, sizeof(globalflags));
08615    ast_set_flag(&globalflags, IAX_RTUPDATE);
08616 
08617 #ifdef SO_NO_CHECK
08618    nochecksums = 0;
08619 #endif
08620 
08621    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08622    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08623 
08624    v = ast_variable_browse(cfg, "general");
08625 
08626    /* Seed initial tos value */
08627    tosval = ast_variable_retrieve(cfg, "general", "tos");
08628    if (tosval) {
08629       if (ast_str2tos(tosval, &tos))
08630          ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n");
08631    }
08632    while(v) {
08633       if (!strcasecmp(v->name, "bindport")){ 
08634          if (reload)
08635             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
08636          else
08637             portno = atoi(v->value);
08638       } else if (!strcasecmp(v->name, "pingtime")) 
08639          ping_time = atoi(v->value);
08640       else if (!strcasecmp(v->name, "nochecksums")) {
08641 #ifdef SO_NO_CHECK
08642          if (ast_true(v->value))
08643             nochecksums = 1;
08644          else
08645             nochecksums = 0;
08646 #else
08647          if (ast_true(v->value))
08648             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
08649 #endif
08650       }
08651       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
08652          maxjitterbuffer = atoi(v->value);
08653 #ifdef NEWJB
08654       else if (!strcasecmp(v->name, "resyncthreshold")) 
08655          resyncthreshold = atoi(v->value);
08656       else if (!strcasecmp(v->name, "maxjitterinterps")) 
08657          maxjitterinterps = atoi(v->value);
08658 #endif
08659       else if (!strcasecmp(v->name, "jittershrinkrate")) 
08660          jittershrinkrate = atoi(v->value);
08661       else if (!strcasecmp(v->name, "maxexcessbuffer")) 
08662          max_jitter_buffer = atoi(v->value);
08663       else if (!strcasecmp(v->name, "minexcessbuffer")) 
08664          min_jitter_buffer = atoi(v->value);
08665       else if (!strcasecmp(v->name, "lagrqtime")) 
08666          lagrq_time = atoi(v->value);
08667       else if (!strcasecmp(v->name, "dropcount")) 
08668          iax2_dropcount = atoi(v->value);
08669       else if (!strcasecmp(v->name, "maxregexpire")) 
08670          max_reg_expire = atoi(v->value);
08671       else if (!strcasecmp(v->name, "minregexpire")) 
08672          min_reg_expire = atoi(v->value);
08673       else if (!strcasecmp(v->name, "bindaddr")) {
08674          if (reload) {
08675             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
08676          } else {
08677             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
08678                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
08679             } else {
08680                if (option_verbose > 1) {
08681                   if (strchr(v->value, ':'))
08682                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
08683                   else
08684                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
08685                }
08686                if (defaultsockfd < 0) 
08687                   defaultsockfd = ast_netsock_sockfd(ns);
08688                ast_netsock_unref(ns);
08689             }
08690          }
08691       } else if (!strcasecmp(v->name, "authdebug"))
08692          authdebug = ast_true(v->value);
08693       else if (!strcasecmp(v->name, "encryption"))
08694          iax2_encryption = get_encrypt_methods(v->value);
08695       else if (!strcasecmp(v->name, "notransfer"))
08696          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
08697       else if (!strcasecmp(v->name, "codecpriority")) {
08698          if(!strcasecmp(v->value, "caller"))
08699             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
08700          else if(!strcasecmp(v->value, "disabled"))
08701             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08702          else if(!strcasecmp(v->value, "reqonly")) {
08703             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
08704             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08705          }
08706       } else if (!strcasecmp(v->name, "jitterbuffer"))
08707          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
08708       else if (!strcasecmp(v->name, "forcejitterbuffer"))
08709          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
08710       else if (!strcasecmp(v->name, "delayreject"))
08711          delayreject = ast_true(v->value);
08712       else if (!strcasecmp(v->name, "mailboxdetail"))
08713          ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL);   
08714       else if (!strcasecmp(v->name, "rtcachefriends"))
08715          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
08716       else if (!strcasecmp(v->name, "rtignoreregexpire"))
08717          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
08718       else if (!strcasecmp(v->name, "rtupdate"))
08719          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
08720       else if (!strcasecmp(v->name, "trunktimestamps"))
08721          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
08722       else if (!strcasecmp(v->name, "rtautoclear")) {
08723          int i = atoi(v->value);
08724          if(i > 0)
08725             global_rtautoclear = i;
08726          else
08727             i = 0;
08728          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
08729       } else if (!strcasecmp(v->name, "trunkfreq")) {
08730          trunkfreq = atoi(v->value);
08731          if (trunkfreq < 10)
08732             trunkfreq = 10;
08733       } else if (!strcasecmp(v->name, "autokill")) {
08734          if (sscanf(v->value, "%d", &x) == 1) {
08735             if (x >= 0)
08736                autokill = x;
08737             else
08738                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
08739          } else if (ast_true(v->value)) {
08740             autokill = DEFAULT_MAXMS;
08741          } else {
08742             autokill = 0;
08743          }
08744       } else if (!strcasecmp(v->name, "bandwidth")) {
08745          if (!strcasecmp(v->value, "low")) {
08746             capability = IAX_CAPABILITY_LOWBANDWIDTH;
08747          } else if (!strcasecmp(v->value, "medium")) {
08748             capability = IAX_CAPABILITY_MEDBANDWIDTH;
08749          } else if (!strcasecmp(v->value, "high")) {
08750             capability = IAX_CAPABILITY_FULLBANDWIDTH;
08751          } else
08752             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
08753       } else if (!strcasecmp(v->name, "allow")) {
08754          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
08755       } else if (!strcasecmp(v->name, "disallow")) {
08756          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
08757       } else if (!strcasecmp(v->name, "register")) {
08758          iax2_register(v->value, v->lineno);
08759       } else if (!strcasecmp(v->name, "iaxcompat")) {
08760          iaxcompat = ast_true(v->value);
08761       } else if (!strcasecmp(v->name, "regcontext")) {
08762          ast_copy_string(regcontext, v->value, sizeof(regcontext));
08763          /* Create context if it doesn't exist already */
08764          if (!ast_context_find(regcontext))
08765             ast_context_create(NULL, regcontext, channeltype);
08766       } else if (!strcasecmp(v->name, "tos")) {
08767          if (ast_str2tos(v->value, &tos))
08768             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
08769       } else if (!strcasecmp(v->name, "accountcode")) {
08770          ast_copy_string(accountcode, v->value, sizeof(accountcode));
08771       } else if (!strcasecmp(v->name, "amaflags")) {
08772          format = ast_cdr_amaflags2int(v->value);
08773          if (format < 0) {
08774             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08775          } else {
08776             amaflags = format;
08777          }
08778       } else if (!strcasecmp(v->name, "language")) {
08779                         ast_copy_string(language, v->value, sizeof(language));
08780       } /*else if (strcasecmp(v->name,"type")) */
08781       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08782       v = v->next;
08783    }
08784    
08785    if (defaultsockfd < 0) {
08786       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
08787          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
08788       } else {
08789          if (option_verbose > 1)
08790             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
08791          defaultsockfd = ast_netsock_sockfd(ns);
08792          ast_netsock_unref(ns);
08793       }
08794    }
08795    
08796    if (min_reg_expire > max_reg_expire) {
08797       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
08798          min_reg_expire, max_reg_expire, max_reg_expire);
08799       min_reg_expire = max_reg_expire;
08800    }
08801    iax2_capability = capability;
08802    cat = ast_category_browse(cfg, NULL);
08803    while(cat) {
08804       if (strcasecmp(cat, "general")) {
08805          utype = ast_variable_retrieve(cfg, cat, "type");
08806          if (utype) {
08807             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
08808                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
08809                if (user) {
08810                   ast_mutex_lock(&userl.lock);
08811                   user->next = userl.users;
08812                   userl.users = user;
08813                   ast_mutex_unlock(&userl.lock);
08814                }
08815             }
08816             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
08817                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
08818                if (peer) {
08819                   ast_mutex_lock(&peerl.lock);
08820                   peer->next = peerl.peers;
08821                   peerl.peers = peer;
08822                   ast_mutex_unlock(&peerl.lock);
08823                   if (ast_test_flag(peer, IAX_DYNAMIC))
08824                      reg_source_db(peer);
08825                }
08826             } else if (strcasecmp(utype, "user")) {
08827                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
08828             }
08829          } else
08830             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
08831       }
08832       cat = ast_category_browse(cfg, cat);
08833    }
08834    ast_config_destroy(cfg);
08835    set_timing();
08836    return capability;
08837 }
08838 
08839 static int reload_config(void)
08840 {
08841    char *config = "iax.conf";
08842    struct iax2_registry *reg;
08843    struct iax2_peer *peer;
08844    ast_copy_string(accountcode, "", sizeof(accountcode));
08845    ast_copy_string(language, "", sizeof(language));
08846    amaflags = 0;
08847    delayreject = 0;
08848    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
08849    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
08850    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
08851    delete_users();
08852    set_config(config,1);
08853    prune_peers();
08854    prune_users();
08855    for (reg = registrations; reg; reg = reg->next)
08856       iax2_do_register(reg);
08857    /* Qualify hosts, too */
08858    ast_mutex_lock(&peerl.lock);
08859    for (peer = peerl.peers; peer; peer = peer->next)
08860       iax2_poke_peer(peer, 0);
08861    ast_mutex_unlock(&peerl.lock);
08862    reload_firmware();
08863    iax_provision_reload();
08864    return 0;
08865 }
08866 
08867 static int iax2_reload(int fd, int argc, char *argv[])
08868 {
08869    return reload_config();
08870 }
08871 
08872 int reload(void)
08873 {
08874    return reload_config();
08875 }
08876 
08877 static int cache_get_callno_locked(const char *data)
08878 {
08879    struct sockaddr_in sin;
08880    int x;
08881    int callno;
08882    struct iax_ie_data ied;
08883    struct create_addr_info cai;
08884    struct parsed_dial_string pds;
08885    char *tmpstr;
08886 
08887    for (x=0; x<IAX_MAX_CALLS; x++) {
08888       /* Look for an *exact match* call.  Once a call is negotiated, it can only
08889          look up entries for a single context */
08890       if (!ast_mutex_trylock(&iaxsl[x])) {
08891          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
08892             return x;
08893          ast_mutex_unlock(&iaxsl[x]);
08894       }
08895    }
08896 
08897    /* No match found, we need to create a new one */
08898 
08899    memset(&cai, 0, sizeof(cai));
08900    memset(&ied, 0, sizeof(ied));
08901    memset(&pds, 0, sizeof(pds));
08902 
08903    tmpstr = ast_strdupa(data);
08904    parse_dial_string(tmpstr, &pds);
08905 
08906    /* Populate our address from the given */
08907    if (create_addr(pds.peer, &sin, &cai))
08908       return -1;
08909 
08910    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
08911       pds.peer, pds.username, pds.password, pds.context);
08912 
08913    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08914    if (callno < 1) {
08915       ast_log(LOG_WARNING, "Unable to create call\n");
08916       return -1;
08917    }
08918 
08919    ast_mutex_lock(&iaxsl[callno]);
08920    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
08921    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
08922 
08923    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
08924    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
08925    /* the string format is slightly different from a standard dial string,
08926       because the context appears in the 'exten' position
08927    */
08928    if (pds.exten)
08929       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
08930    if (pds.username)
08931       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
08932    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
08933    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
08934    /* Keep password handy */
08935    if (pds.password)
08936       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
08937    if (pds.key)
08938       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
08939    /* Start the call going */
08940    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
08941 
08942    return callno;
08943 }
08944 
08945 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
08946 {
08947    struct iax2_dpcache *dp, *prev = NULL, *next;
08948    struct timeval tv;
08949    int x;
08950    int com[2];
08951    int timeout;
08952    int old=0;
08953    int outfd;
08954    int abort;
08955    int callno;
08956    struct ast_channel *c;
08957    struct ast_frame *f;
08958    gettimeofday(&tv, NULL);
08959    dp = dpcache;
08960    while(dp) {
08961       next = dp->next;
08962       /* Expire old caches */
08963       if (ast_tvcmp(tv, dp->expiry) > 0) {
08964             /* It's expired, let it disappear */
08965             if (prev)
08966                prev->next = dp->next;
08967             else
08968                dpcache = dp->next;
08969             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
08970                /* Free memory and go again */
08971                free(dp);
08972             } else {
08973                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);
08974             }
08975             dp = next;
08976             continue;
08977       }
08978       /* We found an entry that matches us! */
08979       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
08980          break;
08981       prev = dp;
08982       dp = next;
08983    }
08984    if (!dp) {
08985       /* No matching entry.  Create a new one. */
08986       /* First, can we make a callno? */
08987       callno = cache_get_callno_locked(data);
08988       if (callno < 0) {
08989          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
08990          return NULL;
08991       }
08992       dp = malloc(sizeof(struct iax2_dpcache));
08993       if (!dp) {
08994          ast_mutex_unlock(&iaxsl[callno]);
08995          return NULL;
08996       }
08997       memset(dp, 0, sizeof(struct iax2_dpcache));
08998       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
08999       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09000       gettimeofday(&dp->expiry, NULL);
09001       dp->orig = dp->expiry;
09002       /* Expires in 30 mins by default */
09003       dp->expiry.tv_sec += iaxdefaultdpcache;
09004       dp->next = dpcache;
09005       dp->flags = CACHE_FLAG_PENDING;
09006       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09007          dp->waiters[x] = -1;
09008       dpcache = dp;
09009       dp->peer = iaxs[callno]->dpentries;
09010       iaxs[callno]->dpentries = dp;
09011       /* Send the request if we're already up */
09012       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09013          iax2_dprequest(dp, callno);
09014       ast_mutex_unlock(&iaxsl[callno]);
09015    }
09016    /* By here we must have a dp */
09017    if (dp->flags & CACHE_FLAG_PENDING) {
09018       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09019          for a reply to come back so long as it's pending */
09020       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09021          /* Find an empty slot */
09022          if (dp->waiters[x] < 0)
09023             break;
09024       }
09025       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09026          ast_log(LOG_WARNING, "No more waiter positions available\n");
09027          return NULL;
09028       }
09029       if (pipe(com)) {
09030          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09031          return NULL;
09032       }
09033       dp->waiters[x] = com[1];
09034       /* Okay, now we wait */
09035       timeout = iaxdefaulttimeout * 1000;
09036       /* Temporarily unlock */
09037       ast_mutex_unlock(&dpcache_lock);
09038       /* Defer any dtmf */
09039       if (chan)
09040          old = ast_channel_defer_dtmf(chan);
09041       abort = 0;
09042       while(timeout) {
09043          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09044          if (outfd > -1) {
09045             break;
09046          }
09047          if (c) {
09048             f = ast_read(c);
09049             if (f)
09050                ast_frfree(f);
09051             else {
09052                /* Got hung up on, abort! */
09053                break;
09054                abort = 1;
09055             }
09056          }
09057       }
09058       if (!timeout) {
09059          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09060       }
09061       ast_mutex_lock(&dpcache_lock);
09062       dp->waiters[x] = -1;
09063       close(com[1]);
09064       close(com[0]);
09065       if (abort) {
09066          /* Don't interpret anything, just abort.  Not sure what th epoint
09067            of undeferring dtmf on a hung up channel is but hey whatever */
09068          if (!old && chan)
09069             ast_channel_undefer_dtmf(chan);
09070          return NULL;
09071       }
09072       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09073          /* Now to do non-independent analysis the results of our wait */
09074          if (dp->flags & CACHE_FLAG_PENDING) {
09075             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09076                pending.  Don't let it take as long to timeout. */
09077             dp->flags &= ~CACHE_FLAG_PENDING;
09078             dp->flags |= CACHE_FLAG_TIMEOUT;
09079             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09080                systems without leaving it unavailable once the server comes back online */
09081             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09082             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09083                if (dp->waiters[x] > -1)
09084                   write(dp->waiters[x], "asdf", 4);
09085          }
09086       }
09087       /* Our caller will obtain the rest */
09088       if (!old && chan)
09089          ast_channel_undefer_dtmf(chan);
09090    }
09091    return dp;  
09092 }
09093 
09094 /*--- iax2_exists: Part of the IAX2 switch interface ---*/
09095 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09096 {
09097    struct iax2_dpcache *dp;
09098    int res = 0;
09099 #if 0
09100    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09101 #endif
09102    if ((priority != 1) && (priority != 2))
09103       return 0;
09104    ast_mutex_lock(&dpcache_lock);
09105    dp = find_cache(chan, data, context, exten, priority);
09106    if (dp) {
09107       if (dp->flags & CACHE_FLAG_EXISTS)
09108          res= 1;
09109    }
09110    ast_mutex_unlock(&dpcache_lock);
09111    if (!dp) {
09112       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09113    }
09114    return res;
09115 }
09116 
09117 /*--- iax2_canmatch: part of the IAX2 dial plan switch interface */
09118 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09119 {
09120    int res = 0;
09121    struct iax2_dpcache *dp;
09122 #if 0
09123    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09124 #endif
09125    if ((priority != 1) && (priority != 2))
09126       return 0;
09127    ast_mutex_lock(&dpcache_lock);
09128    dp = find_cache(chan, data, context, exten, priority);
09129    if (dp) {
09130       if (dp->flags & CACHE_FLAG_CANEXIST)
09131          res= 1;
09132    }
09133    ast_mutex_unlock(&dpcache_lock);
09134    if (!dp) {
09135       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09136    }
09137    return res;
09138 }
09139 
09140 /*--- iax2_matchmore: Part of the IAX2 Switch interface */
09141 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09142 {
09143    int res = 0;
09144    struct iax2_dpcache *dp;
09145 #if 0
09146    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09147 #endif
09148    if ((priority != 1) && (priority != 2))
09149       return 0;
09150    ast_mutex_lock(&dpcache_lock);
09151    dp = find_cache(chan, data, context, exten, priority);
09152    if (dp) {
09153       if (dp->flags & CACHE_FLAG_MATCHMORE)
09154          res= 1;
09155    }
09156    ast_mutex_unlock(&dpcache_lock);
09157    if (!dp) {
09158       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09159    }
09160    return res;
09161 }
09162 
09163 /*--- iax2_exec: Execute IAX2 dialplan switch */
09164 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
09165 {
09166    char odata[256];
09167    char req[256];
09168    char *ncontext;
09169    char *dialstatus;
09170    struct iax2_dpcache *dp;
09171    struct ast_app *dial;
09172 #if 0
09173    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);
09174 #endif
09175    if (priority == 2) {
09176       /* Indicate status, can be overridden in dialplan */
09177       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09178       if (dialstatus) {
09179          dial = pbx_findapp(dialstatus);
09180          if (dial) 
09181             pbx_exec(chan, dial, "", newstack);
09182       }
09183       return -1;
09184    } else if (priority != 1)
09185       return -1;
09186    ast_mutex_lock(&dpcache_lock);
09187    dp = find_cache(chan, data, context, exten, priority);
09188    if (dp) {
09189       if (dp->flags & CACHE_FLAG_EXISTS) {
09190          ast_copy_string(odata, data, sizeof(odata));
09191          ncontext = strchr(odata, '/');
09192          if (ncontext) {
09193             *ncontext = '\0';
09194             ncontext++;
09195             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09196          } else {
09197             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09198          }
09199          if (option_verbose > 2)
09200             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09201       } else {
09202          ast_mutex_unlock(&dpcache_lock);
09203          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09204          return -1;
09205       }
09206    }
09207    ast_mutex_unlock(&dpcache_lock);
09208    dial = pbx_findapp("Dial");
09209    if (dial) {
09210       return pbx_exec(chan, dial, req, newstack);
09211    } else {
09212       ast_log(LOG_WARNING, "No dial application registered\n");
09213    }
09214    return -1;
09215 }
09216 
09217 static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
09218 {
09219    char *ret = NULL;
09220    struct iax2_peer *peer;
09221    char *peername, *colname;
09222    char iabuf[INET_ADDRSTRLEN];
09223 
09224    if (!(peername = ast_strdupa(data))) {
09225       ast_log(LOG_ERROR, "Memory Error!\n");
09226       return ret;
09227    }
09228 
09229    /* if our channel, return the IP address of the endpoint of current channel */
09230    if (!strcmp(peername,"CURRENTCHANNEL")) {
09231            unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09232       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
09233       return buf;
09234    }
09235 
09236    if ((colname = strchr(peername, ':'))) {
09237       *colname = '\0';
09238       colname++;
09239    } else {
09240       colname = "ip";
09241    }
09242    if (!(peer = find_peer(peername, 1)))
09243       return ret;
09244 
09245    if (!strcasecmp(colname, "ip")) {
09246       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09247    } else  if (!strcasecmp(colname, "status")) {
09248       peer_status(peer, buf, len); 
09249    } else  if (!strcasecmp(colname, "mailbox")) {
09250       ast_copy_string(buf, peer->mailbox, len);
09251    } else  if (!strcasecmp(colname, "context")) {
09252       ast_copy_string(buf, peer->context, len);
09253    } else  if (!strcasecmp(colname, "expire")) {
09254       snprintf(buf, len, "%d", peer->expire);
09255    } else  if (!strcasecmp(colname, "dynamic")) {
09256       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09257    } else  if (!strcasecmp(colname, "callerid_name")) {
09258       ast_copy_string(buf, peer->cid_name, len);
09259    } else  if (!strcasecmp(colname, "callerid_num")) {
09260       ast_copy_string(buf, peer->cid_num, len);
09261    } else  if (!strcasecmp(colname, "codecs")) {
09262       ast_getformatname_multiple(buf, len -1, peer->capability);
09263    } else  if (!strncasecmp(colname, "codec[", 6)) {
09264       char *codecnum, *ptr;
09265       int index = 0, codec = 0;
09266       
09267       codecnum = strchr(colname, '[');
09268       *codecnum = '\0';
09269       codecnum++;
09270       if ((ptr = strchr(codecnum, ']'))) {
09271          *ptr = '\0';
09272       }
09273       index = atoi(codecnum);
09274       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09275          ast_copy_string(buf, ast_getformatname(codec), len);
09276       }
09277    }
09278    ret = buf;
09279 
09280    return ret;
09281 }
09282 
09283 struct ast_custom_function iaxpeer_function = {
09284     .name = "IAXPEER",
09285     .synopsis = "Gets IAX peer information",
09286     .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[:item])",
09287     .read = function_iaxpeer,
09288    .desc = "If peername specified, valid items are:\n"
09289    "- ip (default)          The IP address.\n"
09290    "- status                The peer's status (if qualify=yes)\n"
09291    "- mailbox               The configured mailbox.\n"
09292    "- context               The configured context.\n"
09293    "- expire                The epoch time of the next expire.\n"
09294    "- dynamic               Is it dynamic? (yes/no).\n"
09295    "- callerid_name         The configured Caller ID name.\n"
09296    "- callerid_num          The configured Caller ID number.\n"
09297    "- codecs                The configured codecs.\n"
09298    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
09299    "\n"
09300    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
09301    "\n"
09302 };
09303 
09304 
09305 /*--- iax2_devicestate: Part of the device state notification system ---*/
09306 static int iax2_devicestate(void *data) 
09307 {
09308    char *dest = (char *) data;
09309    struct iax2_peer *p;
09310    int found = 0;
09311    char *ext, *host;
09312    char tmp[256];
09313    int res = AST_DEVICE_INVALID;
09314 
09315    ast_copy_string(tmp, dest, sizeof(tmp));
09316    host = strchr(tmp, '@');
09317    if (host) {
09318       *host = '\0';
09319       host++;
09320       ext = tmp;
09321    } else {
09322       host = tmp;
09323       ext = NULL;
09324    }
09325 
09326    if (option_debug > 2)
09327       ast_log(LOG_DEBUG, "Checking device state for device %s\n", dest);
09328 
09329    /* SLD: FIXME: second call to find_peer during registration */
09330    p = find_peer(host, 1);
09331    if (p) {
09332       found++;
09333       res = AST_DEVICE_UNAVAILABLE;
09334       if (option_debug > 2) 
09335          ast_log(LOG_DEBUG, "iax2_devicestate(%s): Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09336             host, dest, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09337 
09338       if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09339           (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09340          /* Peer is registered, or have default IP address
09341             and a valid registration */
09342          if (p->historicms == 0 || p->historicms <= p->maxms)
09343             /* let the core figure out whether it is in use or not */
09344             res = AST_DEVICE_UNKNOWN;  
09345       }
09346    } else {
09347       if (option_debug > 2) 
09348          ast_log(LOG_DEBUG, "Devicestate: Can't find peer %s.\n", host);
09349    }
09350    
09351    if (p && ast_test_flag(p, IAX_TEMPONLY))
09352       destroy_peer(p);
09353    return res;
09354 }
09355 
09356 static struct ast_switch iax2_switch = 
09357 {
09358    name:          "IAX2",
09359    description:      "IAX Remote Dialplan Switch",
09360    exists:        iax2_exists,
09361    canmatch:      iax2_canmatch,
09362    exec:       iax2_exec,
09363    matchmore:     iax2_matchmore,
09364 };
09365 
09366 static char show_stats_usage[] =
09367 "Usage: iax show stats\n"
09368 "       Display statistics on IAX channel driver.\n";
09369 
09370 static char show_cache_usage[] =
09371 "Usage: iax show cache\n"
09372 "       Display currently cached IAX Dialplan results.\n";
09373 
09374 static char show_peer_usage[] =
09375 "Usage: iax show peer <name>\n"
09376 "       Display details on specific IAX peer\n";
09377 
09378 static char prune_realtime_usage[] =
09379 "Usage: iax2 prune realtime [<peername>|all]\n"
09380 "       Prunes object(s) from the cache\n";
09381 
09382 static char iax2_reload_usage[] =
09383 "Usage: iax2 reload\n"
09384 "       Reloads IAX configuration from iax.conf\n";
09385 
09386 static char show_prov_usage[] =
09387 "Usage: iax2 provision <host> <template> [forced]\n"
09388 "       Provisions the given peer or IP address using a template\n"
09389 "       matching either 'template' or '*' if the template is not\n"
09390 "       found.  If 'forced' is specified, even empty provisioning\n"
09391 "       fields will be provisioned as empty fields.\n";
09392 
09393 static char show_users_usage[] = 
09394 "Usage: iax2 show users [like <pattern>]\n"
09395 "       Lists all known IAX2 users.\n"
09396 "       Optional regular expression pattern is used to filter the user list.\n";
09397 
09398 static char show_channels_usage[] = 
09399 "Usage: iax2 show channels\n"
09400 "       Lists all currently active IAX channels.\n";
09401 
09402 static char show_netstats_usage[] = 
09403 "Usage: iax2 show netstats\n"
09404 "       Lists network status for all currently active IAX channels.\n";
09405 
09406 static char show_peers_usage[] = 
09407 "Usage: iax2 show peers [registered] [like <pattern>]\n"
09408 "       Lists all known IAX2 peers.\n"
09409 "       Optional 'registered' argument lists only peers with known addresses.\n"
09410 "       Optional regular expression pattern is used to filter the peer list.\n";
09411 
09412 static char show_firmware_usage[] = 
09413 "Usage: iax2 show firmware\n"
09414 "       Lists all known IAX firmware images.\n";
09415 
09416 static char show_reg_usage[] =
09417 "Usage: iax2 show registry\n"
09418 "       Lists all registration requests and status.\n";
09419 
09420 static char debug_usage[] = 
09421 "Usage: iax2 debug\n"
09422 "       Enables dumping of IAX packets for debugging purposes\n";
09423 
09424 static char no_debug_usage[] = 
09425 "Usage: iax2 no debug\n"
09426 "       Disables dumping of IAX packets for debugging purposes\n";
09427 
09428 static char debug_trunk_usage[] =
09429 "Usage: iax2 trunk debug\n"
09430 "       Requests current status of IAX trunking\n";
09431 
09432 static char no_debug_trunk_usage[] =
09433 "Usage: iax2 no trunk debug\n"
09434 "       Requests current status of IAX trunking\n";
09435 
09436 static char debug_jb_usage[] =
09437 "Usage: iax2 jb debug\n"
09438 "       Enables jitterbuffer debugging information\n";
09439 
09440 static char no_debug_jb_usage[] =
09441 "Usage: iax2 no jb debug\n"
09442 "       Disables jitterbuffer debugging information\n";
09443 
09444 static char iax2_test_losspct_usage[] =
09445 "Usage: iax2 test losspct <percentage>\n"
09446 "       For testing, throws away <percentage> percent of incoming packets\n";
09447 
09448 #ifdef IAXTESTS
09449 static char iax2_test_late_usage[] =
09450 "Usage: iax2 test late <ms>\n"
09451 "       For testing, count the next frame as <ms> ms late\n";
09452 
09453 static char iax2_test_resync_usage[] =
09454 "Usage: iax2 test resync <ms>\n"
09455 "       For testing, adjust all future frames by <ms> ms\n";
09456 
09457 static char iax2_test_jitter_usage[] =
09458 "Usage: iax2 test jitter <ms> <pct>\n"
09459 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
09460 #endif /* IAXTESTS */
09461 
09462 static struct ast_cli_entry iax2_cli[] = {
09463    { { "iax2", "set", "jitter", NULL }, iax2_set_jitter,
09464      "Sets IAX jitter buffer", jitter_usage },
09465    { { "iax2", "show", "stats", NULL }, iax2_show_stats,
09466      "Display IAX statistics", show_stats_usage },
09467    { { "iax2", "show", "cache", NULL }, iax2_show_cache,
09468      "Display IAX cached dialplan", show_cache_usage },
09469    { { "iax2", "show", "peer", NULL }, iax2_show_peer,
09470      "Show details on specific IAX peer", show_peer_usage, complete_iax2_show_peer },
09471    { { "iax2", "prune", "realtime", NULL }, iax2_prune_realtime,
09472      "Prune a cached realtime lookup", prune_realtime_usage, complete_iax2_show_peer },
09473    { { "iax2", "reload", NULL }, iax2_reload,
09474      "Reload IAX configuration", iax2_reload_usage },
09475    { { "iax2", "show", "users", NULL }, iax2_show_users,
09476      "Show defined IAX users", show_users_usage },
09477    { { "iax2", "show", "firmware", NULL }, iax2_show_firmware,
09478      "Show available IAX firmwares", show_firmware_usage },
09479    { { "iax2", "show", "channels", NULL }, iax2_show_channels,
09480      "Show active IAX channels", show_channels_usage },
09481    { { "iax2", "show", "netstats", NULL }, iax2_show_netstats,
09482      "Show active IAX channel netstats", show_netstats_usage },
09483    { { "iax2", "show", "peers", NULL }, iax2_show_peers,
09484      "Show defined IAX peers", show_peers_usage },
09485    { { "iax2", "show", "registry", NULL }, iax2_show_registry,
09486      "Show IAX registration status", show_reg_usage },
09487    { { "iax2", "debug", NULL }, iax2_do_debug,
09488      "Enable IAX debugging", debug_usage },
09489    { { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug,
09490      "Enable IAX trunk debugging", debug_trunk_usage },
09491    { { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug,
09492      "Enable IAX jitterbuffer debugging", debug_jb_usage },
09493    { { "iax2", "no", "debug", NULL }, iax2_no_debug,
09494      "Disable IAX debugging", no_debug_usage },
09495    { { "iax2", "no", "trunk", "debug", NULL }, iax2_no_trunk_debug,
09496      "Disable IAX trunk debugging", no_debug_trunk_usage },
09497    { { "iax2", "no", "jb", "debug", NULL }, iax2_no_jb_debug,
09498      "Disable IAX jitterbuffer debugging", no_debug_jb_usage },
09499    { { "iax2", "test", "losspct", NULL }, iax2_test_losspct,
09500      "Set IAX2 incoming frame loss percentage", iax2_test_losspct_usage },
09501    { { "iax2", "provision", NULL }, iax2_prov_cmd,
09502      "Provision an IAX device", show_prov_usage, iax2_prov_complete_template_3rd },
09503 #ifdef IAXTESTS
09504    { { "iax2", "test", "late", NULL }, iax2_test_late,
09505      "Test the receipt of a late frame", iax2_test_late_usage },
09506    { { "iax2", "test", "resync", NULL }, iax2_test_resync,
09507      "Test a resync in received timestamps", iax2_test_resync_usage },
09508    { { "iax2", "test", "jitter", NULL }, iax2_test_jitter,
09509      "Simulates jitter for testing", iax2_test_jitter_usage },
09510 #endif /* IAXTESTS */
09511 };
09512 
09513 static int __unload_module(void)
09514 {
09515    int x;
09516    /* Cancel the network thread, close the net socket */
09517    if (netthreadid != AST_PTHREADT_NULL) {
09518       pthread_cancel(netthreadid);
09519       pthread_join(netthreadid, NULL);
09520    }
09521    ast_netsock_release(netsock);
09522    for (x=0;x<IAX_MAX_CALLS;x++)
09523       if (iaxs[x])
09524          iax2_destroy(x);
09525    ast_manager_unregister( "IAXpeers" );
09526    ast_manager_unregister( "IAXnetstats" );
09527    ast_unregister_application(papp);
09528    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09529    ast_unregister_switch(&iax2_switch);
09530    ast_channel_unregister(&iax2_tech);
09531    delete_users();
09532    iax_provision_unload();
09533    sched_context_destroy(sched);
09534    return 0;
09535 }
09536 
09537 int unload_module()
09538 {
09539    ast_mutex_destroy(&iaxq.lock);
09540    ast_mutex_destroy(&userl.lock);
09541    ast_mutex_destroy(&peerl.lock);
09542    ast_mutex_destroy(&waresl.lock);
09543    ast_custom_function_unregister(&iaxpeer_function);
09544    return __unload_module();
09545 }
09546 
09547 
09548 /*--- load_module: Load IAX2 module, load configuraiton ---*/
09549 int load_module(void)
09550 {
09551    char *config = "iax.conf";
09552    int res = 0;
09553    int x;
09554    struct iax2_registry *reg;
09555    struct iax2_peer *peer;
09556    
09557    ast_custom_function_register(&iaxpeer_function);
09558 
09559    iax_set_output(iax_debug_output);
09560    iax_set_error(iax_error_output);
09561 #ifdef NEWJB
09562    jb_setoutput(jb_error_output, jb_warning_output, NULL);
09563 #endif
09564    
09565 #ifdef IAX_TRUNKING
09566 #ifdef ZT_TIMERACK
09567    timingfd = open("/dev/zap/timer", O_RDWR);
09568    if (timingfd < 0)
09569 #endif
09570       timingfd = open("/dev/zap/pseudo", O_RDWR);
09571    if (timingfd < 0) 
09572       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
09573 #endif      
09574 
09575    memset(iaxs, 0, sizeof(iaxs));
09576 
09577    for (x=0;x<IAX_MAX_CALLS;x++)
09578       ast_mutex_init(&iaxsl[x]);
09579    
09580    io = io_context_create();
09581    sched = sched_context_create();
09582    
09583    if (!io || !sched) {
09584       ast_log(LOG_ERROR, "Out of memory\n");
09585       return -1;
09586    }
09587 
09588    netsock = ast_netsock_list_alloc();
09589    if (!netsock) {
09590       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
09591       return -1;
09592    }
09593    ast_netsock_init(netsock);
09594 
09595    ast_mutex_init(&iaxq.lock);
09596    ast_mutex_init(&userl.lock);
09597    ast_mutex_init(&peerl.lock);
09598    ast_mutex_init(&waresl.lock);
09599    
09600    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09601 
09602    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
09603    
09604    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
09605    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
09606 
09607    set_config(config, 0);
09608 
09609    if (ast_channel_register(&iax2_tech)) {
09610       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
09611       __unload_module();
09612       return -1;
09613    }
09614 
09615    if (ast_register_switch(&iax2_switch)) 
09616       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
09617 
09618    res = start_network_thread();
09619    if (!res) {
09620       if (option_verbose > 1) 
09621          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
09622    } else {
09623       ast_log(LOG_ERROR, "Unable to start network thread\n");
09624       ast_netsock_release(netsock);
09625    }
09626 
09627    for (reg = registrations; reg; reg = reg->next)
09628       iax2_do_register(reg);
09629    ast_mutex_lock(&peerl.lock);
09630    for (peer = peerl.peers; peer; peer = peer->next) {
09631       if (peer->sockfd < 0)
09632          peer->sockfd = defaultsockfd;
09633       iax2_poke_peer(peer, 0);
09634    }
09635    ast_mutex_unlock(&peerl.lock);
09636    reload_firmware();
09637    iax_provision_reload();
09638    return res;
09639 }
09640 
09641 char *description()
09642 {
09643    return (char *) desc;
09644 }
09645 
09646 int usecount()
09647 {
09648    return usecnt;
09649 }
09650 
09651 char *key()
09652 {
09653    return ASTERISK_GPL_KEY;
09654 }

Generated on Fri May 26 01:45:30 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6