Wed Aug 15 01:24:16 2007

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, 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  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>zaptel</use>
00033  ***/
00034 
00035 #include "asterisk.h"
00036 
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 78242 $")
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <sys/types.h>
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <string.h>
00053 #include <strings.h>
00054 #include <errno.h>
00055 #include <unistd.h>
00056 #include <netdb.h>
00057 #include <fcntl.h>
00058 #include <sys/stat.h>
00059 #include <regex.h>
00060 
00061 #ifdef HAVE_ZAPTEL
00062 #include <sys/ioctl.h>
00063 #include <zaptel/zaptel.h>
00064 #endif
00065 
00066 #include "asterisk/lock.h"
00067 #include "asterisk/frame.h" 
00068 #include "asterisk/channel.h"
00069 #include "asterisk/logger.h"
00070 #include "asterisk/module.h"
00071 #include "asterisk/pbx.h"
00072 #include "asterisk/sched.h"
00073 #include "asterisk/io.h"
00074 #include "asterisk/config.h"
00075 #include "asterisk/options.h"
00076 #include "asterisk/cli.h"
00077 #include "asterisk/translate.h"
00078 #include "asterisk/md5.h"
00079 #include "asterisk/cdr.h"
00080 #include "asterisk/crypto.h"
00081 #include "asterisk/acl.h"
00082 #include "asterisk/manager.h"
00083 #include "asterisk/callerid.h"
00084 #include "asterisk/app.h"
00085 #include "asterisk/astdb.h"
00086 #include "asterisk/musiconhold.h"
00087 #include "asterisk/features.h"
00088 #include "asterisk/utils.h"
00089 #include "asterisk/causes.h"
00090 #include "asterisk/localtime.h"
00091 #include "asterisk/aes.h"
00092 #include "asterisk/dnsmgr.h"
00093 #include "asterisk/devicestate.h"
00094 #include "asterisk/netsock.h"
00095 #include "asterisk/stringfields.h"
00096 #include "asterisk/linkedlists.h"
00097 
00098 #include "iax2.h"
00099 #include "iax2-parser.h"
00100 #include "iax2-provision.h"
00101 #include "jitterbuf.h"
00102 
00103 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00104    multithreaded mode. */
00105 #define SCHED_MULTITHREADED
00106 
00107 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00108    thread is actually doing. */
00109 #define DEBUG_SCHED_MULTITHREAD
00110 
00111 #ifndef IPTOS_MINCOST
00112 #define IPTOS_MINCOST 0x02
00113 #endif
00114 
00115 #ifdef SO_NO_CHECK
00116 static int nochecksums = 0;
00117 #endif
00118 
00119 
00120 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00121 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00122 
00123 #define DEFAULT_THREAD_COUNT 10
00124 #define DEFAULT_MAX_THREAD_COUNT 100
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 tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00142 
00143 static char context[80] = "default";
00144 
00145 static char language[MAX_LANGUAGE] = "";
00146 static char regcontext[AST_MAX_CONTEXT] = "";
00147 
00148 static int maxauthreq = 3;
00149 static int max_retries = 4;
00150 static int ping_time = 21;
00151 static int lagrq_time = 10;
00152 static int maxtrunkcall = TRUNK_CALL_START;
00153 static int maxnontrunkcall = 1;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 
00162 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00163 
00164 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00165 
00166 static unsigned int tos = 0;
00167 
00168 static int min_reg_expire;
00169 static int max_reg_expire;
00170 
00171 static int timingfd = -1;           /* Timing file descriptor */
00172 
00173 static struct ast_netsock_list *netsock;
00174 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00175 static int defaultsockfd = -1;
00176 
00177 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00178 
00179 /* Ethernet, etc */
00180 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00181 /* T1, maybe ISDN */
00182 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00183                 ~AST_FORMAT_SLINEAR &        \
00184                 ~AST_FORMAT_ULAW &        \
00185                 ~AST_FORMAT_ALAW &        \
00186                 ~AST_FORMAT_G722) 
00187 /* A modem */
00188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00189                 ~AST_FORMAT_G726 &        \
00190                 ~AST_FORMAT_G726_AAL2 &      \
00191                 ~AST_FORMAT_ADPCM)
00192 
00193 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00194                 ~AST_FORMAT_G723_1)
00195 
00196 
00197 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00198 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00199 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00200 
00201 static   struct io_context *io;
00202 static   struct sched_context *sched;
00203 
00204 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00205 
00206 static int iaxdebug = 0;
00207 
00208 static int iaxtrunkdebug = 0;
00209 
00210 static int test_losspct = 0;
00211 #ifdef IAXTESTS
00212 static int test_late = 0;
00213 static int test_resync = 0;
00214 static int test_jit = 0;
00215 static int test_jitpct = 0;
00216 #endif /* IAXTESTS */
00217 
00218 static char accountcode[AST_MAX_ACCOUNT_CODE];
00219 static char mohinterpret[MAX_MUSICCLASS];
00220 static char mohsuggest[MAX_MUSICCLASS];
00221 static int amaflags = 0;
00222 static int adsi = 0;
00223 static int delayreject = 0;
00224 static int iax2_encryption = 0;
00225 
00226 static struct ast_flags globalflags = { 0 };
00227 
00228 static pthread_t netthreadid = AST_PTHREADT_NULL;
00229 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00230 AST_MUTEX_DEFINE_STATIC(sched_lock);
00231 static ast_cond_t sched_cond;
00232 
00233 enum {
00234    IAX_STATE_STARTED =     (1 << 0),
00235    IAX_STATE_AUTHENTICATED =  (1 << 1),
00236    IAX_STATE_TBD =      (1 << 2),
00237    IAX_STATE_UNCHANGED =      (1 << 3),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00272                        response, so that we've achieved a three-way handshake with
00273                        them before sending voice or anything else*/
00274 } iax2_flags;
00275 
00276 static int global_rtautoclear = 120;
00277 
00278 static int reload_config(void);
00279 static int iax2_reload(int fd, int argc, char *argv[]);
00280 
00281 
00282 struct iax2_user {
00283    AST_DECLARE_STRING_FIELDS(
00284       AST_STRING_FIELD(name);
00285       AST_STRING_FIELD(secret);
00286       AST_STRING_FIELD(dbsecret);
00287       AST_STRING_FIELD(accountcode);
00288       AST_STRING_FIELD(mohinterpret);
00289       AST_STRING_FIELD(mohsuggest);
00290       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00291       AST_STRING_FIELD(language);
00292       AST_STRING_FIELD(cid_num);
00293       AST_STRING_FIELD(cid_name);
00294    );
00295    
00296    int authmethods;
00297    int encmethods;
00298    int amaflags;
00299    int adsi;
00300    unsigned int flags;
00301    int capability;
00302    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00303    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00304    struct ast_codec_pref prefs;
00305    struct ast_ha *ha;
00306    struct iax2_context *contexts;
00307    struct ast_variable *vars;
00308    AST_LIST_ENTRY(iax2_user) entry;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361    AST_LIST_ENTRY(iax2_peer) entry;
00362 };
00363 
00364 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00365 
00366 static struct iax2_trunk_peer {
00367    ast_mutex_t lock;
00368    int sockfd;
00369    struct sockaddr_in addr;
00370    struct timeval txtrunktime;      /*!< Transmit trunktime */
00371    struct timeval rxtrunktime;      /*!< Receive trunktime */
00372    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00373    struct timeval trunkact;      /*!< Last trunk activity */
00374    unsigned int lastsent;        /*!< Last sent time */
00375    /* Trunk data and length */
00376    unsigned char *trunkdata;
00377    unsigned int trunkdatalen;
00378    unsigned int trunkdataalloc;
00379    struct iax2_trunk_peer *next;
00380    int trunkerror;
00381    int calls;
00382 } *tpeers = NULL;
00383 
00384 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00385 
00386 struct iax_firmware {
00387    struct iax_firmware *next;
00388    int fd;
00389    int mmaplen;
00390    int dead;
00391    struct ast_iax2_firmware_header *fwh;
00392    unsigned char *buf;
00393 };
00394 
00395 enum iax_reg_state {
00396    REG_STATE_UNREGISTERED = 0,
00397    REG_STATE_REGSENT,
00398    REG_STATE_AUTHSENT,
00399    REG_STATE_REGISTERED,
00400    REG_STATE_REJECTED,
00401    REG_STATE_TIMEOUT,
00402    REG_STATE_NOAUTH
00403 };
00404 
00405 enum iax_transfer_state {
00406    TRANSFER_NONE = 0,
00407    TRANSFER_BEGIN,
00408    TRANSFER_READY,
00409    TRANSFER_RELEASED,
00410    TRANSFER_PASSTHROUGH,
00411    TRANSFER_MBEGIN,
00412    TRANSFER_MREADY,
00413    TRANSFER_MRELEASED,
00414    TRANSFER_MPASSTHROUGH,
00415    TRANSFER_MEDIA,
00416    TRANSFER_MEDIAPASS
00417 };
00418 
00419 struct iax2_registry {
00420    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00421    char username[80];
00422    char secret[80];        /*!< Password or key name in []'s */
00423    char random[80];
00424    int expire;          /*!< Sched ID of expiration */
00425    int refresh;            /*!< How often to refresh */
00426    enum iax_reg_state regstate;
00427    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00428    int callno;          /*!< Associated call number if applicable */
00429    struct sockaddr_in us;        /*!< Who the server thinks we are */
00430    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00431    AST_LIST_ENTRY(iax2_registry) entry;
00432 };
00433 
00434 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00435 
00436 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00437 #define MIN_RETRY_TIME     100
00438 #define MAX_RETRY_TIME     10000
00439 
00440 #define MAX_JITTER_BUFFER  50
00441 #define MIN_JITTER_BUFFER  10
00442 
00443 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00444 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00445 
00446 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00447 
00448 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00449 #define TS_GAP_FOR_JB_RESYNC  5000
00450 
00451 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00452 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00453 static int iaxdynamicthreadcount = 0;
00454 static int iaxactivethreadcount = 0;
00455 
00456 struct iax_rr {
00457    int jitter;
00458    int losspct;
00459    int losscnt;
00460    int packets;
00461    int delay;
00462    int dropped;
00463    int ooo;
00464 };
00465 
00466 struct chan_iax2_pvt {
00467    /*! Socket to send/receive on for this call */
00468    int sockfd;
00469    /*! Last received voice format */
00470    int voiceformat;
00471    /*! Last received video format */
00472    int videoformat;
00473    /*! Last sent voice format */
00474    int svoiceformat;
00475    /*! Last sent video format */
00476    int svideoformat;
00477    /*! What we are capable of sending */
00478    int capability;
00479    /*! Last received timestamp */
00480    unsigned int last;
00481    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00482    unsigned int lastsent;
00483    /*! Next outgoing timestamp if everything is good */
00484    unsigned int nextpred;
00485    /*! True if the last voice we transmitted was not silence/CNG */
00486    int notsilenttx;
00487    /*! Ping time */
00488    unsigned int pingtime;
00489    /*! Max time for initial response */
00490    int maxtime;
00491    /*! Peer Address */
00492    struct sockaddr_in addr;
00493    /*! Actual used codec preferences */
00494    struct ast_codec_pref prefs;
00495    /*! Requested codec preferences */
00496    struct ast_codec_pref rprefs;
00497    /*! Our call number */
00498    unsigned short callno;
00499    /*! Peer callno */
00500    unsigned short peercallno;
00501    /*! Negotiated format, this is only used to remember what format was
00502        chosen for an unauthenticated call so that the channel can get
00503        created later using the right format */
00504    int chosenformat;
00505    /*! Peer selected format */
00506    int peerformat;
00507    /*! Peer capability */
00508    int peercapability;
00509    /*! timeval that we base our transmission on */
00510    struct timeval offset;
00511    /*! timeval that we base our delivery on */
00512    struct timeval rxcore;
00513    /*! The jitterbuffer */
00514         jitterbuf *jb;
00515    /*! active jb read scheduler id */
00516         int jbid;                       
00517    /*! LAG */
00518    int lag;
00519    /*! Error, as discovered by the manager */
00520    int error;
00521    /*! Owner if we have one */
00522    struct ast_channel *owner;
00523    /*! What's our state? */
00524    struct ast_flags state;
00525    /*! Expiry (optional) */
00526    int expiry;
00527    /*! Next outgoing sequence number */
00528    unsigned char oseqno;
00529    /*! Next sequence number they have not yet acknowledged */
00530    unsigned char rseqno;
00531    /*! Next incoming sequence number */
00532    unsigned char iseqno;
00533    /*! Last incoming sequence number we have acknowledged */
00534    unsigned char aseqno;
00535 
00536    AST_DECLARE_STRING_FIELDS(
00537       /*! Peer name */
00538       AST_STRING_FIELD(peer);
00539       /*! Default Context */
00540       AST_STRING_FIELD(context);
00541       /*! Caller ID if available */
00542       AST_STRING_FIELD(cid_num);
00543       AST_STRING_FIELD(cid_name);
00544       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00545       AST_STRING_FIELD(ani);
00546       /*! DNID */
00547       AST_STRING_FIELD(dnid);
00548       /*! RDNIS */
00549       AST_STRING_FIELD(rdnis);
00550       /*! Requested Extension */
00551       AST_STRING_FIELD(exten);
00552       /*! Expected Username */
00553       AST_STRING_FIELD(username);
00554       /*! Expected Secret */
00555       AST_STRING_FIELD(secret);
00556       /*! MD5 challenge */
00557       AST_STRING_FIELD(challenge);
00558       /*! Public keys permitted keys for incoming authentication */
00559       AST_STRING_FIELD(inkeys);
00560       /*! Private key for outgoing authentication */
00561       AST_STRING_FIELD(outkey);
00562       /*! Preferred language */
00563       AST_STRING_FIELD(language);
00564       /*! Hostname/peername for naming purposes */
00565       AST_STRING_FIELD(host);
00566 
00567       AST_STRING_FIELD(dproot);
00568       AST_STRING_FIELD(accountcode);
00569       AST_STRING_FIELD(mohinterpret);
00570       AST_STRING_FIELD(mohsuggest);
00571    );
00572    
00573    /*! permitted authentication methods */
00574    int authmethods;
00575    /*! permitted encryption methods */
00576    int encmethods;
00577    /*! Encryption AES-128 Key */
00578    aes_encrypt_ctx ecx;
00579    /*! Decryption AES-128 Key */
00580    aes_decrypt_ctx dcx;
00581    /*! 32 bytes of semi-random data */
00582    unsigned char semirand[32];
00583    /*! Associated registry */
00584    struct iax2_registry *reg;
00585    /*! Associated peer for poking */
00586    struct iax2_peer *peerpoke;
00587    /*! IAX_ flags */
00588    unsigned int flags;
00589    int adsi;
00590 
00591    /*! Transferring status */
00592    enum iax_transfer_state transferring;
00593    /*! Transfer identifier */
00594    int transferid;
00595    /*! Who we are IAX transfering to */
00596    struct sockaddr_in transfer;
00597    /*! What's the new call number for the transfer */
00598    unsigned short transfercallno;
00599    /*! Transfer decrypt AES-128 Key */
00600    aes_encrypt_ctx tdcx;
00601 
00602    /*! Status of knowledge of peer ADSI capability */
00603    int peeradsicpe;
00604 
00605    /*! Who we are bridged to */
00606    unsigned short bridgecallno;
00607    
00608    int pingid;       /*!< Transmit PING request */
00609    int lagid;        /*!< Retransmit lag request */
00610    int autoid;       /*!< Auto hangup for Dialplan requestor */
00611    int authid;       /*!< Authentication rejection ID */
00612    int authfail;        /*!< Reason to report failure */
00613    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00614    int calling_ton;
00615    int calling_tns;
00616    int calling_pres;
00617    int amaflags;
00618    struct iax2_dpcache *dpentries;
00619    struct ast_variable *vars;
00620    /*! last received remote rr */
00621    struct iax_rr remote_rr;
00622    /*! Current base time: (just for stats) */
00623    int min;
00624    /*! Dropped frame count: (just for stats) */
00625    int frames_dropped;
00626    /*! received frame count: (just for stats) */
00627    int frames_received;
00628 };
00629 
00630 static struct ast_iax2_queue {
00631    AST_LIST_HEAD(, iax_frame) queue;
00632    int count;
00633 } iaxq;
00634 
00635 static AST_LIST_HEAD_STATIC(users, iax2_user);
00636 
00637 static AST_LIST_HEAD_STATIC(peers, iax2_peer);
00638 
00639 static struct ast_firmware_list {
00640    struct iax_firmware *wares;
00641    ast_mutex_t lock;
00642 } waresl;
00643 
00644 /*! Extension exists */
00645 #define CACHE_FLAG_EXISTS     (1 << 0)
00646 /*! Extension is nonexistent */
00647 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00648 /*! Extension can exist */
00649 #define CACHE_FLAG_CANEXIST      (1 << 2)
00650 /*! Waiting to hear back response */
00651 #define CACHE_FLAG_PENDING    (1 << 3)
00652 /*! Timed out */
00653 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00654 /*! Request transmitted */
00655 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00656 /*! Timeout */
00657 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00658 /*! Matchmore */
00659 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00660 
00661 static struct iax2_dpcache {
00662    char peercontext[AST_MAX_CONTEXT];
00663    char exten[AST_MAX_EXTENSION];
00664    struct timeval orig;
00665    struct timeval expiry;
00666    int flags;
00667    unsigned short callno;
00668    int waiters[256];
00669    struct iax2_dpcache *next;
00670    struct iax2_dpcache *peer; /*!< For linking in peers */
00671 } *dpcache;
00672 
00673 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00674 
00675 static void reg_source_db(struct iax2_peer *p);
00676 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00677 
00678 static void destroy_peer(struct iax2_peer *peer);
00679 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00680 
00681 #define IAX_IOSTATE_IDLE      0
00682 #define IAX_IOSTATE_READY     1
00683 #define IAX_IOSTATE_PROCESSING   2
00684 #define IAX_IOSTATE_SCHEDREADY   3
00685 
00686 #define IAX_TYPE_POOL    1
00687 #define IAX_TYPE_DYNAMIC 2
00688 
00689 struct iax2_pkt_buf {
00690    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00691    size_t len;
00692    unsigned char buf[1];
00693 };
00694 
00695 struct iax2_thread {
00696    AST_LIST_ENTRY(iax2_thread) list;
00697    int type;
00698    int iostate;
00699 #ifdef SCHED_MULTITHREADED
00700    void (*schedfunc)(void *);
00701    void *scheddata;
00702 #endif
00703 #ifdef DEBUG_SCHED_MULTITHREAD
00704    char curfunc[80];
00705 #endif   
00706    int actions;
00707    pthread_t threadid;
00708    int threadnum;
00709    struct sockaddr_in iosin;
00710    unsigned char readbuf[4096]; 
00711    unsigned char *buf;
00712    ssize_t buf_len;
00713    size_t buf_size;
00714    int iofd;
00715    time_t checktime;
00716    ast_mutex_t lock;
00717    ast_cond_t cond;
00718    unsigned int ready_for_signal:1;
00719    /*! if this thread is processing a full frame,
00720      some information about that frame will be stored
00721      here, so we can avoid dispatching any more full
00722      frames for that callno to other threads */
00723    struct {
00724       unsigned short callno;
00725       struct sockaddr_in sin;
00726       unsigned char type;
00727       unsigned char csub;
00728    } ffinfo;
00729    /*! Queued up full frames for processing.  If more full frames arrive for
00730     *  a call which this thread is already processing a full frame for, they
00731     *  are queued up here. */
00732    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00733 };
00734 
00735 /* Thread lists */
00736 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00737 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00738 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00739 
00740 static void *iax2_process_thread(void *data);
00741 
00742 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00743 {
00744    ast_mutex_lock(lock);
00745    ast_cond_signal(cond);
00746    ast_mutex_unlock(lock);
00747 }
00748 
00749 static void iax_debug_output(const char *data)
00750 {
00751    if (iaxdebug)
00752       ast_verbose("%s", data);
00753 }
00754 
00755 static void iax_error_output(const char *data)
00756 {
00757    ast_log(LOG_WARNING, "%s", data);
00758 }
00759 
00760 static void jb_error_output(const char *fmt, ...)
00761 {
00762    va_list args;
00763    char buf[1024];
00764 
00765    va_start(args, fmt);
00766    vsnprintf(buf, 1024, fmt, args);
00767    va_end(args);
00768 
00769    ast_log(LOG_ERROR, buf);
00770 }
00771 
00772 static void jb_warning_output(const char *fmt, ...)
00773 {
00774    va_list args;
00775    char buf[1024];
00776 
00777    va_start(args, fmt);
00778    vsnprintf(buf, 1024, fmt, args);
00779    va_end(args);
00780 
00781    ast_log(LOG_WARNING, buf);
00782 }
00783 
00784 static void jb_debug_output(const char *fmt, ...)
00785 {
00786    va_list args;
00787    char buf[1024];
00788 
00789    va_start(args, fmt);
00790    vsnprintf(buf, 1024, fmt, args);
00791    va_end(args);
00792 
00793    ast_verbose(buf);
00794 }
00795 
00796 /* XXX We probably should use a mutex when working with this XXX */
00797 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00798 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
00799 static struct timeval lastused[IAX_MAX_CALLS];
00800 
00801 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);
00802 static int expire_registry(void *data);
00803 static int iax2_answer(struct ast_channel *c);
00804 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00805 static int iax2_devicestate(void *data);
00806 static int iax2_digit_begin(struct ast_channel *c, char digit);
00807 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00808 static int iax2_do_register(struct iax2_registry *reg);
00809 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00810 static int iax2_hangup(struct ast_channel *c);
00811 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00812 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00813 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00814 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00815 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00816 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00817 static int iax2_sendtext(struct ast_channel *c, const char *text);
00818 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00819 static int iax2_transfer(struct ast_channel *c, const char *dest);
00820 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00821 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00822 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00823 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00824 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00825 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00826 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00827 static struct ast_frame *iax2_read(struct ast_channel *c);
00828 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00829 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00830 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00831 static void destroy_user(struct iax2_user *user);
00832 static void prune_peers(void);
00833 
00834 static const struct ast_channel_tech iax2_tech = {
00835    .type = "IAX2",
00836    .description = tdesc,
00837    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00838    .properties = AST_CHAN_TP_WANTSJITTER,
00839    .requester = iax2_request,
00840    .devicestate = iax2_devicestate,
00841    .send_digit_begin = iax2_digit_begin,
00842    .send_digit_end = iax2_digit_end,
00843    .send_text = iax2_sendtext,
00844    .send_image = iax2_sendimage,
00845    .send_html = iax2_sendhtml,
00846    .call = iax2_call,
00847    .hangup = iax2_hangup,
00848    .answer = iax2_answer,
00849    .read = iax2_read,
00850    .write = iax2_write,
00851    .write_video = iax2_write,
00852    .indicate = iax2_indicate,
00853    .setoption = iax2_setoption,
00854    .bridge = iax2_bridge,
00855    .transfer = iax2_transfer,
00856    .fixup = iax2_fixup,
00857 };
00858 
00859 /* WARNING: insert_idle_thread should only ever be called within the
00860  * context of an iax2_process_thread() thread.
00861  */
00862 static void insert_idle_thread(struct iax2_thread *thread)
00863 {
00864    if (thread->type == IAX_TYPE_DYNAMIC) {
00865       AST_LIST_LOCK(&dynamic_list);
00866       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00867       AST_LIST_UNLOCK(&dynamic_list);
00868    } else {
00869       AST_LIST_LOCK(&idle_list);
00870       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00871       AST_LIST_UNLOCK(&idle_list);
00872    }
00873 
00874    return;
00875 }
00876 
00877 static struct iax2_thread *find_idle_thread(void)
00878 {
00879    pthread_attr_t attr;
00880    struct iax2_thread *thread = NULL;
00881 
00882    /* Pop the head of the list off */
00883    AST_LIST_LOCK(&idle_list);
00884    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00885    AST_LIST_UNLOCK(&idle_list);
00886 
00887    /* If no idle thread is available from the regular list, try dynamic */
00888    if (thread == NULL) {
00889       AST_LIST_LOCK(&dynamic_list);
00890       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00891       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00892       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00893          /* We need to MAKE a thread! */
00894          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00895             thread->threadnum = iaxdynamicthreadcount;
00896             thread->type = IAX_TYPE_DYNAMIC;
00897             ast_mutex_init(&thread->lock);
00898             ast_cond_init(&thread->cond, NULL);
00899             pthread_attr_init(&attr);
00900             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00901             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00902                free(thread);
00903                thread = NULL;
00904             } else {
00905                /* All went well and the thread is up, so increment our count */
00906                iaxdynamicthreadcount++;
00907                
00908                /* Wait for the thread to be ready before returning it to the caller */
00909                while (!thread->ready_for_signal)
00910                   usleep(1);
00911             }
00912          }
00913       }
00914       AST_LIST_UNLOCK(&dynamic_list);
00915    }
00916 
00917    /* this thread is not processing a full frame (since it is idle),
00918       so ensure that the field for the full frame call number is empty */
00919    if (thread)
00920       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00921 
00922    return thread;
00923 }
00924 
00925 #ifdef SCHED_MULTITHREADED
00926 static int __schedule_action(void (*func)(void *data), void *data, const char *funcname)
00927 {
00928    struct iax2_thread *thread = NULL;
00929    static time_t lasterror;
00930    static time_t t;
00931 
00932    thread = find_idle_thread();
00933 
00934    if (thread != NULL) {
00935       thread->schedfunc = func;
00936       thread->scheddata = data;
00937       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00938 #ifdef DEBUG_SCHED_MULTITHREAD
00939       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00940 #endif
00941       signal_condition(&thread->lock, &thread->cond);
00942       return 0;
00943    }
00944    time(&t);
00945    if (t != lasterror) 
00946       ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
00947    lasterror = t;
00948 
00949    return -1;
00950 }
00951 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00952 #endif
00953 
00954 static int send_ping(void *data);
00955 
00956 static void __send_ping(void *data)
00957 {
00958    int callno = (long)data;
00959    ast_mutex_lock(&iaxsl[callno]);
00960    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00961       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00962       iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data);
00963    }
00964    ast_mutex_unlock(&iaxsl[callno]);
00965 }
00966 
00967 static int send_ping(void *data)
00968 {
00969 #ifdef SCHED_MULTITHREADED
00970    if (schedule_action(__send_ping, data))
00971 #endif      
00972       __send_ping(data);
00973    return 0;
00974 }
00975 
00976 static int get_encrypt_methods(const char *s)
00977 {
00978    int e;
00979    if (!strcasecmp(s, "aes128"))
00980       e = IAX_ENCRYPT_AES128;
00981    else if (ast_true(s))
00982       e = IAX_ENCRYPT_AES128;
00983    else
00984       e = 0;
00985    return e;
00986 }
00987 
00988 static int send_lagrq(void *data);
00989 
00990 static void __send_lagrq(void *data)
00991 {
00992    int callno = (long)data;
00993    /* Ping only if it's real not if it's bridged */
00994    ast_mutex_lock(&iaxsl[callno]);
00995    if (iaxs[callno] && iaxs[callno]->lagid != -1) {
00996       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
00997       iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
00998    }
00999    ast_mutex_unlock(&iaxsl[callno]);
01000 }
01001 
01002 static int send_lagrq(void *data)
01003 {
01004 #ifdef SCHED_MULTITHREADED
01005    if (schedule_action(__send_lagrq, data))
01006 #endif      
01007       __send_lagrq(data);
01008    return 0;
01009 }
01010 
01011 static unsigned char compress_subclass(int subclass)
01012 {
01013    int x;
01014    int power=-1;
01015    /* If it's 128 or smaller, just return it */
01016    if (subclass < IAX_FLAG_SC_LOG)
01017       return subclass;
01018    /* Otherwise find its power */
01019    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01020       if (subclass & (1 << x)) {
01021          if (power > -1) {
01022             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01023             return 0;
01024          } else
01025             power = x;
01026       }
01027    }
01028    return power | IAX_FLAG_SC_LOG;
01029 }
01030 
01031 static int uncompress_subclass(unsigned char csub)
01032 {
01033    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01034    if (csub & IAX_FLAG_SC_LOG) {
01035       /* special case for 'compressed' -1 */
01036       if (csub == 0xff)
01037          return -1;
01038       else
01039          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01040    }
01041    else
01042       return csub;
01043 }
01044 
01045 static struct iax2_peer *find_peer(const char *name, int realtime) 
01046 {
01047    struct iax2_peer *peer = NULL;
01048 
01049    /* Grab peer from linked list */
01050    AST_LIST_LOCK(&peers);
01051    AST_LIST_TRAVERSE(&peers, peer, entry) {
01052       if (!strcasecmp(peer->name, name)) {
01053          break;
01054       }
01055    }
01056    AST_LIST_UNLOCK(&peers);
01057 
01058    /* Now go for realtime if applicable */
01059    if(!peer && realtime)
01060       peer = realtime_peer(name, NULL);
01061    return peer;
01062 }
01063 
01064 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len, int lockpeer)
01065 {
01066    struct iax2_peer *peer = NULL;
01067    int res = 0;
01068 
01069    if (lockpeer)
01070       AST_LIST_LOCK(&peers);
01071    AST_LIST_TRAVERSE(&peers, peer, entry) {
01072       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01073           (peer->addr.sin_port == sin.sin_port)) {
01074          ast_copy_string(host, peer->name, len);
01075          res = 1;
01076          break;
01077       }
01078    }
01079    if (lockpeer)
01080       AST_LIST_UNLOCK(&peers);
01081    if (!peer) {
01082       peer = realtime_peer(NULL, &sin);
01083       if (peer) {
01084          ast_copy_string(host, peer->name, len);
01085          if (ast_test_flag(peer, IAX_TEMPONLY))
01086             destroy_peer(peer);
01087          res = 1;
01088       }
01089    }
01090 
01091    return res;
01092 }
01093 
01094 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, const char *host)
01095 {
01096    struct chan_iax2_pvt *tmp;
01097    jb_conf jbconf;
01098 
01099    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01100       return NULL;
01101 
01102    if (ast_string_field_init(tmp, 32)) {
01103       free(tmp);
01104       tmp = NULL;
01105       return NULL;
01106    }
01107       
01108    tmp->prefs = prefs;
01109    tmp->callno = 0;
01110    tmp->peercallno = 0;
01111    tmp->transfercallno = 0;
01112    tmp->bridgecallno = 0;
01113    tmp->pingid = -1;
01114    tmp->lagid = -1;
01115    tmp->autoid = -1;
01116    tmp->authid = -1;
01117    tmp->initid = -1;
01118 
01119    ast_string_field_set(tmp,exten, "s");
01120    ast_string_field_set(tmp,host, host);
01121 
01122    tmp->jb = jb_new();
01123    tmp->jbid = -1;
01124    jbconf.max_jitterbuf = maxjitterbuffer;
01125    jbconf.resync_threshold = resyncthreshold;
01126    jbconf.max_contig_interp = maxjitterinterps;
01127    jb_setconf(tmp->jb,&jbconf);
01128 
01129    return tmp;
01130 }
01131 
01132 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01133 {
01134    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01135    if (new) {
01136       size_t afdatalen = new->afdatalen;
01137       memcpy(new, fr, sizeof(*new));
01138       iax_frame_wrap(new, &fr->af);
01139       new->afdatalen = afdatalen;
01140       new->data = NULL;
01141       new->datalen = 0;
01142       new->direction = DIRECTION_INGRESS;
01143       new->retrans = -1;
01144    }
01145    return new;
01146 }
01147 
01148 #define NEW_PREVENT  0
01149 #define NEW_ALLOW    1
01150 #define NEW_FORCE    2
01151 
01152 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
01153 {
01154    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01155       (cur->addr.sin_port == sin->sin_port)) {
01156       /* This is the main host */
01157       if ((cur->peercallno == callno) ||
01158          ((dcallno == cur->callno) && !cur->peercallno)) {
01159          /* That's us.  Be sure we keep track of the peer call number */
01160          return 1;
01161       }
01162    }
01163    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01164        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01165       /* We're transferring */
01166       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01167          return 1;
01168    }
01169    return 0;
01170 }
01171 
01172 static void update_max_trunk(void)
01173 {
01174    int max = TRUNK_CALL_START;
01175    int x;
01176    /* XXX Prolly don't need locks here XXX */
01177    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01178       if (iaxs[x])
01179          max = x + 1;
01180    }
01181    maxtrunkcall = max;
01182    if (option_debug && iaxdebug)
01183       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01184 }
01185 
01186 static void update_max_nontrunk(void)
01187 {
01188    int max = 1;
01189    int x;
01190    /* XXX Prolly don't need locks here XXX */
01191    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01192       if (iaxs[x])
01193          max = x + 1;
01194    }
01195    maxnontrunkcall = max;
01196    if (option_debug && iaxdebug)
01197       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01198 }
01199 
01200 static int make_trunk(unsigned short callno, int locked)
01201 {
01202    int x;
01203    int res= 0;
01204    struct timeval now;
01205    if (iaxs[callno]->oseqno) {
01206       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01207       return -1;
01208    }
01209    if (callno & TRUNK_CALL_START) {
01210       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01211       return -1;
01212    }
01213    gettimeofday(&now, NULL);
01214    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01215       ast_mutex_lock(&iaxsl[x]);
01216       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01217          iaxs[x] = iaxs[callno];
01218          iaxs[x]->callno = x;
01219          iaxs[callno] = NULL;
01220          /* Update the two timers that should have been started */
01221          if (iaxs[x]->pingid > -1)
01222             ast_sched_del(sched, iaxs[x]->pingid);
01223          if (iaxs[x]->lagid > -1)
01224             ast_sched_del(sched, iaxs[x]->lagid);
01225          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01226          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01227          if (locked)
01228             ast_mutex_unlock(&iaxsl[callno]);
01229          res = x;
01230          if (!locked)
01231             ast_mutex_unlock(&iaxsl[x]);
01232          break;
01233       }
01234       ast_mutex_unlock(&iaxsl[x]);
01235    }
01236    if (x >= IAX_MAX_CALLS - 1) {
01237       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01238       return -1;
01239    }
01240    ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01241    /* We move this call from a non-trunked to a trunked call */
01242    update_max_trunk();
01243    update_max_nontrunk();
01244    return res;
01245 }
01246 
01247 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
01248 {
01249    int res = 0;
01250    int x;
01251    struct timeval now;
01252    char host[80];
01253 
01254    if (new <= NEW_ALLOW) {
01255       /* Look for an existing connection first */
01256       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01257          ast_mutex_lock(&iaxsl[x]);
01258          if (iaxs[x]) {
01259             /* Look for an exact match */
01260             if (match(sin, callno, dcallno, iaxs[x])) {
01261                res = x;
01262             }
01263          }
01264          ast_mutex_unlock(&iaxsl[x]);
01265       }
01266       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01267          ast_mutex_lock(&iaxsl[x]);
01268          if (iaxs[x]) {
01269             /* Look for an exact match */
01270             if (match(sin, callno, dcallno, iaxs[x])) {
01271                res = x;
01272             }
01273          }
01274          ast_mutex_unlock(&iaxsl[x]);
01275       }
01276    }
01277    if ((res < 1) && (new >= NEW_ALLOW)) {
01278       /* It may seem odd that we look through the peer list for a name for
01279        * this *incoming* call.  Well, it is weird.  However, users don't
01280        * have an IP address/port number that we can match against.  So,
01281        * this is just checking for a peer that has that IP/port and
01282        * assuming that we have a user of the same name.  This isn't always
01283        * correct, but it will be changed if needed after authentication. */
01284       if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer))
01285          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01286       gettimeofday(&now, NULL);
01287       for (x=1;x<TRUNK_CALL_START;x++) {
01288          /* Find first unused call number that hasn't been used in a while */
01289          ast_mutex_lock(&iaxsl[x]);
01290          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01291          ast_mutex_unlock(&iaxsl[x]);
01292       }
01293       /* We've still got lock held if we found a spot */
01294       if (x >= TRUNK_CALL_START) {
01295          ast_log(LOG_WARNING, "No more space\n");
01296          return 0;
01297       }
01298       iaxs[x] = new_iax(sin, lockpeer, host);
01299       update_max_nontrunk();
01300       if (iaxs[x]) {
01301          if (option_debug && iaxdebug)
01302             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01303          iaxs[x]->sockfd = sockfd;
01304          iaxs[x]->addr.sin_port = sin->sin_port;
01305          iaxs[x]->addr.sin_family = sin->sin_family;
01306          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01307          iaxs[x]->peercallno = callno;
01308          iaxs[x]->callno = x;
01309          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01310          iaxs[x]->expiry = min_reg_expire;
01311          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01312          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01313          iaxs[x]->amaflags = amaflags;
01314          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01315          
01316          ast_string_field_set(iaxs[x], accountcode, accountcode);
01317          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01318          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01319       } else {
01320          ast_log(LOG_WARNING, "Out of resources\n");
01321          ast_mutex_unlock(&iaxsl[x]);
01322          return 0;
01323       }
01324       ast_mutex_unlock(&iaxsl[x]);
01325       res = x;
01326    }
01327    return res;
01328 }
01329 
01330 static void iax2_frame_free(struct iax_frame *fr)
01331 {
01332    if (fr->retrans > -1)
01333       ast_sched_del(sched, fr->retrans);
01334    iax_frame_free(fr);
01335 }
01336 
01337 /*!
01338  * \brief Queue a frame to a call's owning asterisk channel
01339  *
01340  * \note This function assumes that iaxsl[callno] is locked when called.
01341  *
01342  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01343  * was valid before calling it, it may no longer be valid after calling it.
01344  * This function may unlock and lock the mutex associated with this callno,
01345  * meaning that another thread may grab it and destroy the call.
01346  */
01347 static int iax2_queue_frame(int callno, struct ast_frame *f)
01348 {
01349    /* Assumes lock for callno is already held... */
01350    for (;;) {
01351       if (iaxs[callno] && iaxs[callno]->owner) {
01352          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01353             /* Avoid deadlock by pausing and trying again */
01354             ast_mutex_unlock(&iaxsl[callno]);
01355             usleep(1);
01356             ast_mutex_lock(&iaxsl[callno]);
01357          } else {
01358             ast_queue_frame(iaxs[callno]->owner, f);
01359             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01360             break;
01361          }
01362       } else
01363          break;
01364    }
01365    return 0;
01366 }
01367 
01368 static void destroy_firmware(struct iax_firmware *cur)
01369 {
01370    /* Close firmware */
01371    if (cur->fwh) {
01372       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01373    }
01374    close(cur->fd);
01375    free(cur);
01376 }
01377 
01378 static int try_firmware(char *s)
01379 {
01380    struct stat stbuf;
01381    struct iax_firmware *cur;
01382    int ifd;
01383    int fd;
01384    int res;
01385    
01386    struct ast_iax2_firmware_header *fwh, fwh2;
01387    struct MD5Context md5;
01388    unsigned char sum[16];
01389    unsigned char buf[1024];
01390    int len, chunk;
01391    char *s2;
01392    char *last;
01393    s2 = alloca(strlen(s) + 100);
01394    if (!s2) {
01395       ast_log(LOG_WARNING, "Alloca failed!\n");
01396       return -1;
01397    }
01398    last = strrchr(s, '/');
01399    if (last)
01400       last++;
01401    else
01402       last = s;
01403    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01404    res = stat(s, &stbuf);
01405    if (res < 0) {
01406       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01407       return -1;
01408    }
01409    /* Make sure it's not a directory */
01410    if (S_ISDIR(stbuf.st_mode))
01411       return -1;
01412    ifd = open(s, O_RDONLY);
01413    if (ifd < 0) {
01414       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01415       return -1;
01416    }
01417    fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
01418    if (fd < 0) {
01419       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01420       close(ifd);
01421       return -1;
01422    }
01423    /* Unlink our newly created file */
01424    unlink(s2);
01425    
01426    /* Now copy the firmware into it */
01427    len = stbuf.st_size;
01428    while(len) {
01429       chunk = len;
01430       if (chunk > sizeof(buf))
01431          chunk = sizeof(buf);
01432       res = read(ifd, buf, chunk);
01433       if (res != chunk) {
01434          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01435          close(ifd);
01436          close(fd);
01437          return -1;
01438       }
01439       res = write(fd, buf, chunk);
01440       if (res != chunk) {
01441          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01442          close(ifd);
01443          close(fd);
01444          return -1;
01445       }
01446       len -= chunk;
01447    }
01448    close(ifd);
01449    /* Return to the beginning */
01450    lseek(fd, 0, SEEK_SET);
01451    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01452       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01453       close(fd);
01454       return -1;
01455    }
01456    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01457       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01458       close(fd);
01459       return -1;
01460    }
01461    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01462       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01463       close(fd);
01464       return -1;
01465    }
01466    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01467       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01468       close(fd);
01469       return -1;
01470    }
01471    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01472    if (fwh == (void *) -1) {
01473       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01474       close(fd);
01475       return -1;
01476    }
01477    MD5Init(&md5);
01478    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01479    MD5Final(sum, &md5);
01480    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01481       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01482       munmap((void*)fwh, stbuf.st_size);
01483       close(fd);
01484       return -1;
01485    }
01486    cur = waresl.wares;
01487    while(cur) {
01488       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01489          /* Found a candidate */
01490          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01491             /* The version we have on loaded is older, load this one instead */
01492             break;
01493          /* This version is no newer than what we have.  Don't worry about it.
01494             We'll consider it a proper load anyhow though */
01495          munmap((void*)fwh, stbuf.st_size);
01496          close(fd);
01497          return 0;
01498       }
01499       cur = cur->next;
01500    }
01501    if (!cur) {
01502       /* Allocate a new one and link it */
01503       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01504          cur->fd = -1;
01505          cur->next = waresl.wares;
01506          waresl.wares = cur;
01507       }
01508    }
01509    if (cur) {
01510       if (cur->fwh) {
01511          munmap((void*)cur->fwh, cur->mmaplen);
01512       }
01513       if (cur->fd > -1)
01514          close(cur->fd);
01515       cur->fwh = fwh;
01516       cur->fd = fd;
01517       cur->mmaplen = stbuf.st_size;
01518       cur->dead = 0;
01519    }
01520    return 0;
01521 }
01522 
01523 static int iax_check_version(char *dev)
01524 {
01525    int res = 0;
01526    struct iax_firmware *cur;
01527    if (!ast_strlen_zero(dev)) {
01528       ast_mutex_lock(&waresl.lock);
01529       cur = waresl.wares;
01530       while(cur) {
01531          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01532             res = ntohs(cur->fwh->version);
01533             break;
01534          }
01535          cur = cur->next;
01536       }
01537       ast_mutex_unlock(&waresl.lock);
01538    }
01539    return res;
01540 }
01541 
01542 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01543 {
01544    int res = -1;
01545    unsigned int bs = desc & 0xff;
01546    unsigned int start = (desc >> 8) & 0xffffff;
01547    unsigned int bytes;
01548    struct iax_firmware *cur;
01549    if (!ast_strlen_zero((char *)dev) && bs) {
01550       start *= bs;
01551       ast_mutex_lock(&waresl.lock);
01552       cur = waresl.wares;
01553       while(cur) {
01554          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01555             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01556             if (start < ntohl(cur->fwh->datalen)) {
01557                bytes = ntohl(cur->fwh->datalen) - start;
01558                if (bytes > bs)
01559                   bytes = bs;
01560                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01561             } else {
01562                bytes = 0;
01563                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01564             }
01565             if (bytes == bs)
01566                res = 0;
01567             else
01568                res = 1;
01569             break;
01570          }
01571          cur = cur->next;
01572       }
01573       ast_mutex_unlock(&waresl.lock);
01574    }
01575    return res;
01576 }
01577 
01578 
01579 static void reload_firmware(void)
01580 {
01581    struct iax_firmware *cur, *curl, *curp;
01582    DIR *fwd;
01583    struct dirent *de;
01584    char dir[256];
01585    char fn[256];
01586    /* Mark all as dead */
01587    ast_mutex_lock(&waresl.lock);
01588    cur = waresl.wares;
01589    while(cur) {
01590       cur->dead = 1;
01591       cur = cur->next;
01592    }
01593    /* Now that we've freed them, load the new ones */
01594    snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01595    fwd = opendir(dir);
01596    if (fwd) {
01597       while((de = readdir(fwd))) {
01598          if (de->d_name[0] != '.') {
01599             snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01600             if (!try_firmware(fn)) {
01601                if (option_verbose > 1)
01602                   ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01603             }
01604          }
01605       }
01606       closedir(fwd);
01607    } else 
01608       ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01609 
01610    /* Clean up leftovers */
01611    cur = waresl.wares;
01612    curp = NULL;
01613    while(cur) {
01614       curl = cur;
01615       cur = cur->next;
01616       if (curl->dead) {
01617          if (curp) {
01618             curp->next = cur;
01619          } else {
01620             waresl.wares = cur;
01621          }
01622          destroy_firmware(curl);
01623       } else {
01624          curp = cur;
01625       }
01626    }
01627    ast_mutex_unlock(&waresl.lock);
01628 }
01629 
01630 /*!
01631  * \note This function assumes that iaxsl[callno] is locked when called.
01632  *
01633  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01634  * was valid before calling it, it may no longer be valid after calling it.
01635  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
01636  * associated with this callno, meaning that another thread may grab it and destroy the call.
01637  */
01638 static int __do_deliver(void *data)
01639 {
01640    /* Just deliver the packet by using queueing.  This is called by
01641      the IAX thread with the iaxsl lock held. */
01642    struct iax_frame *fr = data;
01643    fr->retrans = -1;
01644    fr->af.has_timing_info = 0;
01645    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01646       iax2_queue_frame(fr->callno, &fr->af);
01647    /* Free our iax frame */
01648    iax2_frame_free(fr);
01649    /* And don't run again */
01650    return 0;
01651 }
01652 
01653 static int handle_error(void)
01654 {
01655    /* XXX Ideally we should figure out why an error occured and then abort those
01656       rather than continuing to try.  Unfortunately, the published interface does
01657       not seem to work XXX */
01658 #if 0
01659    struct sockaddr_in *sin;
01660    int res;
01661    struct msghdr m;
01662    struct sock_extended_err e;
01663    m.msg_name = NULL;
01664    m.msg_namelen = 0;
01665    m.msg_iov = NULL;
01666    m.msg_control = &e;
01667    m.msg_controllen = sizeof(e);
01668    m.msg_flags = 0;
01669    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01670    if (res < 0)
01671       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01672    else {
01673       if (m.msg_controllen) {
01674          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01675          if (sin) 
01676             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
01677          else
01678             ast_log(LOG_WARNING, "No address detected??\n");
01679       } else {
01680          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01681       }
01682    }
01683 #endif
01684    return 0;
01685 }
01686 
01687 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
01688 {
01689    int res;
01690    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01691                sizeof(*sin));
01692    if (res < 0) {
01693       if (option_debug)
01694          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01695       handle_error();
01696    } else
01697       res = 0;
01698    return res;
01699 }
01700 
01701 static int send_packet(struct iax_frame *f)
01702 {
01703    int res;
01704    int callno = f->callno;
01705 
01706    /* Don't send if there was an error, but return error instead */
01707    if (!callno || !iaxs[callno] || iaxs[callno]->error)
01708        return -1;
01709    
01710    /* Called with iaxsl held */
01711    if (option_debug > 2 && iaxdebug)
01712       ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
01713    if (f->transfer) {
01714       if (iaxdebug)
01715          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01716       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
01717                sizeof(iaxs[callno]->transfer));
01718    } else {
01719       if (iaxdebug)
01720          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01721       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
01722                sizeof(iaxs[callno]->addr));
01723    }
01724    if (res < 0) {
01725       if (option_debug && iaxdebug)
01726          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01727       handle_error();
01728    } else
01729       res = 0;
01730    return res;
01731 }
01732 
01733 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01734 {
01735    struct iax2_user *user = NULL;
01736 
01737    /* Decrement AUTHREQ count if needed */
01738    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01739       AST_LIST_LOCK(&users);
01740       AST_LIST_TRAVERSE(&users, user, entry) {
01741          if (!strcmp(user->name, pvt->username)) {
01742             user->curauthreq--;
01743             break;
01744          }
01745       }
01746       AST_LIST_UNLOCK(&users);
01747       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01748    }
01749    /* No more pings or lagrq's */
01750    if (pvt->pingid > -1)
01751       ast_sched_del(sched, pvt->pingid);
01752    pvt->pingid = -1;
01753    if (pvt->lagid > -1)
01754       ast_sched_del(sched, pvt->lagid);
01755    pvt->lagid = -1;
01756    if (pvt->autoid > -1)
01757       ast_sched_del(sched, pvt->autoid);
01758    pvt->autoid = -1;
01759    if (pvt->authid > -1)
01760       ast_sched_del(sched, pvt->authid);
01761    pvt->authid = -1;
01762    if (pvt->initid > -1)
01763       ast_sched_del(sched, pvt->initid);
01764    pvt->initid = -1;
01765    if (pvt->jbid > -1)
01766       ast_sched_del(sched, pvt->jbid);
01767    pvt->jbid = -1;
01768 }
01769 
01770 static int iax2_predestroy(int callno)
01771 {
01772    struct ast_channel *c;
01773    struct chan_iax2_pvt *pvt = iaxs[callno];
01774 
01775    if (!pvt)
01776       return -1;
01777    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01778       iax2_destroy_helper(pvt);
01779       ast_set_flag(pvt, IAX_ALREADYGONE); 
01780    }
01781    c = pvt->owner;
01782    if (c) {
01783       c->_softhangup |= AST_SOFTHANGUP_DEV;
01784       c->tech_pvt = NULL;
01785       ast_queue_hangup(c);
01786       pvt->owner = NULL;
01787       ast_module_unref(ast_module_info->self);
01788    }
01789    return 0;
01790 }
01791 
01792 static void iax2_destroy(int callno)
01793 {
01794    struct chan_iax2_pvt *pvt;
01795    struct iax_frame *cur;
01796    struct ast_channel *owner;
01797 
01798 retry:
01799    pvt = iaxs[callno];
01800    gettimeofday(&lastused[callno], NULL);
01801    
01802    owner = pvt ? pvt->owner : NULL;
01803 
01804    if (owner) {
01805       if (ast_mutex_trylock(&owner->lock)) {
01806          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01807          ast_mutex_unlock(&iaxsl[callno]);
01808          usleep(1);
01809          ast_mutex_lock(&iaxsl[callno]);
01810          goto retry;
01811       }
01812    }
01813    if (!owner)
01814       iaxs[callno] = NULL;
01815    if (pvt) {
01816       if (!owner)
01817          pvt->owner = NULL;
01818       iax2_destroy_helper(pvt);
01819 
01820       /* Already gone */
01821       ast_set_flag(pvt, IAX_ALREADYGONE); 
01822 
01823       if (owner) {
01824          /* If there's an owner, prod it to give up */
01825          owner->_softhangup |= AST_SOFTHANGUP_DEV;
01826          ast_queue_hangup(owner);
01827       }
01828 
01829       AST_LIST_LOCK(&iaxq.queue);
01830       AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01831          /* Cancel any pending transmissions */
01832          if (cur->callno == pvt->callno) 
01833             cur->retries = -1;
01834       }
01835       AST_LIST_UNLOCK(&iaxq.queue);
01836 
01837       if (pvt->reg)
01838          pvt->reg->callno = 0;
01839       if (!owner) {
01840          jb_frame frame;
01841          if (pvt->vars) {
01842              ast_variables_destroy(pvt->vars);
01843              pvt->vars = NULL;
01844          }
01845 
01846          while (jb_getall(pvt->jb, &frame) == JB_OK)
01847             iax2_frame_free(frame.data);
01848          jb_destroy(pvt->jb);
01849          /* gotta free up the stringfields */
01850          ast_string_field_free_pools(pvt);
01851          free(pvt);
01852       }
01853    }
01854    if (owner) {
01855       ast_mutex_unlock(&owner->lock);
01856    }
01857    if (callno & 0x4000)
01858       update_max_trunk();
01859 }
01860 
01861 static int update_packet(struct iax_frame *f)
01862 {
01863    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
01864    struct ast_iax2_full_hdr *fh = f->data;
01865    /* Mark this as a retransmission */
01866    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
01867    /* Update iseqno */
01868    f->iseqno = iaxs[f->callno]->iseqno;
01869    fh->iseqno = f->iseqno;
01870    return 0;
01871 }
01872 
01873 static int attempt_transmit(void *data);
01874 static void __attempt_transmit(void *data)
01875 {
01876    /* Attempt to transmit the frame to the remote peer...
01877       Called without iaxsl held. */
01878    struct iax_frame *f = data;
01879    int freeme=0;
01880    int callno = f->callno;
01881    /* Make sure this call is still active */
01882    if (callno) 
01883       ast_mutex_lock(&iaxsl[callno]);
01884    if (callno && iaxs[callno]) {
01885       if ((f->retries < 0) /* Already ACK'd */ ||
01886           (f->retries >= max_retries) /* Too many attempts */) {
01887             /* Record an error if we've transmitted too many times */
01888             if (f->retries >= max_retries) {
01889                if (f->transfer) {
01890                   /* Transfer timeout */
01891                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
01892                } else if (f->final) {
01893                   if (f->final) 
01894                      iax2_destroy(callno);
01895                } else {
01896                   if (iaxs[callno]->owner)
01897                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
01898                   iaxs[callno]->error = ETIMEDOUT;
01899                   if (iaxs[callno]->owner) {
01900                      struct ast_frame fr = { 0, };
01901                      /* Hangup the fd */
01902                      fr.frametype = AST_FRAME_CONTROL;
01903                      fr.subclass = AST_CONTROL_HANGUP;
01904                      iax2_queue_frame(callno, &fr); // XXX
01905                      /* Remember, owner could disappear */
01906                      if (iaxs[callno] && iaxs[callno]->owner)
01907                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01908                   } else {
01909                      if (iaxs[callno]->reg) {
01910                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
01911                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
01912                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
01913                      }
01914                      iax2_destroy(callno);
01915                   }
01916                }
01917 
01918             }
01919             freeme++;
01920       } else {
01921          /* Update it if it needs it */
01922          update_packet(f);
01923          /* Attempt transmission */
01924          send_packet(f);
01925          f->retries++;
01926          /* Try again later after 10 times as long */
01927          f->retrytime *= 10;
01928          if (f->retrytime > MAX_RETRY_TIME)
01929             f->retrytime = MAX_RETRY_TIME;
01930          /* Transfer messages max out at one second */
01931          if (f->transfer && (f->retrytime > 1000))
01932             f->retrytime = 1000;
01933          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
01934       }
01935    } else {
01936       /* Make sure it gets freed */
01937       f->retries = -1;
01938       freeme++;
01939    }
01940    if (callno)
01941       ast_mutex_unlock(&iaxsl[callno]);
01942    /* Do not try again */
01943    if (freeme) {
01944       /* Don't attempt delivery, just remove it from the queue */
01945       AST_LIST_LOCK(&iaxq.queue);
01946       AST_LIST_REMOVE(&iaxq.queue, f, list);
01947       iaxq.count--;
01948       AST_LIST_UNLOCK(&iaxq.queue);
01949       f->retrans = -1;
01950       /* Free the IAX frame */
01951       iax2_frame_free(f);
01952    }
01953 }
01954 
01955 static int attempt_transmit(void *data)
01956 {
01957 #ifdef SCHED_MULTITHREADED
01958    if (schedule_action(__attempt_transmit, data))
01959 #endif      
01960       __attempt_transmit(data);
01961    return 0;
01962 }
01963 
01964 static int iax2_prune_realtime(int fd, int argc, char *argv[])
01965 {
01966    struct iax2_peer *peer;
01967 
01968    if (argc != 4)
01969         return RESULT_SHOWUSAGE;
01970    if (!strcmp(argv[3],"all")) {
01971       reload_config();
01972       ast_cli(fd, "OK cache is flushed.\n");
01973    } else if ((peer = find_peer(argv[3], 0))) {
01974       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
01975          ast_set_flag(peer, IAX_RTAUTOCLEAR);
01976          expire_registry((void *)peer->name);
01977          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
01978       } else {
01979          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
01980       }
01981    } else {
01982       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
01983    }
01984    
01985    return RESULT_SUCCESS;
01986 }
01987 
01988 static int iax2_test_losspct(int fd, int argc, char *argv[])
01989 {
01990        if (argc != 4)
01991                return RESULT_SHOWUSAGE;
01992 
01993        test_losspct = atoi(argv[3]);
01994 
01995        return RESULT_SUCCESS;
01996 }
01997 
01998 #ifdef IAXTESTS
01999 static int iax2_test_late(int fd, int argc, char *argv[])
02000 {
02001    if (argc != 4)
02002       return RESULT_SHOWUSAGE;
02003 
02004    test_late = atoi(argv[3]);
02005 
02006    return RESULT_SUCCESS;
02007 }
02008 
02009 static int iax2_test_resync(int fd, int argc, char *argv[])
02010 {
02011    if (argc != 4)
02012       return RESULT_SHOWUSAGE;
02013 
02014    test_resync = atoi(argv[3]);
02015 
02016    return RESULT_SUCCESS;
02017 }
02018 
02019 static int iax2_test_jitter(int fd, int argc, char *argv[])
02020 {
02021    if (argc < 4 || argc > 5)
02022       return RESULT_SHOWUSAGE;
02023 
02024    test_jit = atoi(argv[3]);
02025    if (argc == 5) 
02026       test_jitpct = atoi(argv[4]);
02027 
02028    return RESULT_SUCCESS;
02029 }
02030 #endif /* IAXTESTS */
02031 
02032 /*! \brief  peer_status: Report Peer status in character string */
02033 /*    returns 1 if peer is online, -1 if unmonitored */
02034 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02035 {
02036    int res = 0;
02037    if (peer->maxms) {
02038       if (peer->lastms < 0) {
02039          ast_copy_string(status, "UNREACHABLE", statuslen);
02040       } else if (peer->lastms > peer->maxms) {
02041          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02042          res = 1;
02043       } else if (peer->lastms) {
02044          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02045          res = 1;
02046       } else {
02047          ast_copy_string(status, "UNKNOWN", statuslen);
02048       }
02049    } else { 
02050       ast_copy_string(status, "Unmonitored", statuslen);
02051       res = -1;
02052    }
02053    return res;
02054 }
02055 
02056 /*! \brief Show one peer in detail */
02057 static int iax2_show_peer(int fd, int argc, char *argv[])
02058 {
02059    char status[30];
02060    char cbuf[256];
02061    struct iax2_peer *peer;
02062    char codec_buf[512];
02063    int x = 0, codec = 0, load_realtime = 0;
02064 
02065    if (argc < 4)
02066       return RESULT_SHOWUSAGE;
02067 
02068    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02069 
02070    peer = find_peer(argv[3], load_realtime);
02071    if (peer) {
02072       ast_cli(fd,"\n\n");
02073       ast_cli(fd, "  * Name       : %s\n", peer->name);
02074       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02075       ast_cli(fd, "  Context      : %s\n", peer->context);
02076       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02077       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02078       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02079       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02080       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02081       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
02082       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02083       ast_cli(fd, "  Username     : %s\n", peer->username);
02084       ast_cli(fd, "  Codecs       : ");
02085       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02086       ast_cli(fd, "%s\n", codec_buf);
02087 
02088       ast_cli(fd, "  Codec Order  : (");
02089       for(x = 0; x < 32 ; x++) {
02090          codec = ast_codec_pref_index(&peer->prefs,x);
02091          if(!codec)
02092             break;
02093          ast_cli(fd, "%s", ast_getformatname(codec));
02094          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02095             ast_cli(fd, "|");
02096       }
02097 
02098       if (!x)
02099          ast_cli(fd, "none");
02100       ast_cli(fd, ")\n");
02101 
02102       ast_cli(fd, "  Status       : ");
02103       peer_status(peer, status, sizeof(status));   
02104       ast_cli(fd, "%s\n",status);
02105       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02106       ast_cli(fd,"\n");
02107       if (ast_test_flag(peer, IAX_TEMPONLY))
02108          destroy_peer(peer);
02109    } else {
02110       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02111       ast_cli(fd,"\n");
02112    }
02113 
02114    return RESULT_SUCCESS;
02115 }
02116 
02117 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02118 {
02119    int which = 0;
02120    struct iax2_peer *p = NULL;
02121    char *res = NULL;
02122    int wordlen = strlen(word);
02123 
02124    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02125    if (pos == 3) {
02126       AST_LIST_LOCK(&peers);
02127       AST_LIST_TRAVERSE(&peers, p, entry) {
02128          if (!strncasecmp(p->name, word, wordlen) && ++which > state) {
02129             res = ast_strdup(p->name);
02130             break;
02131          }
02132       }
02133       AST_LIST_UNLOCK(&peers);
02134    }
02135 
02136    return res;
02137 }
02138 
02139 static int iax2_show_stats(int fd, int argc, char *argv[])
02140 {
02141    struct iax_frame *cur;
02142    int cnt = 0, dead=0, final=0;
02143 
02144    if (argc != 3)
02145       return RESULT_SHOWUSAGE;
02146 
02147    AST_LIST_LOCK(&iaxq.queue);
02148    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02149       if (cur->retries < 0)
02150          dead++;
02151       if (cur->final)
02152          final++;
02153       cnt++;
02154    }
02155    AST_LIST_UNLOCK(&iaxq.queue);
02156 
02157    ast_cli(fd, "    IAX Statistics\n");
02158    ast_cli(fd, "---------------------\n");
02159    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02160    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02161    
02162    return RESULT_SUCCESS;
02163 }
02164 
02165 static int iax2_show_cache(int fd, int argc, char *argv[])
02166 {
02167    struct iax2_dpcache *dp;
02168    char tmp[1024], *pc;
02169    int s;
02170    int x,y;
02171    struct timeval tv;
02172    gettimeofday(&tv, NULL);
02173    ast_mutex_lock(&dpcache_lock);
02174    dp = dpcache;
02175    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02176    while(dp) {
02177       s = dp->expiry.tv_sec - tv.tv_sec;
02178       tmp[0] = '\0';
02179       if (dp->flags & CACHE_FLAG_EXISTS)
02180          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02181       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02182          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02183       if (dp->flags & CACHE_FLAG_CANEXIST)
02184          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02185       if (dp->flags & CACHE_FLAG_PENDING)
02186          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02187       if (dp->flags & CACHE_FLAG_TIMEOUT)
02188          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02189       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02190          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02191       if (dp->flags & CACHE_FLAG_MATCHMORE)
02192          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02193       if (dp->flags & CACHE_FLAG_UNKNOWN)
02194          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02195       /* Trim trailing pipe */
02196       if (!ast_strlen_zero(tmp))
02197          tmp[strlen(tmp) - 1] = '\0';
02198       else
02199          ast_copy_string(tmp, "(none)", sizeof(tmp));
02200       y=0;
02201       pc = strchr(dp->peercontext, '@');
02202       if (!pc)
02203          pc = dp->peercontext;
02204       else
02205          pc++;
02206       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02207          if (dp->waiters[x] > -1)
02208             y++;
02209       if (s > 0)
02210          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02211       else
02212          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02213       dp = dp->next;
02214    }
02215    ast_mutex_unlock(&dpcache_lock);
02216    return RESULT_SUCCESS;
02217 }
02218 
02219 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02220 
02221 static void unwrap_timestamp(struct iax_frame *fr)
02222 {
02223    int x;
02224 
02225    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02226       x = fr->ts - iaxs[fr->callno]->last;
02227       if (x < -50000) {
02228          /* Sudden big jump backwards in timestamp:
02229             What likely happened here is that miniframe timestamp has circled but we haven't
02230             gotten the update from the main packet.  We'll just pretend that we did, and
02231             update the timestamp appropriately. */
02232          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02233          if (option_debug && iaxdebug)
02234             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02235       }
02236       if (x > 50000) {
02237          /* Sudden apparent big jump forwards in timestamp:
02238             What's likely happened is this is an old miniframe belonging to the previous
02239             top-16-bit timestamp that has turned up out of order.
02240             Adjust the timestamp appropriately. */
02241          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02242          if (option_debug && iaxdebug)
02243             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02244       }
02245    }
02246 }
02247 
02248 static int get_from_jb(void *p);
02249 
02250 static void update_jbsched(struct chan_iax2_pvt *pvt)
02251 {
02252    int when;
02253    
02254    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02255    
02256    when = jb_next(pvt->jb) - when;
02257    
02258    if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02259    
02260    if(when <= 0) {
02261       /* XXX should really just empty until when > 0.. */
02262       when = 1;
02263    }
02264    
02265    pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02266    
02267    /* Signal scheduler thread */
02268    signal_condition(&sched_lock, &sched_cond);
02269 }
02270 
02271 static void __get_from_jb(void *p) 
02272 {
02273    int callno = PTR_TO_CALLNO(p);
02274    struct chan_iax2_pvt *pvt = NULL;
02275    struct iax_frame *fr;
02276    jb_frame frame;
02277    int ret;
02278    long now;
02279    long next;
02280    struct timeval tv;
02281    
02282    /* Make sure we have a valid private structure before going on */
02283    ast_mutex_lock(&iaxsl[callno]);
02284    pvt = iaxs[callno];
02285    if (!pvt) {
02286       /* No go! */
02287       ast_mutex_unlock(&iaxsl[callno]);
02288       return;
02289    }
02290 
02291    pvt->jbid = -1;
02292    
02293    gettimeofday(&tv,NULL);
02294    /* round up a millisecond since ast_sched_runq does; */
02295    /* prevents us from spinning while waiting for our now */
02296    /* to catch up with runq's now */
02297    tv.tv_usec += 1000;
02298    
02299    now = ast_tvdiff_ms(tv, pvt->rxcore);
02300    
02301    if(now >= (next = jb_next(pvt->jb))) {
02302       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02303       switch(ret) {
02304       case JB_OK:
02305          fr = frame.data;
02306          __do_deliver(fr);
02307          /* __do_deliver() can cause the call to disappear */
02308          pvt = iaxs[callno];
02309          break;
02310       case JB_INTERP:
02311       {
02312          struct ast_frame af = { 0, };
02313          
02314          /* create an interpolation frame */
02315          af.frametype = AST_FRAME_VOICE;
02316          af.subclass = pvt->voiceformat;
02317          af.samples  = frame.ms * 8;
02318          af.src  = "IAX2 JB interpolation";
02319          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02320          af.offset = AST_FRIENDLY_OFFSET;
02321          
02322          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02323           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02324          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02325             iax2_queue_frame(callno, &af);
02326             /* iax2_queue_frame() could cause the call to disappear */
02327             pvt = iaxs[callno];
02328          }
02329       }
02330          break;
02331       case JB_DROP:
02332          iax2_frame_free(frame.data);
02333          break;
02334       case JB_NOFRAME:
02335       case JB_EMPTY:
02336          /* do nothing */
02337          break;
02338       default:
02339          /* shouldn't happen */
02340          break;
02341       }
02342    }
02343    if (pvt)
02344       update_jbsched(pvt);
02345    ast_mutex_unlock(&iaxsl[callno]);
02346 }
02347 
02348 static int get_from_jb(void *data)
02349 {
02350 #ifdef SCHED_MULTITHREADED
02351    if (schedule_action(__get_from_jb, data))
02352 #endif      
02353       __get_from_jb(data);
02354    return 0;
02355 }
02356 
02357 /*!
02358  * \note This function assumes fr->callno is locked
02359  *
02360  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02361  * was valid before calling it, it may no longer be valid after calling it.
02362  */
02363 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02364 {
02365    int type, len;
02366    int ret;
02367    int needfree = 0;
02368 
02369    /* Attempt to recover wrapped timestamps */
02370    unwrap_timestamp(fr);
02371 
02372    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02373    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02374       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02375    else {
02376 #if 0
02377       ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02378 #endif
02379       fr->af.delivery = ast_tv(0,0);
02380    }
02381 
02382    type = JB_TYPE_CONTROL;
02383    len = 0;
02384 
02385    if(fr->af.frametype == AST_FRAME_VOICE) {
02386       type = JB_TYPE_VOICE;
02387       len = ast_codec_get_samples(&fr->af) / 8;
02388    } else if(fr->af.frametype == AST_FRAME_CNG) {
02389       type = JB_TYPE_SILENCE;
02390    }
02391 
02392    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02393       if (tsout)
02394          *tsout = fr->ts;
02395       __do_deliver(fr);
02396       return -1;
02397    }
02398 
02399    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02400     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02401    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
02402        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
02403        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
02404       jb_frame frame;
02405 
02406       /* deliver any frames in the jb */
02407       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02408          __do_deliver(frame.data);
02409          /* __do_deliver() can make the call disappear */
02410          if (!iaxs[fr->callno])
02411             return -1;
02412       }
02413 
02414       jb_reset(iaxs[fr->callno]->jb);
02415 
02416       if (iaxs[fr->callno]->jbid > -1)
02417          ast_sched_del(sched, iaxs[fr->callno]->jbid);
02418 
02419       iaxs[fr->callno]->jbid = -1;
02420 
02421       /* deliver this frame now */
02422       if (tsout)
02423          *tsout = fr->ts;
02424       __do_deliver(fr);
02425       return -1;
02426    }
02427 
02428    /* insert into jitterbuffer */
02429    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02430    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02431          calc_rxstamp(iaxs[fr->callno],fr->ts));
02432    if (ret == JB_DROP) {
02433       needfree++;
02434    } else if (ret == JB_SCHED) {
02435       update_jbsched(iaxs[fr->callno]);
02436    }
02437    if (tsout)
02438       *tsout = fr->ts;
02439    if (needfree) {
02440       /* Free our iax frame */
02441       iax2_frame_free(fr);
02442       return -1;
02443    }
02444    return 0;
02445 }
02446 
02447 static int iax2_transmit(struct iax_frame *fr)
02448 {
02449    /* Lock the queue and place this packet at the end */
02450    /* By setting this to 0, the network thread will send it for us, and
02451       queue retransmission if necessary */
02452    fr->sentyet = 0;
02453    AST_LIST_LOCK(&iaxq.queue);
02454    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02455    iaxq.count++;
02456    AST_LIST_UNLOCK(&iaxq.queue);
02457    /* Wake up the network and scheduler thread */
02458    if (netthreadid != AST_PTHREADT_NULL)
02459       pthread_kill(netthreadid, SIGURG);
02460    signal_condition(&sched_lock, &sched_cond);
02461    return 0;
02462 }
02463 
02464 
02465 
02466 static int iax2_digit_begin(struct ast_channel *c, char digit)
02467 {
02468    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02469 }
02470 
02471 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02472 {
02473    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02474 }
02475 
02476 static int iax2_sendtext(struct ast_channel *c, const char *text)
02477 {
02478    
02479    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02480       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02481 }
02482 
02483 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02484 {
02485    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02486 }
02487 
02488 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02489 {
02490    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02491 }
02492 
02493 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02494 {
02495    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02496    ast_mutex_lock(&iaxsl[callno]);
02497    if (iaxs[callno])
02498       iaxs[callno]->owner = newchan;
02499    else
02500       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02501    ast_mutex_unlock(&iaxsl[callno]);
02502    return 0;
02503 }
02504 
02505 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02506 {
02507    struct ast_variable *var;
02508    struct ast_variable *tmp;
02509    struct iax2_peer *peer=NULL;
02510    time_t regseconds = 0, nowtime;
02511    int dynamic=0;
02512 
02513    if (peername)
02514       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02515    else {
02516       char porta[25];
02517       sprintf(porta, "%d", ntohs(sin->sin_port));
02518       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02519       if (var) {
02520          /* We'll need the peer name in order to build the structure! */
02521          for (tmp = var; tmp; tmp = tmp->next) {
02522             if (!strcasecmp(tmp->name, "name"))
02523                peername = tmp->value;
02524          }
02525       }
02526    }
02527    if (!var)
02528       return NULL;
02529 
02530    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02531    
02532    if (!peer) {
02533       ast_variables_destroy(var);
02534       return NULL;
02535    }
02536 
02537    for (tmp = var; tmp; tmp = tmp->next) {
02538       /* Make sure it's not a user only... */
02539       if (!strcasecmp(tmp->name, "type")) {
02540          if (strcasecmp(tmp->value, "friend") &&
02541              strcasecmp(tmp->value, "peer")) {
02542             /* Whoops, we weren't supposed to exist! */
02543             destroy_peer(peer);
02544             peer = NULL;
02545             break;
02546          } 
02547       } else if (!strcasecmp(tmp->name, "regseconds")) {
02548          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02549       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02550          inet_aton(tmp->value, &(peer->addr.sin_addr));
02551       } else if (!strcasecmp(tmp->name, "port")) {
02552          peer->addr.sin_port = htons(atoi(tmp->value));
02553       } else if (!strcasecmp(tmp->name, "host")) {
02554          if (!strcasecmp(tmp->value, "dynamic"))
02555             dynamic = 1;
02556       }
02557    }
02558 
02559    ast_variables_destroy(var);
02560 
02561    if (!peer)
02562       return NULL;
02563 
02564    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02565       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02566       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02567          if (peer->expire > -1)
02568             ast_sched_del(sched, peer->expire);
02569          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
02570       }
02571       AST_LIST_LOCK(&peers);
02572       AST_LIST_INSERT_HEAD(&peers, peer, entry);
02573       AST_LIST_UNLOCK(&peers);
02574       if (ast_test_flag(peer, IAX_DYNAMIC))
02575          reg_source_db(peer);
02576    } else {
02577       ast_set_flag(peer, IAX_TEMPONLY);   
02578    }
02579 
02580    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02581       time(&nowtime);
02582       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02583          memset(&peer->addr, 0, sizeof(peer->addr));
02584          realtime_update_peer(peer->name, &peer->addr, 0);
02585          if (option_debug)
02586             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02587                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02588       }
02589       else {
02590          if (option_debug)
02591             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02592                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02593       }
02594    }
02595 
02596    return peer;
02597 }
02598 
02599 static struct iax2_user *realtime_user(const char *username)
02600 {
02601    struct ast_variable *var;
02602    struct ast_variable *tmp;
02603    struct iax2_user *user=NULL;
02604 
02605    var = ast_load_realtime("iaxusers", "name", username, NULL);
02606    if (!var)
02607       return NULL;
02608 
02609    tmp = var;
02610    while(tmp) {
02611       /* Make sure it's not a peer only... */
02612       if (!strcasecmp(tmp->name, "type")) {
02613          if (strcasecmp(tmp->value, "friend") &&
02614              strcasecmp(tmp->value, "user")) {
02615             return NULL;
02616          } 
02617       }
02618       tmp = tmp->next;
02619    }
02620 
02621    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02622 
02623    ast_variables_destroy(var);
02624 
02625    if (!user)
02626       return NULL;
02627 
02628    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02629       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02630       AST_LIST_LOCK(&users);
02631       AST_LIST_INSERT_HEAD(&users, user, entry);
02632       AST_LIST_UNLOCK(&users);
02633    } else {
02634       ast_set_flag(user, IAX_TEMPONLY);   
02635    }
02636 
02637    return user;
02638 }
02639 
02640 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02641 {
02642    char port[10];
02643    char regseconds[20];
02644    
02645    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02646    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02647    ast_update_realtime("iaxpeers", "name", peername, 
02648       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02649       "regseconds", regseconds, NULL);
02650 }
02651 
02652 struct create_addr_info {
02653    int capability;
02654    unsigned int flags;
02655    int maxtime;
02656    int encmethods;
02657    int found;
02658    int sockfd;
02659    int adsi;
02660    char username[80];
02661    char secret[80];
02662    char outkey[80];
02663    char timezone[80];
02664    char prefs[32];
02665    char context[AST_MAX_CONTEXT];
02666    char peercontext[AST_MAX_CONTEXT];
02667    char mohinterpret[MAX_MUSICCLASS];
02668    char mohsuggest[MAX_MUSICCLASS];
02669 };
02670 
02671 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02672 {
02673    struct ast_hostent ahp;
02674    struct hostent *hp;
02675    struct iax2_peer *peer;
02676 
02677    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02678    cai->sockfd = defaultsockfd;
02679    cai->maxtime = 0;
02680    sin->sin_family = AF_INET;
02681 
02682    if (!(peer = find_peer(peername, 1))) {
02683       cai->found = 0;
02684 
02685       hp = ast_gethostbyname(peername, &ahp);
02686       if (hp) {
02687          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02688          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02689          /* use global iax prefs for unknown peer/user */
02690          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02691          return 0;
02692       } else {
02693          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02694          return -1;
02695       }
02696    }
02697 
02698    cai->found = 1;
02699    
02700    /* if the peer has no address (current or default), return failure */
02701    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02702       if (ast_test_flag(peer, IAX_TEMPONLY))
02703          destroy_peer(peer);
02704       return -1;
02705    }
02706 
02707    /* if the peer is being monitored and is currently unreachable, return failure */
02708    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02709       if (ast_test_flag(peer, IAX_TEMPONLY))
02710          destroy_peer(peer);
02711       return -1;
02712    }
02713 
02714    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02715    cai->maxtime = peer->maxms;
02716    cai->capability = peer->capability;
02717    cai->encmethods = peer->encmethods;
02718    cai->sockfd = peer->sockfd;
02719    cai->adsi = peer->adsi;
02720    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02721    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02722    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02723    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02724    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02725    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02726    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02727    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02728    if (ast_strlen_zero(peer->dbsecret)) {
02729       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02730    } else {
02731       char *family;
02732       char *key = NULL;
02733 
02734       family = ast_strdupa(peer->dbsecret);
02735       key = strchr(family, '/');
02736       if (key)
02737          *key++ = '\0';
02738       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02739          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02740          if (ast_test_flag(peer, IAX_TEMPONLY))
02741             destroy_peer(peer);
02742          return -1;
02743       }
02744    }
02745 
02746    if (peer->addr.sin_addr.s_addr) {
02747       sin->sin_addr = peer->addr.sin_addr;
02748       sin->sin_port = peer->addr.sin_port;
02749    } else {
02750       sin->sin_addr = peer->defaddr.sin_addr;
02751       sin->sin_port = peer->defaddr.sin_port;
02752    }
02753 
02754    if (ast_test_flag(peer, IAX_TEMPONLY))
02755       destroy_peer(peer);
02756 
02757    return 0;
02758 }
02759 
02760 static void __auto_congest(void *nothing)
02761 {
02762    int callno = PTR_TO_CALLNO(nothing);
02763    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02764    ast_mutex_lock(&iaxsl[callno]);
02765    if (iaxs[callno]) {
02766       iaxs[callno]->initid = -1;
02767       iax2_queue_frame(callno, &f);
02768       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02769    }
02770    ast_mutex_unlock(&iaxsl[callno]);
02771 }
02772 
02773 static int auto_congest(void *data)
02774 {
02775 #ifdef SCHED_MULTITHREADED
02776    if (schedule_action(__auto_congest, data))
02777 #endif      
02778       __auto_congest(data);
02779    return 0;
02780 }
02781 
02782 static unsigned int iax2_datetime(const char *tz)
02783 {
02784    time_t t;
02785    struct tm tm;
02786    unsigned int tmp;
02787    time(&t);
02788    if (!ast_strlen_zero(tz))
02789       ast_localtime(&t, &tm, tz);
02790    else
02791       ast_localtime(&t, &tm, NULL);
02792    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02793    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02794    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02795    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02796    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02797    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02798    return tmp;
02799 }
02800 
02801 struct parsed_dial_string {
02802    char *username;
02803    char *password;
02804    char *key;
02805    char *peer;
02806    char *port;
02807    char *exten;
02808    char *context;
02809    char *options;
02810 };
02811 
02812 /*!
02813  * \brief Parses an IAX dial string into its component parts.
02814  * \param data the string to be parsed
02815  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
02816  * \return nothing
02817  *
02818  * This function parses the string and fills the structure
02819  * with pointers to its component parts. The input string
02820  * will be modified.
02821  *
02822  * \note This function supports both plaintext passwords and RSA
02823  * key names; if the password string is formatted as '[keyname]',
02824  * then the keyname will be placed into the key field, and the
02825  * password field will be set to NULL.
02826  *
02827  * \note The dial string format is:
02828  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
02829  */
02830 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
02831 {
02832    if (ast_strlen_zero(data))
02833       return;
02834 
02835    pds->peer = strsep(&data, "/");
02836    pds->exten = strsep(&data, "/");
02837    pds->options = data;
02838 
02839    if (pds->exten) {
02840       data = pds->exten;
02841       pds->exten = strsep(&data, "@");
02842       pds->context = data;
02843    }
02844 
02845    if (strchr(pds->peer, '@')) {
02846       data = pds->peer;
02847       pds->username = strsep(&data, "@");
02848       pds->peer = data;
02849    }
02850 
02851    if (pds->username) {
02852       data = pds->username;
02853       pds->username = strsep(&data, ":");
02854       pds->password = data;
02855    }
02856 
02857    data = pds->peer;
02858    pds->peer = strsep(&data, ":");
02859    pds->port = data;
02860 
02861    /* check for a key name wrapped in [] in the secret position, if found,
02862       move it to the key field instead
02863    */
02864    if (pds->password && (pds->password[0] == '[')) {
02865       pds->key = ast_strip_quoted(pds->password, "[", "]");
02866       pds->password = NULL;
02867    }
02868 }
02869 
02870 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
02871 {
02872    struct sockaddr_in sin;
02873    char *l=NULL, *n=NULL, *tmpstr;
02874    struct iax_ie_data ied;
02875    char *defaultrdest = "s";
02876    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02877    struct parsed_dial_string pds;
02878    struct create_addr_info cai;
02879 
02880    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
02881       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
02882       return -1;
02883    }
02884 
02885    memset(&cai, 0, sizeof(cai));
02886    cai.encmethods = iax2_encryption;
02887 
02888    memset(&pds, 0, sizeof(pds));
02889    tmpstr = ast_strdupa(dest);
02890    parse_dial_string(tmpstr, &pds);
02891 
02892    if (!pds.exten)
02893       pds.exten = defaultrdest;
02894 
02895    if (create_addr(pds.peer, &sin, &cai)) {
02896       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
02897       return -1;
02898    }
02899 
02900    if (!pds.username && !ast_strlen_zero(cai.username))
02901       pds.username = cai.username;
02902    if (!pds.password && !ast_strlen_zero(cai.secret))
02903       pds.password = cai.secret;
02904    if (!pds.key && !ast_strlen_zero(cai.outkey))
02905       pds.key = cai.outkey;
02906    if (!pds.context && !ast_strlen_zero(cai.peercontext))
02907       pds.context = cai.peercontext;
02908 
02909    /* Keep track of the context for outgoing calls too */
02910    ast_copy_string(c->context, cai.context, sizeof(c->context));
02911 
02912    if (pds.port)
02913       sin.sin_port = htons(atoi(pds.port));
02914 
02915    l = c->cid.cid_num;
02916    n = c->cid.cid_name;
02917 
02918    /* Now build request */ 
02919    memset(&ied, 0, sizeof(ied));
02920 
02921    /* On new call, first IE MUST be IAX version of caller */
02922    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
02923    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
02924    if (pds.options && strchr(pds.options, 'a')) {
02925       /* Request auto answer */
02926       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
02927    }
02928 
02929    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
02930 
02931    if (l) {
02932       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
02933       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02934    } else {
02935       if (n)
02936          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02937       else
02938          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
02939    }
02940 
02941    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
02942    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
02943 
02944    if (n)
02945       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
02946    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
02947       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
02948 
02949    if (!ast_strlen_zero(c->language))
02950       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
02951    if (!ast_strlen_zero(c->cid.cid_dnid))
02952       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
02953    if (!ast_strlen_zero(c->cid.cid_rdnis))
02954       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
02955 
02956    if (pds.context)
02957       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
02958 
02959    if (pds.username)
02960       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
02961 
02962    if (cai.encmethods)
02963       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
02964 
02965    ast_mutex_lock(&iaxsl[callno]);
02966 
02967    if (!ast_strlen_zero(c->context))
02968       ast_string_field_set(iaxs[callno], context, c->context);
02969 
02970    if (pds.username)
02971       ast_string_field_set(iaxs[callno], username, pds.username);
02972 
02973    iaxs[callno]->encmethods = cai.encmethods;
02974 
02975    iaxs[callno]->adsi = cai.adsi;
02976    
02977    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
02978    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
02979 
02980    if (pds.key)
02981       ast_string_field_set(iaxs[callno], outkey, pds.key);
02982    if (pds.password)
02983       ast_string_field_set(iaxs[callno], secret, pds.password);
02984 
02985    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
02986    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
02987    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
02988    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
02989 
02990    if (iaxs[callno]->maxtime) {
02991       /* Initialize pingtime and auto-congest time */
02992       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
02993       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
02994    } else if (autokill) {
02995       iaxs[callno]->pingtime = autokill / 2;
02996       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
02997    }
02998 
02999    /* send the command using the appropriate socket for this peer */
03000    iaxs[callno]->sockfd = cai.sockfd;
03001 
03002    /* Transmit the string in a "NEW" request */
03003    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03004 
03005    ast_mutex_unlock(&iaxsl[callno]);
03006    ast_setstate(c, AST_STATE_RINGING);
03007    
03008    return 0;
03009 }
03010 
03011 static int iax2_hangup(struct ast_channel *c) 
03012 {
03013    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03014    int alreadygone;
03015    struct iax_ie_data ied;
03016    memset(&ied, 0, sizeof(ied));
03017    ast_mutex_lock(&iaxsl[callno]);
03018    if (callno && iaxs[callno]) {
03019       ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03020       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03021       /* Send the hangup unless we have had a transmission error or are already gone */
03022       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03023       if (!iaxs[callno]->error && !alreadygone) 
03024          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03025       /* Explicitly predestroy it */
03026       iax2_predestroy(callno);
03027       /* If we were already gone to begin with, destroy us now */
03028       if (alreadygone) {
03029          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03030          iax2_destroy(callno);
03031       }
03032    }
03033    ast_mutex_unlock(&iaxsl[callno]);
03034    if (option_verbose > 2) 
03035       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03036    return 0;
03037 }
03038 
03039 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03040 {
03041    struct ast_option_header *h;
03042    int res;
03043 
03044    switch (option) {
03045    case AST_OPTION_TXGAIN:
03046    case AST_OPTION_RXGAIN:
03047       /* these two cannot be sent, because they require a result */
03048       errno = ENOSYS;
03049       return -1;
03050    default:
03051       if (!(h = ast_malloc(datalen + sizeof(*h))))
03052          return -1;
03053 
03054       h->flag = AST_OPTION_FLAG_REQUEST;
03055       h->option = htons(option);
03056       memcpy(h->data, data, datalen);
03057       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03058                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03059                  datalen + sizeof(*h), -1);
03060       free(h);
03061       return res;
03062    }
03063 }
03064 
03065 static struct ast_frame *iax2_read(struct ast_channel *c) 
03066 {
03067    ast_log(LOG_NOTICE, "I should never be called!\n");
03068    return &ast_null_frame;
03069 }
03070 
03071 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03072 {
03073    int res;
03074    struct iax_ie_data ied0;
03075    struct iax_ie_data ied1;
03076    unsigned int transferid = (unsigned int)ast_random();
03077    memset(&ied0, 0, sizeof(ied0));
03078    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03079    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03080    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03081 
03082    memset(&ied1, 0, sizeof(ied1));
03083    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03084    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03085    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03086    
03087    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03088    if (res)
03089       return -1;
03090    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03091    if (res)
03092       return -1;
03093    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03094    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03095    return 0;
03096 }
03097 
03098 static void lock_both(unsigned short callno0, unsigned short callno1)
03099 {
03100    ast_mutex_lock(&iaxsl[callno0]);
03101    while (ast_mutex_trylock(&iaxsl[callno1])) {
03102       ast_mutex_unlock(&iaxsl[callno0]);
03103       usleep(10);
03104       ast_mutex_lock(&iaxsl[callno0]);
03105    }
03106 }
03107 
03108 static void unlock_both(unsigned short callno0, unsigned short callno1)
03109 {
03110    ast_mutex_unlock(&iaxsl[callno1]);
03111    ast_mutex_unlock(&iaxsl[callno0]);
03112 }
03113 
03114 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)
03115 {
03116    struct ast_channel *cs[3];
03117    struct ast_channel *who, *other;
03118    int to = -1;
03119    int res = -1;
03120    int transferstarted=0;
03121    struct ast_frame *f;
03122    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03123    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03124    struct timeval waittimer = {0, 0}, tv;
03125 
03126    lock_both(callno0, callno1);
03127    if (!iaxs[callno0] || !iaxs[callno1]) {
03128       unlock_both(callno0, callno1);
03129       return AST_BRIDGE_FAILED;
03130    }
03131    /* Put them in native bridge mode */
03132    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03133       iaxs[callno0]->bridgecallno = callno1;
03134       iaxs[callno1]->bridgecallno = callno0;
03135    }
03136    unlock_both(callno0, callno1);
03137 
03138    /* If not, try to bridge until we can execute a transfer, if we can */
03139    cs[0] = c0;
03140    cs[1] = c1;
03141    for (/* ever */;;) {
03142       /* Check in case we got masqueraded into */
03143       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03144          if (option_verbose > 2)
03145             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03146          /* Remove from native mode */
03147          if (c0->tech == &iax2_tech) {
03148             ast_mutex_lock(&iaxsl[callno0]);
03149             iaxs[callno0]->bridgecallno = 0;
03150             ast_mutex_unlock(&iaxsl[callno0]);
03151          }
03152          if (c1->tech == &iax2_tech) {
03153             ast_mutex_lock(&iaxsl[callno1]);
03154             iaxs[callno1]->bridgecallno = 0;
03155             ast_mutex_unlock(&iaxsl[callno1]);
03156          }
03157          return AST_BRIDGE_FAILED_NOWARN;
03158       }
03159       if (c0->nativeformats != c1->nativeformats) {
03160          if (option_verbose > 2) {
03161             char buf0[255];
03162             char buf1[255];
03163             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03164             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03165             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03166          }
03167          /* Remove from native mode */
03168          lock_both(callno0, callno1);
03169          if (iaxs[callno0])
03170             iaxs[callno0]->bridgecallno = 0;
03171          if (iaxs[callno1])
03172             iaxs[callno1]->bridgecallno = 0;
03173          unlock_both(callno0, callno1);
03174          return AST_BRIDGE_FAILED_NOWARN;
03175       }
03176       /* check if transfered and if we really want native bridging */
03177       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03178          /* Try the transfer */
03179          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03180                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03181             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03182          transferstarted = 1;
03183       }
03184       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03185          /* Call has been transferred.  We're no longer involved */
03186          gettimeofday(&tv, NULL);
03187          if (ast_tvzero(waittimer)) {
03188             waittimer = tv;
03189          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03190             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03191             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03192             *fo = NULL;
03193             *rc = c0;
03194             res = AST_BRIDGE_COMPLETE;
03195             break;
03196          }
03197       }
03198       to = 1000;
03199       who = ast_waitfor_n(cs, 2, &to);
03200       if (timeoutms > -1) {
03201          timeoutms -= (1000 - to);
03202          if (timeoutms < 0)
03203             timeoutms = 0;
03204       }
03205       if (!who) {
03206          if (!timeoutms) {
03207             res = AST_BRIDGE_RETRY;
03208             break;
03209          }
03210          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03211             res = AST_BRIDGE_FAILED;
03212             break;
03213          }
03214          continue;
03215       }
03216       f = ast_read(who);
03217       if (!f) {
03218          *fo = NULL;
03219          *rc = who;
03220          res = AST_BRIDGE_COMPLETE;
03221          break;
03222       }
03223       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03224          *fo = f;
03225          *rc = who;
03226          res =  AST_BRIDGE_COMPLETE;
03227          break;
03228       }
03229       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03230       if ((f->frametype == AST_FRAME_VOICE) ||
03231           (f->frametype == AST_FRAME_TEXT) ||
03232           (f->frametype == AST_FRAME_VIDEO) || 
03233           (f->frametype == AST_FRAME_IMAGE) ||
03234           (f->frametype == AST_FRAME_DTMF)) {
03235          /* monitored dtmf take out of the bridge.
03236           * check if we monitor the specific source.
03237           */
03238          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03239          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03240             *rc = who;
03241             *fo = f;
03242             res = AST_BRIDGE_COMPLETE;
03243             /* Remove from native mode */
03244             break;
03245          }
03246          /* everything else goes to the other side */
03247          ast_write(other, f);
03248       }
03249       ast_frfree(f);
03250       /* Swap who gets priority */
03251       cs[2] = cs[0];
03252       cs[0] = cs[1];
03253       cs[1] = cs[2];
03254    }
03255    lock_both(callno0, callno1);
03256    if(iaxs[callno0])
03257       iaxs[callno0]->bridgecallno = 0;
03258    if(iaxs[callno1])
03259       iaxs[callno1]->bridgecallno = 0;
03260    unlock_both(callno0, callno1);
03261    return res;
03262 }
03263 
03264 static int iax2_answer(struct ast_channel *c)
03265 {
03266    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03267    if (option_debug)
03268       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03269    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03270 }
03271 
03272 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03273 {
03274    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03275    struct chan_iax2_pvt *pvt;
03276    int res = 0;
03277 
03278    if (option_debug && iaxdebug)
03279       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03280 
03281    ast_mutex_lock(&iaxsl[callno]);
03282    pvt = iaxs[callno];
03283 
03284    switch (condition) {
03285    case AST_CONTROL_HOLD:
03286       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03287          ast_moh_start(c, data, pvt->mohinterpret);
03288          goto done;
03289       }
03290       break;
03291    case AST_CONTROL_UNHOLD:
03292       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03293          ast_moh_stop(c);
03294          goto done;
03295       }
03296    }
03297 
03298    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03299 
03300 done:
03301    ast_mutex_unlock(&iaxsl[callno]);
03302 
03303    return res;
03304 }
03305    
03306 static int iax2_transfer(struct ast_channel *c, const char *dest)
03307 {
03308    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03309    struct iax_ie_data ied;
03310    char tmp[256], *context;
03311    ast_copy_string(tmp, dest, sizeof(tmp));
03312    context = strchr(tmp, '@');
03313    if (context) {
03314       *context = '\0';
03315       context++;
03316    }
03317    memset(&ied, 0, sizeof(ied));
03318    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03319    if (context)
03320       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03321    if (option_debug)
03322       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03323    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03324 }
03325    
03326 static int iax2_getpeertrunk(struct sockaddr_in sin)
03327 {
03328    struct iax2_peer *peer = NULL;
03329    int res = 0;
03330 
03331    AST_LIST_LOCK(&peers);
03332    AST_LIST_TRAVERSE(&peers, peer, entry) {
03333       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03334           (peer->addr.sin_port == sin.sin_port)) {
03335          res = ast_test_flag(peer, IAX_TRUNK);
03336          break;
03337       }
03338    }
03339    AST_LIST_UNLOCK(&peers);
03340 
03341    return res;
03342 }
03343 
03344 /*! \brief  Create new call, interface with the PBX core */
03345 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03346 {
03347    struct ast_channel *tmp;
03348    struct chan_iax2_pvt *i;
03349    struct ast_variable *v = NULL;
03350 
03351    if (!(i = iaxs[callno])) {
03352       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03353       return NULL;
03354    }
03355 
03356    /* Don't hold call lock */
03357    ast_mutex_unlock(&iaxsl[callno]);
03358    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
03359    ast_mutex_lock(&iaxsl[callno]);
03360    if (!tmp)
03361       return NULL;
03362    tmp->tech = &iax2_tech;
03363    /* We can support any format by default, until we get restricted */
03364    tmp->nativeformats = capability;
03365    tmp->readformat = ast_best_codec(capability);
03366    tmp->writeformat = ast_best_codec(capability);
03367    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03368 
03369    /* Don't use ast_set_callerid() here because it will
03370     * generate a NewCallerID event before the NewChannel event */
03371    tmp->cid.cid_num = ast_strdup(i->cid_num);
03372    tmp->cid.cid_name = ast_strdup(i->cid_name);
03373    if (!ast_strlen_zero(i->ani))
03374       tmp->cid.cid_ani = ast_strdup(i->ani);
03375    else
03376       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03377    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03378    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03379    tmp->cid.cid_pres = i->calling_pres;
03380    tmp->cid.cid_ton = i->calling_ton;
03381    tmp->cid.cid_tns = i->calling_tns;
03382    if (!ast_strlen_zero(i->language))
03383       ast_string_field_set(tmp, language, i->language);
03384    if (!ast_strlen_zero(i->accountcode))
03385       ast_string_field_set(tmp, accountcode, i->accountcode);
03386    if (i->amaflags)
03387       tmp->amaflags = i->amaflags;
03388    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03389    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03390    if (i->adsi)
03391       tmp->adsicpe = i->peeradsicpe;
03392    else
03393       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03394    i->owner = tmp;
03395    i->capability = capability;
03396 
03397    for (v = i->vars ; v ; v = v->next)
03398       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03399 
03400    if (state != AST_STATE_DOWN) {
03401       if (ast_pbx_start(tmp)) {
03402          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03403          ast_hangup(tmp);
03404          i->owner = NULL;
03405          return NULL;
03406       }
03407    }
03408 
03409    ast_module_ref(ast_module_info->self);
03410    
03411    return tmp;
03412 }
03413 
03414 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03415 {
03416    unsigned long int mssincetx; /* unsigned to handle overflows */
03417    long int ms, pred;
03418 
03419    tpeer->trunkact = *tv;
03420    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03421    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03422       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03423       tpeer->txtrunktime = *tv;
03424       tpeer->lastsent = 999999;
03425    }
03426    /* Update last transmit time now */
03427    tpeer->lasttxtime = *tv;
03428    
03429    /* Calculate ms offset */
03430    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03431    /* Predict from last value */
03432    pred = tpeer->lastsent + sampms;
03433    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03434       ms = pred;
03435    
03436    /* We never send the same timestamp twice, so fudge a little if we must */
03437    if (ms == tpeer->lastsent)
03438       ms = tpeer->lastsent + 1;
03439    tpeer->lastsent = ms;
03440    return ms;
03441 }
03442 
03443 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03444 {
03445    long ms; /* NOT unsigned */
03446    if (ast_tvzero(iaxs[callno]->rxcore)) {
03447       /* Initialize rxcore time if appropriate */
03448       gettimeofday(&iaxs[callno]->rxcore, NULL);
03449       /* Round to nearest 20ms so traces look pretty */
03450       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03451    }
03452    /* Calculate difference between trunk and channel */
03453    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03454    /* Return as the sum of trunk time and the difference between trunk and real time */
03455    return ms + ts;
03456 }
03457 
03458 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03459 {
03460    int ms;
03461    int voice = 0;
03462    int genuine = 0;
03463    int adjust;
03464    struct timeval *delivery = NULL;
03465 
03466 
03467    /* What sort of frame do we have?: voice is self-explanatory
03468       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03469       non-genuine frames are CONTROL frames [ringing etc], DTMF
03470       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03471       the others need a timestamp slaved to the voice frames so that they go in sequence
03472    */
03473    if (f) {
03474       if (f->frametype == AST_FRAME_VOICE) {
03475          voice = 1;
03476          delivery = &f->delivery;
03477       } else if (f->frametype == AST_FRAME_IAX) {
03478          genuine = 1;
03479       } else if (f->frametype == AST_FRAME_CNG) {
03480          p->notsilenttx = 0;  
03481       }
03482    }
03483    if (ast_tvzero(p->offset)) {
03484       gettimeofday(&p->offset, NULL);
03485       /* Round to nearest 20ms for nice looking traces */
03486       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03487    }
03488    /* If the timestamp is specified, just send it as is */
03489    if (ts)
03490       return ts;
03491    /* If we have a time that the frame arrived, always use it to make our timestamp */
03492    if (delivery && !ast_tvzero(*delivery)) {
03493       ms = ast_tvdiff_ms(*delivery, p->offset);
03494       if (option_debug > 2 && iaxdebug)
03495          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03496    } else {
03497       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03498       if (ms < 0)
03499          ms = 0;
03500       if (voice) {
03501          /* On a voice frame, use predicted values if appropriate */
03502          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03503             /* Adjust our txcore, keeping voice and non-voice synchronized */
03504             /* AN EXPLANATION:
03505                When we send voice, we usually send "calculated" timestamps worked out
03506                on the basis of the number of samples sent. When we send other frames,
03507                we usually send timestamps worked out from the real clock.
03508                The problem is that they can tend to drift out of step because the 
03509                   source channel's clock and our clock may not be exactly at the same rate.
03510                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03511                for this call.  Moving it adjusts timestamps for non-voice frames.
03512                We make the adjustment in the style of a moving average.  Each time we
03513                adjust p->offset by 10% of the difference between our clock-derived
03514                timestamp and the predicted timestamp.  That's why you see "10000"
03515                below even though IAX2 timestamps are in milliseconds.
03516                The use of a moving average avoids offset moving too radically.
03517                Generally, "adjust" roams back and forth around 0, with offset hardly
03518                changing at all.  But if a consistent different starts to develop it
03519                will be eliminated over the course of 10 frames (200-300msecs) 
03520             */
03521             adjust = (ms - p->nextpred);
03522             if (adjust < 0)
03523                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03524             else if (adjust > 0)
03525                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03526 
03527             if (!p->nextpred) {
03528                p->nextpred = ms; /*f->samples / 8;*/
03529                if (p->nextpred <= p->lastsent)
03530                   p->nextpred = p->lastsent + 3;
03531             }
03532             ms = p->nextpred;
03533          } else {
03534                 /* in this case, just use the actual
03535             * time, since we're either way off
03536             * (shouldn't happen), or we're  ending a
03537             * silent period -- and seed the next
03538             * predicted time.  Also, round ms to the
03539             * next multiple of frame size (so our
03540             * silent periods are multiples of
03541             * frame size too) */
03542 
03543             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03544                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03545                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03546 
03547             if (f->samples >= 8) /* check to make sure we dont core dump */
03548             {
03549                int diff = ms % (f->samples / 8);
03550                if (diff)
03551                    ms += f->samples/8 - diff;
03552             }
03553 
03554             p->nextpred = ms;
03555             p->notsilenttx = 1;
03556          }
03557       } else {
03558          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03559             it's a genuine frame */
03560          if (genuine) {
03561             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03562             if (ms <= p->lastsent)
03563                ms = p->lastsent + 3;
03564          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03565             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03566             ms = p->lastsent + 3;
03567          }
03568       }
03569    }
03570    p->lastsent = ms;
03571    if (voice)
03572       p->nextpred = p->nextpred + f->samples / 8;
03573    return ms;
03574 }
03575 
03576 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03577 {
03578    /* Returns where in "receive time" we are.  That is, how many ms
03579       since we received (or would have received) the frame with timestamp 0 */
03580    int ms;
03581 #ifdef IAXTESTS
03582    int jit;
03583 #endif /* IAXTESTS */
03584    /* Setup rxcore if necessary */
03585    if (ast_tvzero(p->rxcore)) {
03586       p->rxcore = ast_tvnow();
03587       if (option_debug && iaxdebug)
03588          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03589                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03590       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03591 #if 1
03592       if (option_debug && iaxdebug)
03593          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03594                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03595 #endif
03596    }
03597 
03598    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03599 #ifdef IAXTESTS
03600    if (test_jit) {
03601       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03602          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03603          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03604             jit = -jit;
03605          ms += jit;
03606       }
03607    }
03608    if (test_late) {
03609       ms += test_late;
03610       test_late = 0;
03611    }
03612 #endif /* IAXTESTS */
03613    return ms;
03614 }
03615 
03616 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03617 {
03618    struct iax2_trunk_peer *tpeer;
03619    
03620    /* Finds and locks trunk peer */
03621    ast_mutex_lock(&tpeerlock);
03622    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03623       /* We don't lock here because tpeer->addr *never* changes */
03624       if (!inaddrcmp(&tpeer->addr, sin)) {
03625          ast_mutex_lock(&tpeer->lock);
03626          break;
03627       }
03628    }
03629    if (!tpeer) {
03630       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03631          ast_mutex_init(&tpeer->lock);
03632          tpeer->lastsent = 9999;
03633          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03634          tpeer->trunkact = ast_tvnow();
03635          ast_mutex_lock(&tpeer->lock);
03636          tpeer->next = tpeers;
03637          tpeer->sockfd = fd;
03638          tpeers = tpeer;
03639 #ifdef SO_NO_CHECK
03640          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03641 #endif
03642          ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03643       }
03644    }
03645    ast_mutex_unlock(&tpeerlock);
03646    return tpeer;
03647 }
03648 
03649 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03650 {
03651    struct ast_frame *f;
03652    struct iax2_trunk_peer *tpeer;
03653    void *tmp, *ptr;
03654    struct ast_iax2_meta_trunk_entry *met;
03655    struct ast_iax2_meta_trunk_mini *mtm;
03656 
03657    f = &fr->af;
03658    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03659    if (tpeer) {
03660       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03661          /* Need to reallocate space */
03662          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03663             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03664                ast_mutex_unlock(&tpeer->lock);
03665                return -1;
03666             }
03667             
03668             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03669             tpeer->trunkdata = tmp;
03670             ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
03671          } else {
03672             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03673             ast_mutex_unlock(&tpeer->lock);
03674             return -1;
03675          }
03676       }
03677 
03678       /* Append to meta frame */
03679       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03680       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03681          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03682          mtm->len = htons(f->datalen);
03683          mtm->mini.callno = htons(pvt->callno);
03684          mtm->mini.ts = htons(0xffff & fr->ts);
03685          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03686          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03687       } else {
03688          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03689          /* Store call number and length in meta header */
03690          met->callno = htons(pvt->callno);
03691          met->len = htons(f->datalen);
03692          /* Advance pointers/decrease length past trunk entry header */
03693          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03694          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03695       }
03696       /* Copy actual trunk data */
03697       memcpy(ptr, f->data, f->datalen);
03698       tpeer->trunkdatalen += f->datalen;
03699 
03700       tpeer->calls++;
03701       ast_mutex_unlock(&tpeer->lock);
03702    }
03703    return 0;
03704 }
03705 
03706 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03707 {
03708    aes_encrypt_key128(digest, ecx);
03709    aes_decrypt_key128(digest, dcx);
03710 }
03711 
03712 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03713 {
03714 #if 0
03715    /* Debug with "fake encryption" */
03716    int x;
03717    if (len % 16)
03718       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03719    for (x=0;x<len;x++)
03720       dst[x] = src[x] ^ 0xff;
03721 #else 
03722    unsigned char lastblock[16] = { 0 };
03723    int x;
03724    while(len > 0) {
03725       aes_decrypt(src, dst, dcx);
03726       for (x=0;x<16;x++)
03727          dst[x] ^= lastblock[x];
03728       memcpy(lastblock, src, sizeof(lastblock));
03729       dst += 16;
03730       src += 16;
03731       len -= 16;
03732    }
03733 #endif
03734 }
03735 
03736 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03737 {
03738 #if 0
03739    /* Debug with "fake encryption" */
03740    int x;
03741    if (len % 16)
03742       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03743    for (x=0;x<len;x++)
03744       dst[x] = src[x] ^ 0xff;
03745 #else
03746    unsigned char curblock[16] = { 0 };
03747    int x;
03748    while(len > 0) {
03749       for (x=0;x<16;x++)
03750          curblock[x] ^= src[x];
03751       aes_encrypt(curblock, dst, ecx);
03752       memcpy(curblock, dst, sizeof(curblock)); 
03753       dst += 16;
03754       src += 16;
03755       len -= 16;
03756    }
03757 #endif
03758 }
03759 
03760 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03761 {
03762    int padding;
03763    unsigned char *workspace;
03764 
03765    workspace = alloca(*datalen);
03766    memset(f, 0, sizeof(*f));
03767    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03768       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03769       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03770          return -1;
03771       /* Decrypt */
03772       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03773 
03774       padding = 16 + (workspace[15] & 0xf);
03775       if (option_debug && iaxdebug)
03776          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03777       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03778          return -1;
03779 
03780       *datalen -= padding;
03781       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03782       f->frametype = fh->type;
03783       if (f->frametype == AST_FRAME_VIDEO) {
03784          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03785       } else {
03786          f->subclass = uncompress_subclass(fh->csub);
03787       }
03788    } else {
03789       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03790       if (option_debug && iaxdebug)
03791          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03792       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03793          return -1;
03794       /* Decrypt */
03795       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03796       padding = 16 + (workspace[15] & 0x0f);
03797       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03798          return -1;
03799       *datalen -= padding;
03800       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03801    }
03802    return 0;
03803 }
03804 
03805 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
03806 {
03807    int padding;
03808    unsigned char *workspace;
03809    workspace = alloca(*datalen + 32);
03810    if (!workspace)
03811       return -1;
03812    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03813       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03814       if (option_debug && iaxdebug)
03815          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03816       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03817       padding = 16 + (padding & 0xf);
03818       memcpy(workspace, poo, padding);
03819       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03820       workspace[15] &= 0xf0;
03821       workspace[15] |= (padding & 0xf);
03822       if (option_debug && iaxdebug)
03823          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]);
03824       *datalen += padding;
03825       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03826       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03827          memcpy(poo, workspace + *datalen - 32, 32);
03828    } else {
03829       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03830       if (option_debug && iaxdebug)
03831          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03832       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03833       padding = 16 + (padding & 0xf);
03834       memcpy(workspace, poo, padding);
03835       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03836       workspace[15] &= 0xf0;
03837       workspace[15] |= (padding & 0x0f);
03838       *datalen += padding;
03839       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03840       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03841          memcpy(poo, workspace + *datalen - 32, 32);
03842    }
03843    return 0;
03844 }
03845 
03846 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03847 {
03848    int res=-1;
03849    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03850       /* Search for possible keys, given secrets */
03851       struct MD5Context md5;
03852       unsigned char digest[16];
03853       char *tmppw, *stringp;
03854       
03855       tmppw = ast_strdupa(iaxs[callno]->secret);
03856       stringp = tmppw;
03857       while ((tmppw = strsep(&stringp, ";"))) {
03858          MD5Init(&md5);
03859          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03860          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03861          MD5Final(digest, &md5);
03862          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03863          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03864          if (!res) {
03865             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03866             break;
03867          }
03868       }
03869    } else 
03870       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03871    return res;
03872 }
03873 
03874 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
03875 {
03876    /* Queue a packet for delivery on a given private structure.  Use "ts" for
03877       timestamp, or calculate if ts is 0.  Send immediately without retransmission
03878       or delayed, with retransmission */
03879    struct ast_iax2_full_hdr *fh;
03880    struct ast_iax2_mini_hdr *mh;
03881    struct ast_iax2_video_hdr *vh;
03882    struct {
03883       struct iax_frame fr2;
03884       unsigned char buffer[4096];
03885    } frb;
03886    struct iax_frame *fr;
03887    int res;
03888    int sendmini=0;
03889    unsigned int lastsent;
03890    unsigned int fts;
03891 
03892    frb.fr2.afdatalen = sizeof(frb.buffer);
03893 
03894    if (!pvt) {
03895       ast_log(LOG_WARNING, "No private structure for packet?\n");
03896       return -1;
03897    }
03898    
03899    lastsent = pvt->lastsent;
03900 
03901    /* Calculate actual timestamp */
03902    fts = calc_timestamp(pvt, ts, f);
03903 
03904    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
03905     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
03906     * increment the "predicted timestamps" for voice, if we're predecting */
03907    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
03908        return 0;
03909 
03910 
03911    if ((ast_test_flag(pvt, IAX_TRUNK) || 
03912          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
03913          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
03914       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
03915        (f->frametype == AST_FRAME_VOICE) 
03916       /* is a voice frame */ &&
03917       (f->subclass == pvt->svoiceformat) 
03918       /* is the same type */ ) {
03919          /* Force immediate rather than delayed transmission */
03920          now = 1;
03921          /* Mark that mini-style frame is appropriate */
03922          sendmini = 1;
03923    }
03924    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
03925       (f->frametype == AST_FRAME_VIDEO) &&
03926       ((f->subclass & ~0x1) == pvt->svideoformat)) {
03927          now = 1;
03928          sendmini = 1;
03929    }
03930    /* Allocate an iax_frame */
03931    if (now) {
03932       fr = &frb.fr2;
03933    } else
03934       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
03935    if (!fr) {
03936       ast_log(LOG_WARNING, "Out of memory\n");
03937       return -1;
03938    }
03939    /* Copy our prospective frame into our immediate or retransmitted wrapper */
03940    iax_frame_wrap(fr, f);
03941 
03942    fr->ts = fts;
03943    fr->callno = pvt->callno;
03944    fr->transfer = transfer;
03945    fr->final = final;
03946    if (!sendmini) {
03947       /* We need a full frame */
03948       if (seqno > -1)
03949          fr->oseqno = seqno;
03950       else
03951          fr->oseqno = pvt->oseqno++;
03952       fr->iseqno = pvt->iseqno;
03953       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
03954       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
03955       fh->ts = htonl(fr->ts);
03956       fh->oseqno = fr->oseqno;
03957       if (transfer) {
03958          fh->iseqno = 0;
03959       } else
03960          fh->iseqno = fr->iseqno;
03961       /* Keep track of the last thing we've acknowledged */
03962       if (!transfer)
03963          pvt->aseqno = fr->iseqno;
03964       fh->type = fr->af.frametype & 0xFF;
03965       if (fr->af.frametype == AST_FRAME_VIDEO)
03966          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
03967       else
03968          fh->csub = compress_subclass(fr->af.subclass);
03969       if (transfer) {
03970          fr->dcallno = pvt->transfercallno;
03971       } else
03972          fr->dcallno = pvt->peercallno;
03973       fh->dcallno = htons(fr->dcallno);
03974       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
03975       fr->data = fh;
03976       fr->retries = 0;
03977       /* Retry after 2x the ping time has passed */
03978       fr->retrytime = pvt->pingtime * 2;
03979       if (fr->retrytime < MIN_RETRY_TIME)
03980          fr->retrytime = MIN_RETRY_TIME;
03981       if (fr->retrytime > MAX_RETRY_TIME)
03982          fr->retrytime = MAX_RETRY_TIME;
03983       /* Acks' don't get retried */
03984       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
03985          fr->retries = -1;
03986       else if (f->frametype == AST_FRAME_VOICE)
03987          pvt->svoiceformat = f->subclass;
03988       else if (f->frametype == AST_FRAME_VIDEO)
03989          pvt->svideoformat = f->subclass & ~0x1;
03990       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
03991          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
03992             if (iaxdebug) {
03993                if (fr->transfer)
03994                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03995                else
03996                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03997             }
03998             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
03999          } else
04000             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04001       }
04002    
04003       if (now) {
04004          res = send_packet(fr);
04005       } else
04006          res = iax2_transmit(fr);
04007    } else {
04008       if (ast_test_flag(pvt, IAX_TRUNK)) {
04009          iax2_trunk_queue(pvt, fr);
04010          res = 0;
04011       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04012          /* Video frame have no sequence number */
04013          fr->oseqno = -1;
04014          fr->iseqno = -1;
04015          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04016          vh->zeros = 0;
04017          vh->callno = htons(0x8000 | fr->callno);
04018          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04019          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04020          fr->data = vh;
04021          fr->retries = -1;
04022          res = send_packet(fr);        
04023       } else {
04024          /* Mini-frames have no sequence number */
04025          fr->oseqno = -1;
04026          fr->iseqno = -1;
04027          /* Mini frame will do */
04028          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04029          mh->callno = htons(fr->callno);
04030          mh->ts = htons(fr->ts & 0xFFFF);
04031          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04032          fr->data = mh;
04033          fr->retries = -1;
04034          if (pvt->transferring == TRANSFER_MEDIAPASS)
04035             fr->transfer = 1;
04036          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04037             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04038                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04039             } else
04040                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04041          }
04042          res = send_packet(fr);
04043       }
04044    }
04045    return res;
04046 }
04047 
04048 static int iax2_show_users(int fd, int argc, char *argv[])
04049 {
04050    regex_t regexbuf;
04051    int havepattern = 0;
04052 
04053 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04054 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04055 
04056    struct iax2_user *user = NULL;
04057    char auth[90];
04058    char *pstr = "";
04059 
04060    switch (argc) {
04061    case 5:
04062       if (!strcasecmp(argv[3], "like")) {
04063          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04064             return RESULT_SHOWUSAGE;
04065          havepattern = 1;
04066       } else
04067          return RESULT_SHOWUSAGE;
04068    case 3:
04069       break;
04070    default:
04071       return RESULT_SHOWUSAGE;
04072    }
04073 
04074    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04075    AST_LIST_LOCK(&users);
04076    AST_LIST_TRAVERSE(&users, user, entry) {
04077       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04078          continue;
04079       
04080       if (!ast_strlen_zero(user->secret)) {
04081          ast_copy_string(auth,user->secret,sizeof(auth));
04082       } else if (!ast_strlen_zero(user->inkeys)) {
04083          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04084       } else
04085          ast_copy_string(auth, "-no secret-", sizeof(auth));
04086       
04087       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04088          pstr = "REQ Only";
04089       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04090          pstr = "Disabled";
04091       else
04092          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04093       
04094       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04095          user->contexts ? user->contexts->context : context,
04096          user->ha ? "Yes" : "No", pstr);
04097       
04098    }
04099    AST_LIST_UNLOCK(&users);
04100 
04101    if (havepattern)
04102       regfree(&regexbuf);
04103 
04104    return RESULT_SUCCESS;
04105 #undef FORMAT
04106 #undef FORMAT2
04107 }
04108 
04109 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04110 {
04111    regex_t regexbuf;
04112    int havepattern = 0;
04113    int total_peers = 0;
04114    int online_peers = 0;
04115    int offline_peers = 0;
04116    int unmonitored_peers = 0;
04117 
04118 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04119 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04120 
04121    struct iax2_peer *peer = NULL;
04122    char name[256];
04123    int registeredonly=0;
04124    char *term = manager ? "\r\n" : "\n";
04125 
04126    switch (argc) {
04127    case 6:
04128       if (!strcasecmp(argv[3], "registered"))
04129          registeredonly = 1;
04130       else
04131          return RESULT_SHOWUSAGE;
04132       if (!strcasecmp(argv[4], "like")) {
04133          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04134             return RESULT_SHOWUSAGE;
04135          havepattern = 1;
04136       } else
04137          return RESULT_SHOWUSAGE;
04138       break;
04139    case 5:
04140       if (!strcasecmp(argv[3], "like")) {
04141          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04142             return RESULT_SHOWUSAGE;
04143          havepattern = 1;
04144       } else
04145          return RESULT_SHOWUSAGE;
04146       break;
04147    case 4:
04148       if (!strcasecmp(argv[3], "registered"))
04149          registeredonly = 1;
04150       else
04151          return RESULT_SHOWUSAGE;
04152       break;
04153    case 3:
04154       break;
04155    default:
04156       return RESULT_SHOWUSAGE;
04157    }
04158 
04159 
04160    if (s)
04161       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04162    else
04163       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04164 
04165    AST_LIST_LOCK(&peers);
04166    AST_LIST_TRAVERSE(&peers, peer, entry) {
04167       char nm[20];
04168       char status[20];
04169       char srch[2000];
04170       int retstatus;
04171 
04172       if (registeredonly && !peer->addr.sin_addr.s_addr)
04173          continue;
04174       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04175          continue;
04176 
04177       if (!ast_strlen_zero(peer->username))
04178          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04179       else
04180          ast_copy_string(name, peer->name, sizeof(name));
04181       
04182       retstatus = peer_status(peer, status, sizeof(status));
04183       if (retstatus > 0)
04184          online_peers++;
04185       else if (!retstatus)
04186          offline_peers++;
04187       else
04188          unmonitored_peers++;
04189       
04190       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04191       
04192       snprintf(srch, sizeof(srch), FORMAT, name, 
04193           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04194           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04195           nm,
04196           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04197           peer->encmethods ? "(E)" : "   ", status, term);
04198       
04199       if (s)
04200          astman_append(s, FORMAT, name, 
04201                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04202                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04203                   nm,
04204                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04205                   peer->encmethods ? "(E)" : "   ", status, term);
04206       else
04207          ast_cli(fd, FORMAT, name, 
04208             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04209             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04210             nm,
04211             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04212             peer->encmethods ? "(E)" : "   ", status, term);
04213       total_peers++;
04214    }
04215    AST_LIST_UNLOCK(&peers);
04216 
04217    if (s)
04218       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04219    else
04220       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04221 
04222    if (havepattern)
04223       regfree(&regexbuf);
04224 
04225    return RESULT_SUCCESS;
04226 #undef FORMAT
04227 #undef FORMAT2
04228 }
04229 
04230 static int iax2_show_threads(int fd, int argc, char *argv[])
04231 {
04232    struct iax2_thread *thread = NULL;
04233    time_t t;
04234    int threadcount = 0, dynamiccount = 0;
04235    char type;
04236 
04237    if (argc != 3)
04238       return RESULT_SHOWUSAGE;
04239       
04240    ast_cli(fd, "IAX2 Thread Information\n");
04241    time(&t);
04242    ast_cli(fd, "Idle Threads:\n");
04243    AST_LIST_LOCK(&idle_list);
04244    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04245 #ifdef DEBUG_SCHED_MULTITHREAD
04246       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04247          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04248 #else
04249       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04250          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04251 #endif
04252       threadcount++;
04253    }
04254    AST_LIST_UNLOCK(&idle_list);
04255    ast_cli(fd, "Active Threads:\n");
04256    AST_LIST_LOCK(&active_list);
04257    AST_LIST_TRAVERSE(&active_list, thread, list) {
04258       if (thread->type == IAX_TYPE_DYNAMIC)
04259          type = 'D';
04260       else
04261          type = 'P';
04262 #ifdef DEBUG_SCHED_MULTITHREAD
04263       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04264          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04265 #else
04266       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04267          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04268 #endif
04269       threadcount++;
04270    }
04271    AST_LIST_UNLOCK(&active_list);
04272    ast_cli(fd, "Dynamic Threads:\n");
04273         AST_LIST_LOCK(&dynamic_list);
04274         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04275 #ifdef DEBUG_SCHED_MULTITHREAD
04276                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04277                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04278 #else
04279                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04280                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04281 #endif
04282       dynamiccount++;
04283         }
04284         AST_LIST_UNLOCK(&dynamic_list);
04285    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04286    return RESULT_SUCCESS;
04287 }
04288 
04289 static int iax2_show_peers(int fd, int argc, char *argv[])
04290 {
04291    return __iax2_show_peers(0, fd, NULL, argc, argv);
04292 }
04293 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04294 {
04295    ast_cli_netstats(s, -1, 0);
04296    astman_append(s, "\r\n");
04297    return RESULT_SUCCESS;
04298 }
04299 
04300 static int iax2_show_firmware(int fd, int argc, char *argv[])
04301 {
04302 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04303 #if !defined(__FreeBSD__)
04304 #define FORMAT "%-15.15s  %-15d %-15d\n"
04305 #else /* __FreeBSD__ */
04306 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04307 #endif /* __FreeBSD__ */
04308    struct iax_firmware *cur;
04309    if ((argc != 3) && (argc != 4))
04310       return RESULT_SHOWUSAGE;
04311    ast_mutex_lock(&waresl.lock);
04312    
04313    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04314    for (cur = waresl.wares;cur;cur = cur->next) {
04315       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04316          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04317             (int)ntohl(cur->fwh->datalen));
04318    }
04319    ast_mutex_unlock(&waresl.lock);
04320    return RESULT_SUCCESS;
04321 #undef FORMAT
04322 #undef FORMAT2
04323 }
04324 
04325 /* JDG: callback to display iax peers in manager */
04326 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04327 {
04328    char *a[] = { "iax2", "show", "users" };
04329    int ret;
04330    const char *id = astman_get_header(m,"ActionID");
04331 
04332    if (!ast_strlen_zero(id))
04333       astman_append(s, "ActionID: %s\r\n",id);
04334    ret = __iax2_show_peers(1, -1, s, 3, a );
04335    astman_append(s, "\r\n\r\n" );
04336    return ret;
04337 } /* /JDG */
04338 
04339 static char *regstate2str(int regstate)
04340 {
04341    switch(regstate) {
04342    case REG_STATE_UNREGISTERED:
04343       return "Unregistered";
04344    case REG_STATE_REGSENT:
04345       return "Request Sent";
04346    case REG_STATE_AUTHSENT:
04347       return "Auth. Sent";
04348    case REG_STATE_REGISTERED:
04349       return "Registered";
04350    case REG_STATE_REJECTED:
04351       return "Rejected";
04352    case REG_STATE_TIMEOUT:
04353       return "Timeout";
04354    case REG_STATE_NOAUTH:
04355       return "No Authentication";
04356    default:
04357       return "Unknown";
04358    }
04359 }
04360 
04361 static int iax2_show_registry(int fd, int argc, char *argv[])
04362 {
04363 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04364 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04365    struct iax2_registry *reg = NULL;
04366 
04367    char host[80];
04368    char perceived[80];
04369    if (argc != 3)
04370       return RESULT_SHOWUSAGE;
04371    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04372    AST_LIST_LOCK(&registrations);
04373    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04374       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04375       if (reg->us.sin_addr.s_addr) 
04376          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04377       else
04378          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04379       ast_cli(fd, FORMAT, host, 
04380                (reg->dnsmgr) ? "Y" : "N", 
04381                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04382    }
04383    AST_LIST_UNLOCK(&registrations);
04384    return RESULT_SUCCESS;
04385 #undef FORMAT
04386 #undef FORMAT2
04387 }
04388 
04389 static int iax2_show_channels(int fd, int argc, char *argv[])
04390 {
04391 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04392 #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"
04393 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04394    int x;
04395    int numchans = 0;
04396 
04397    if (argc != 3)
04398       return RESULT_SHOWUSAGE;
04399    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04400    for (x=0;x<IAX_MAX_CALLS;x++) {
04401       ast_mutex_lock(&iaxsl[x]);
04402       if (iaxs[x]) {
04403          int lag, jitter, localdelay;
04404          jb_info jbinfo;
04405          
04406          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04407             jb_getinfo(iaxs[x]->jb, &jbinfo);
04408             jitter = jbinfo.jitter;
04409             localdelay = jbinfo.current - jbinfo.min;
04410          } else {
04411             jitter = -1;
04412             localdelay = 0;
04413          }
04414          lag = iaxs[x]->remote_rr.delay;
04415          ast_cli(fd, FORMAT,
04416             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04417             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04418             S_OR(iaxs[x]->username, "(None)"),
04419             iaxs[x]->callno, iaxs[x]->peercallno,
04420             iaxs[x]->oseqno, iaxs[x]->iseqno,
04421             lag,
04422             jitter,
04423             localdelay,
04424             ast_getformatname(iaxs[x]->voiceformat) );
04425          numchans++;
04426       }
04427       ast_mutex_unlock(&iaxsl[x]);
04428    }
04429    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04430    return RESULT_SUCCESS;
04431 #undef FORMAT
04432 #undef FORMAT2
04433 #undef FORMATB
04434 }
04435 
04436 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04437 {
04438    int x;
04439    int numchans = 0;
04440    for (x=0;x<IAX_MAX_CALLS;x++) {
04441       ast_mutex_lock(&iaxsl[x]);
04442       if (iaxs[x]) {
04443          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04444          char *fmt;
04445          jb_info jbinfo;
04446          
04447          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04448             jb_getinfo(iaxs[x]->jb, &jbinfo);
04449             localjitter = jbinfo.jitter;
04450             localdelay = jbinfo.current - jbinfo.min;
04451             locallost = jbinfo.frames_lost;
04452             locallosspct = jbinfo.losspct/1000;
04453             localdropped = jbinfo.frames_dropped;
04454             localooo = jbinfo.frames_ooo;
04455          } else {
04456             localjitter = -1;
04457             localdelay = 0;
04458             locallost = -1;
04459             locallosspct = -1;
04460             localdropped = 0;
04461             localooo = -1;
04462          }
04463          if (limit_fmt)
04464             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04465          else
04466             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04467          if (s)
04468             
04469             astman_append(s, fmt,
04470                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04471                      iaxs[x]->pingtime,
04472                      localjitter, 
04473                      localdelay,
04474                      locallost,
04475                      locallosspct,
04476                      localdropped,
04477                      localooo,
04478                      iaxs[x]->frames_received/1000,
04479                      iaxs[x]->remote_rr.jitter,
04480                      iaxs[x]->remote_rr.delay,
04481                      iaxs[x]->remote_rr.losscnt,
04482                      iaxs[x]->remote_rr.losspct,
04483                      iaxs[x]->remote_rr.dropped,
04484                      iaxs[x]->remote_rr.ooo,
04485                      iaxs[x]->remote_rr.packets/1000);
04486          else
04487             ast_cli(fd, fmt,
04488                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04489                iaxs[x]->pingtime,
04490                localjitter, 
04491                localdelay,
04492                locallost,
04493                locallosspct,
04494                localdropped,
04495                localooo,
04496                iaxs[x]->frames_received/1000,
04497                iaxs[x]->remote_rr.jitter,
04498                iaxs[x]->remote_rr.delay,
04499                iaxs[x]->remote_rr.losscnt,
04500                iaxs[x]->remote_rr.losspct,
04501                iaxs[x]->remote_rr.dropped,
04502                iaxs[x]->remote_rr.ooo,
04503                iaxs[x]->remote_rr.packets/1000
04504                );
04505          numchans++;
04506       }
04507       ast_mutex_unlock(&iaxsl[x]);
04508    }
04509    return numchans;
04510 }
04511 
04512 static int iax2_show_netstats(int fd, int argc, char *argv[])
04513 {
04514    int numchans = 0;
04515    if (argc != 3)
04516       return RESULT_SHOWUSAGE;
04517    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04518    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04519    numchans = ast_cli_netstats(NULL, fd, 1);
04520    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04521    return RESULT_SUCCESS;
04522 }
04523 
04524 static int iax2_do_debug(int fd, int argc, char *argv[])
04525 {
04526    if (argc < 2 || argc > 3)
04527       return RESULT_SHOWUSAGE;
04528    iaxdebug = 1;
04529    ast_cli(fd, "IAX2 Debugging Enabled\n");
04530    return RESULT_SUCCESS;
04531 }
04532 
04533 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04534 {
04535    if (argc < 3 || argc > 4)
04536       return RESULT_SHOWUSAGE;
04537    iaxtrunkdebug = 1;
04538    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04539    return RESULT_SUCCESS;
04540 }
04541 
04542 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04543 {
04544    if (argc < 3 || argc > 4)
04545       return RESULT_SHOWUSAGE;
04546    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04547    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04548    return RESULT_SUCCESS;
04549 }
04550 
04551 static int iax2_no_debug(int fd, int argc, char *argv[])
04552 {
04553    if (argc < 3 || argc > 4)
04554       return RESULT_SHOWUSAGE;
04555    iaxdebug = 0;
04556    ast_cli(fd, "IAX2 Debugging Disabled\n");
04557    return RESULT_SUCCESS;
04558 }
04559 
04560 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04561 {
04562    if (argc < 4 || argc > 5)
04563       return RESULT_SHOWUSAGE;
04564    iaxtrunkdebug = 0;
04565    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04566    return RESULT_SUCCESS;
04567 }
04568 
04569 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04570 {
04571    if (argc < 4 || argc > 5)
04572       return RESULT_SHOWUSAGE;
04573    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04574    jb_debug_output("\n");
04575    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04576    return RESULT_SUCCESS;
04577 }
04578 
04579 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04580 {
04581    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04582    int res = -1;
04583    ast_mutex_lock(&iaxsl[callno]);
04584    if (iaxs[callno]) {
04585    /* If there's an outstanding error, return failure now */
04586       if (!iaxs[callno]->error) {
04587          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04588             res = 0;
04589             /* Don't waste bandwidth sending null frames */
04590          else if (f->frametype == AST_FRAME_NULL)
04591             res = 0;
04592          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04593             res = 0;
04594          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04595             res = 0;
04596          else
04597          /* Simple, just queue for transmission */
04598             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04599       } else {
04600          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04601       }
04602    }
04603    /* If it's already gone, just return */
04604    ast_mutex_unlock(&iaxsl[callno]);
04605    return res;
04606 }
04607 
04608 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04609       int now, int transfer, int final)
04610 {
04611    struct ast_frame f = { 0, };
04612 
04613    f.frametype = type;
04614    f.subclass = command;
04615    f.datalen = datalen;
04616    f.src = __FUNCTION__;
04617    f.data = (void *) data;
04618 
04619    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04620 }
04621 
04622 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04623 {
04624    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04625 }
04626 
04627 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04628 {
04629    int res;
04630    ast_mutex_lock(&iaxsl[callno]);
04631    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04632    ast_mutex_unlock(&iaxsl[callno]);
04633    return res;
04634 }
04635 
04636 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)
04637 {
04638    /* It is assumed that the callno has already been locked */
04639    iax2_predestroy(i->callno);
04640    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04641 }
04642 
04643 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)
04644 {
04645    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04646 }
04647 
04648 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04649 {
04650    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04651 }
04652 
04653 static int apply_context(struct iax2_context *con, const char *context)
04654 {
04655    while(con) {
04656       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04657          return -1;
04658       con = con->next;
04659    }
04660    return 0;
04661 }
04662 
04663 
04664 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04665 {
04666    /* Start pessimistic */
04667    int res = -1;
04668    int version = 2;
04669    struct iax2_user *user = NULL, *best = NULL;
04670    int bestscore = 0;
04671    int gotcapability = 0;
04672    struct ast_variable *v = NULL, *tmpvar = NULL;
04673 
04674    if (!iaxs[callno])
04675       return res;
04676    if (ies->called_number)
04677       ast_string_field_set(iaxs[callno], exten, ies->called_number);
04678    if (ies->calling_number) {
04679       ast_shrink_phone_number(ies->calling_number);
04680       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04681    }
04682    if (ies->calling_name)
04683       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04684    if (ies->calling_ani)
04685       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04686    if (ies->dnid)
04687       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04688    if (ies->rdnis)
04689       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04690    if (ies->called_context)
04691       ast_string_field_set(iaxs[callno], context, ies->called_context);
04692    if (ies->language)
04693       ast_string_field_set(iaxs[callno], language, ies->language);
04694    if (ies->username)
04695       ast_string_field_set(iaxs[callno], username, ies->username);
04696    if (ies->calling_ton > -1)
04697       iaxs[callno]->calling_ton = ies->calling_ton;
04698    if (ies->calling_tns > -1)
04699       iaxs[callno]->calling_tns = ies->calling_tns;
04700    if (ies->calling_pres > -1)
04701       iaxs[callno]->calling_pres = ies->calling_pres;
04702    if (ies->format)
04703       iaxs[callno]->peerformat = ies->format;
04704    if (ies->adsicpe)
04705       iaxs[callno]->peeradsicpe = ies->adsicpe;
04706    if (ies->capability) {
04707       gotcapability = 1;
04708       iaxs[callno]->peercapability = ies->capability;
04709    } 
04710    if (ies->version)
04711       version = ies->version;
04712 
04713    /* Use provided preferences until told otherwise for actual preferences */
04714    if(ies->codec_prefs) {
04715       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04716       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04717    }
04718 
04719    if (!gotcapability) 
04720       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04721    if (version > IAX_PROTO_VERSION) {
04722       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04723          ast_inet_ntoa(sin->sin_addr), version);
04724       return res;
04725    }
04726    /* Search the userlist for a compatible entry, and fill in the rest */
04727    AST_LIST_LOCK(&users);
04728    AST_LIST_TRAVERSE(&users, user, entry) {
04729       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04730          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04731          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04732          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04733               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04734          if (!ast_strlen_zero(iaxs[callno]->username)) {
04735             /* Exact match, stop right now. */
04736             best = user;
04737             break;
04738          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04739             /* No required authentication */
04740             if (user->ha) {
04741                /* There was host authentication and we passed, bonus! */
04742                if (bestscore < 4) {
04743                   bestscore = 4;
04744                   best = user;
04745                }
04746             } else {
04747                /* No host access, but no secret, either, not bad */
04748                if (bestscore < 3) {
04749                   bestscore = 3;
04750                   best = user;
04751                }
04752             }
04753          } else {
04754             if (user->ha) {
04755                /* Authentication, but host access too, eh, it's something.. */
04756                if (bestscore < 2) {
04757                   bestscore = 2;
04758                   best = user;
04759                }
04760             } else {
04761                /* Authentication and no host access...  This is our baseline */
04762                if (bestscore < 1) {
04763                   bestscore = 1;
04764                   best = user;
04765                }
04766             }
04767          }
04768       }
04769    }
04770    AST_LIST_UNLOCK(&users);
04771    user = best;
04772    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04773       user = realtime_user(iaxs[callno]->username);
04774       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
04775           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
04776          destroy_user(user);
04777          user = NULL;
04778       }
04779    }
04780    if (user) {
04781       /* We found our match (use the first) */
04782       /* copy vars */
04783       for (v = user->vars ; v ; v = v->next) {
04784          if((tmpvar = ast_variable_new(v->name, v->value))) {
04785             tmpvar->next = iaxs[callno]->vars; 
04786             iaxs[callno]->vars = tmpvar;
04787          }
04788       }
04789       /* If a max AUTHREQ restriction is in place, activate it */
04790       if (user->maxauthreq > 0)
04791          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04792       iaxs[callno]->prefs = user->prefs;
04793       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04794       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04795       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04796       iaxs[callno]->encmethods = user->encmethods;
04797       /* Store the requested username if not specified */
04798       if (ast_strlen_zero(iaxs[callno]->username))
04799          ast_string_field_set(iaxs[callno], username, user->name);
04800       /* Store whether this is a trunked call, too, of course, and move if appropriate */
04801       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04802       iaxs[callno]->capability = user->capability;
04803       /* And use the default context */
04804       if (ast_strlen_zero(iaxs[callno]->context)) {
04805          if (user->contexts)
04806             ast_string_field_set(iaxs[callno], context, user->contexts->context);
04807          else
04808             ast_string_field_set(iaxs[callno], context, context);
04809       }
04810       /* And any input keys */
04811       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
04812       /* And the permitted authentication methods */
04813       iaxs[callno]->authmethods = user->authmethods;
04814       iaxs[callno]->adsi = user->adsi;
04815       /* If they have callerid, override the given caller id.  Always store the ANI */
04816       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
04817          if (ast_test_flag(user, IAX_HASCALLERID)) {
04818             iaxs[callno]->calling_tns = 0;
04819             iaxs[callno]->calling_ton = 0;
04820             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
04821             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
04822             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
04823          }
04824          if (ast_strlen_zero(iaxs[callno]->ani))
04825             ast_string_field_set(iaxs[callno], ani, user->cid_num);
04826       } else {
04827          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
04828       }
04829       if (!ast_strlen_zero(user->accountcode))
04830          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
04831       if (!ast_strlen_zero(user->mohinterpret))
04832          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
04833       if (!ast_strlen_zero(user->mohsuggest))
04834          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
04835       if (user->amaflags)
04836          iaxs[callno]->amaflags = user->amaflags;
04837       if (!ast_strlen_zero(user->language))
04838          ast_string_field_set(iaxs[callno], language, user->language);
04839       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
04840       /* Keep this check last */
04841       if (!ast_strlen_zero(user->dbsecret)) {
04842          char *family, *key=NULL;
04843          char buf[80];
04844          family = ast_strdupa(user->dbsecret);
04845          key = strchr(family, '/');
04846          if (key) {
04847             *key = '\0';
04848             key++;
04849          }
04850          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
04851             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
04852          else
04853             ast_string_field_set(iaxs[callno], secret, buf);
04854       } else
04855          ast_string_field_set(iaxs[callno], secret, user->secret);
04856       if (ast_test_flag(user, IAX_TEMPONLY))
04857          destroy_user(user);
04858       res = 0;
04859    }
04860    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
04861    return res;
04862 }
04863 
04864 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
04865 {
04866    struct ast_iax2_full_hdr fh;
04867    fh.scallno = htons(src | IAX_FLAG_FULL);
04868    fh.dcallno = htons(dst);
04869    fh.ts = 0;
04870    fh.oseqno = 0;
04871    fh.iseqno = 0;
04872    fh.type = AST_FRAME_IAX;
04873    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04874    if (iaxdebug)
04875        iax_showframe(NULL, &fh, 0, sin, 0);
04876 #if 0
04877    if (option_debug)
04878 #endif   
04879       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04880          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
04881    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04882 }
04883 
04884 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
04885 {
04886    /* Select exactly one common encryption if there are any */
04887    p->encmethods &= enc;
04888    if (p->encmethods) {
04889       if (p->encmethods & IAX_ENCRYPT_AES128)
04890          p->encmethods = IAX_ENCRYPT_AES128;
04891       else
04892          p->encmethods = 0;
04893    }
04894 }
04895 
04896 static int authenticate_request(struct chan_iax2_pvt *p)
04897 {
04898    struct iax2_user *user = NULL;
04899    struct iax_ie_data ied;
04900    int res = -1, authreq_restrict = 0;
04901    char challenge[10];
04902 
04903    memset(&ied, 0, sizeof(ied));
04904 
04905    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04906    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04907       AST_LIST_LOCK(&users);
04908       AST_LIST_TRAVERSE(&users, user, entry) {
04909          if (!strcmp(user->name, p->username)) {
04910             if (user->curauthreq == user->maxauthreq)
04911                authreq_restrict = 1;
04912             else
04913                user->curauthreq++;
04914             break;
04915          }
04916       }
04917       AST_LIST_UNLOCK(&users);
04918    }
04919 
04920    /* If the AUTHREQ limit test failed, send back an error */
04921    if (authreq_restrict) {
04922       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04923       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04924       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
04925       return 0;
04926    }
04927 
04928    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04929    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04930       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
04931       ast_string_field_set(p, challenge, challenge);
04932       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
04933       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04934    }
04935    if (p->encmethods)
04936       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04937 
04938    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
04939 
04940    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
04941 
04942    if (p->encmethods)
04943       ast_set_flag(p, IAX_ENCRYPTED);
04944 
04945    return res;
04946 }
04947 
04948 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
04949 {
04950    char requeststr[256];
04951    char md5secret[256] = "";
04952    char secret[256] = "";
04953    char rsasecret[256] = "";
04954    int res = -1; 
04955    int x;
04956    struct iax2_user *user = NULL;
04957 
04958    AST_LIST_LOCK(&users);
04959    AST_LIST_TRAVERSE(&users, user, entry) {
04960       if (!strcmp(user->name, p->username))
04961          break;
04962    }
04963    if (user) {
04964       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04965          user->curauthreq--;
04966          ast_clear_flag(p, IAX_MAXAUTHREQ);
04967       }
04968       ast_string_field_set(p, host, user->name);
04969    }
04970    AST_LIST_UNLOCK(&users);
04971 
04972    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
04973       return res;
04974    if (ies->password)
04975       ast_copy_string(secret, ies->password, sizeof(secret));
04976    if (ies->md5_result)
04977       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04978    if (ies->rsa_result)
04979       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04980    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
04981       struct ast_key *key;
04982       char *keyn;
04983       char tmpkey[256];
04984       char *stringp=NULL;
04985       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
04986       stringp=tmpkey;
04987       keyn = strsep(&stringp, ":");
04988       while(keyn) {
04989          key = ast_key_get(keyn, AST_KEY_PUBLIC);
04990          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
04991             res = 0;
04992             break;
04993          } else if (!key)
04994             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
04995          keyn = strsep(&stringp, ":");
04996       }
04997    } else if (p->authmethods & IAX_AUTH_MD5) {
04998       struct MD5Context md5;
04999       unsigned char digest[16];
05000       char *tmppw, *stringp;
05001       
05002       tmppw = ast_strdupa(p->secret);
05003       stringp = tmppw;
05004       while((tmppw = strsep(&stringp, ";"))) {
05005          MD5Init(&md5);
05006          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05007          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05008          MD5Final(digest, &md5);
05009          /* If they support md5, authenticate with it.  */
05010          for (x=0;x<16;x++)
05011             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05012          if (!strcasecmp(requeststr, md5secret)) {
05013             res = 0;
05014             break;
05015          }
05016       }
05017    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05018       if (!strcmp(secret, p->secret))
05019          res = 0;
05020    }
05021    return res;
05022 }
05023 
05024 /*! \brief Verify inbound registration */
05025 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05026 {
05027    char requeststr[256] = "";
05028    char peer[256] = "";
05029    char md5secret[256] = "";
05030    char rsasecret[256] = "";
05031    char secret[256] = "";
05032    struct iax2_peer *p;
05033    struct ast_key *key;
05034    char *keyn;
05035    int x;
05036    int expire = 0;
05037 
05038    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05039    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05040    if (ies->username)
05041       ast_copy_string(peer, ies->username, sizeof(peer));
05042    if (ies->password)
05043       ast_copy_string(secret, ies->password, sizeof(secret));
05044    if (ies->md5_result)
05045       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05046    if (ies->rsa_result)
05047       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05048    if (ies->refresh)
05049       expire = ies->refresh;
05050 
05051    if (ast_strlen_zero(peer)) {
05052       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05053       return -1;
05054    }
05055 
05056    /* SLD: first call to lookup peer during registration */
05057    p = find_peer(peer, 1);
05058 
05059    if (!p) {
05060       if (authdebug)
05061          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05062       return -1;
05063    }
05064 
05065    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05066       if (authdebug)
05067          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05068       if (ast_test_flag(p, IAX_TEMPONLY))
05069          destroy_peer(p);
05070       return -1;
05071    }
05072 
05073    if (!ast_apply_ha(p->ha, sin)) {
05074       if (authdebug)
05075          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05076       if (ast_test_flag(p, IAX_TEMPONLY))
05077          destroy_peer(p);
05078       return -1;
05079    }
05080    if (!inaddrcmp(&p->addr, sin))
05081       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05082    ast_string_field_set(iaxs[callno], secret, p->secret);
05083    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05084    /* Check secret against what we have on file */
05085    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05086       if (!ast_strlen_zero(p->inkeys)) {
05087          char tmpkeys[256];
05088          char *stringp=NULL;
05089          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05090          stringp=tmpkeys;
05091          keyn = strsep(&stringp, ":");
05092          while(keyn) {
05093             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05094             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05095                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05096                break;
05097             } else if (!key) 
05098                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05099             keyn = strsep(&stringp, ":");
05100          }
05101          if (!keyn) {
05102             if (authdebug)
05103                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05104             if (ast_test_flag(p, IAX_TEMPONLY))
05105                destroy_peer(p);
05106             return -1;
05107          }
05108       } else {
05109          if (authdebug)
05110             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05111          if (ast_test_flag(p, IAX_TEMPONLY))
05112             destroy_peer(p);
05113          return -1;
05114       }
05115    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05116       struct MD5Context md5;
05117       unsigned char digest[16];
05118       char *tmppw, *stringp;
05119       
05120       tmppw = ast_strdupa(p->secret);
05121       stringp = tmppw;
05122       while((tmppw = strsep(&stringp, ";"))) {
05123          MD5Init(&md5);
05124          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05125          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05126          MD5Final(digest, &md5);
05127          for (x=0;x<16;x++)
05128             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05129          if (!strcasecmp(requeststr, md5secret)) 
05130             break;
05131       }
05132       if (tmppw) {
05133          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05134       } else {
05135          if (authdebug)
05136             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05137          if (ast_test_flag(p, IAX_TEMPONLY))
05138             destroy_peer(p);
05139          return -1;
05140       }
05141    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05142       /* They've provided a plain text password and we support that */
05143       if (strcmp(secret, p->secret)) {
05144          if (authdebug)
05145             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05146          if (ast_test_flag(p, IAX_TEMPONLY))
05147             destroy_peer(p);
05148          return -1;
05149       } else
05150          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05151    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05152       if (authdebug)
05153          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05154       if (ast_test_flag(p, IAX_TEMPONLY))
05155          destroy_peer(p);
05156       return -1;
05157    }
05158    ast_string_field_set(iaxs[callno], peer, peer);
05159    /* Choose lowest expiry number */
05160    if (expire && (expire < iaxs[callno]->expiry)) 
05161       iaxs[callno]->expiry = expire;
05162 
05163    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05164 
05165    if (ast_test_flag(p, IAX_TEMPONLY))
05166       destroy_peer(p);
05167    return 0;
05168    
05169 }
05170 
05171 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05172 {
05173    int res = -1;
05174    int x;
05175    if (!ast_strlen_zero(keyn)) {
05176       if (!(authmethods & IAX_AUTH_RSA)) {
05177          if (ast_strlen_zero(secret)) 
05178             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
05179       } else if (ast_strlen_zero(challenge)) {
05180          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05181       } else {
05182          char sig[256];
05183          struct ast_key *key;
05184          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05185          if (!key) {
05186             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05187          } else {
05188             if (ast_sign(key, (char*)challenge, sig)) {
05189                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05190                res = -1;
05191             } else {
05192                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05193                res = 0;
05194             }
05195          }
05196       }
05197    } 
05198    /* Fall back */
05199    if (res && !ast_strlen_zero(secret)) {
05200       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05201          struct MD5Context md5;
05202          unsigned char digest[16];
05203          char digres[128];
05204          MD5Init(&md5);
05205          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05206          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05207          MD5Final(digest, &md5);
05208          /* If they support md5, authenticate with it.  */
05209          for (x=0;x<16;x++)
05210             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05211          if (ecx && dcx)
05212             build_enc_keys(digest, ecx, dcx);
05213          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05214          res = 0;
05215       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05216          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05217          res = 0;
05218       } else
05219          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05220    }
05221    return res;
05222 }
05223 
05224 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05225 {
05226    struct iax2_peer *peer = NULL;
05227    /* Start pessimistic */
05228    int res = -1;
05229    int authmethods = 0;
05230    struct iax_ie_data ied;
05231    
05232    memset(&ied, 0, sizeof(ied));
05233    
05234    if (ies->username)
05235       ast_string_field_set(p, username, ies->username);
05236    if (ies->challenge)
05237       ast_string_field_set(p, challenge, ies->challenge);
05238    if (ies->authmethods)
05239       authmethods = ies->authmethods;
05240    if (authmethods & IAX_AUTH_MD5)
05241       merge_encryption(p, ies->encmethods);
05242    else
05243       p->encmethods = 0;
05244 
05245    /* Check for override RSA authentication first */
05246    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05247       /* Normal password authentication */
05248       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05249    } else {
05250       AST_LIST_LOCK(&peers);
05251       AST_LIST_TRAVERSE(&peers, peer, entry) {
05252          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05253              /* No peer specified at our end, or this is the peer */
05254              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05255              /* No username specified in peer rule, or this is the right username */
05256              && (!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)))
05257              /* No specified host, or this is our host */
05258             ) {
05259             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05260             if (!res)
05261                break;   
05262          }
05263       }
05264       AST_LIST_UNLOCK(&peers);
05265       if (!peer) {
05266          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05267             that we're trying to authenticate *to* a realtime peer */
05268          if ((peer = realtime_peer(p->peer, NULL))) {
05269             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05270             if (ast_test_flag(peer, IAX_TEMPONLY))
05271                destroy_peer(peer);
05272          }
05273       }
05274    }
05275    if (ies->encmethods)
05276       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05277    if (!res)
05278       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05279    return res;
05280 }
05281 
05282 static int iax2_do_register(struct iax2_registry *reg);
05283 
05284 static void __iax2_do_register_s(void *data)
05285 {
05286    struct iax2_registry *reg = data;
05287    reg->expire = -1;
05288    iax2_do_register(reg);
05289 }
05290 
05291 static int iax2_do_register_s(void *data)
05292 {
05293 #ifdef SCHED_MULTITHREADED
05294    if (schedule_action(__iax2_do_register_s, data))
05295 #endif      
05296       __iax2_do_register_s(data);
05297    return 0;
05298 }
05299 
05300 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05301 {
05302    int newcall = 0;
05303    char newip[256];
05304    struct iax_ie_data ied;
05305    struct sockaddr_in new;
05306    
05307    
05308    memset(&ied, 0, sizeof(ied));
05309    if (ies->apparent_addr)
05310       bcopy(ies->apparent_addr, &new, sizeof(new));
05311    if (ies->callno)
05312       newcall = ies->callno;
05313    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05314       ast_log(LOG_WARNING, "Invalid transfer request\n");
05315       return -1;
05316    }
05317    pvt->transfercallno = newcall;
05318    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05319    inet_aton(newip, &pvt->transfer.sin_addr);
05320    pvt->transfer.sin_family = AF_INET;
05321    pvt->transferring = TRANSFER_BEGIN;
05322    pvt->transferid = ies->transferid;
05323    if (ies->transferid)
05324       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05325    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05326    return 0; 
05327 }
05328 
05329 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05330 {
05331    char exten[256] = "";
05332    int status = CACHE_FLAG_UNKNOWN;
05333    int expiry = iaxdefaultdpcache;
05334    int x;
05335    int matchmore = 0;
05336    struct iax2_dpcache *dp, *prev;
05337    
05338    if (ies->called_number)
05339       ast_copy_string(exten, ies->called_number, sizeof(exten));
05340 
05341    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05342       status = CACHE_FLAG_EXISTS;
05343    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05344       status = CACHE_FLAG_CANEXIST;
05345    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05346       status = CACHE_FLAG_NONEXISTENT;
05347 
05348    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05349       /* Don't really do anything with this */
05350    }
05351    if (ies->refresh)
05352       expiry = ies->refresh;
05353    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05354       matchmore = CACHE_FLAG_MATCHMORE;
05355    ast_mutex_lock(&dpcache_lock);
05356    prev = NULL;
05357    dp = pvt->dpentries;
05358    while(dp) {
05359       if (!strcmp(dp->exten, exten)) {
05360          /* Let them go */
05361          if (prev)
05362             prev->peer = dp->peer;
05363          else
05364             pvt->dpentries = dp->peer;
05365          dp->peer = NULL;
05366          dp->callno = 0;
05367          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05368          if (dp->flags & CACHE_FLAG_PENDING) {
05369             dp->flags &= ~CACHE_FLAG_PENDING;
05370             dp->flags |= status;
05371             dp->flags |= matchmore;
05372          }
05373          /* Wake up waiters */
05374          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05375             if (dp->waiters[x] > -1)
05376                write(dp->waiters[x], "asdf", 4);
05377       }
05378       prev = dp;
05379       dp = dp->peer;
05380    }
05381    ast_mutex_unlock(&dpcache_lock);
05382    return 0;
05383 }
05384 
05385 static int complete_transfer(int callno, struct iax_ies *ies)
05386 {
05387    int peercallno = 0;
05388    struct chan_iax2_pvt *pvt = iaxs[callno];
05389    struct iax_frame *cur;
05390    jb_frame frame;
05391 
05392    if (ies->callno)
05393       peercallno = ies->callno;
05394 
05395    if (peercallno < 1) {
05396       ast_log(LOG_WARNING, "Invalid transfer request\n");
05397       return -1;
05398    }
05399    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05400    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05401    /* Reset sequence numbers */
05402    pvt->oseqno = 0;
05403    pvt->rseqno = 0;
05404    pvt->iseqno = 0;
05405    pvt->aseqno = 0;
05406    pvt->peercallno = peercallno;
05407    pvt->transferring = TRANSFER_NONE;
05408    pvt->svoiceformat = -1;
05409    pvt->voiceformat = 0;
05410    pvt->svideoformat = -1;
05411    pvt->videoformat = 0;
05412    pvt->transfercallno = -1;
05413    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05414    memset(&pvt->offset, 0, sizeof(pvt->offset));
05415    /* reset jitterbuffer */
05416    while(jb_getall(pvt->jb,&frame) == JB_OK)
05417       iax2_frame_free(frame.data);
05418    jb_reset(pvt->jb);
05419    pvt->lag = 0;
05420    pvt->last = 0;
05421    pvt->lastsent = 0;
05422    pvt->nextpred = 0;
05423    pvt->pingtime = DEFAULT_RETRY_TIME;
05424    AST_LIST_LOCK(&iaxq.queue);
05425    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05426       /* We must cancel any packets that would have been transmitted
05427          because now we're talking to someone new.  It's okay, they
05428          were transmitted to someone that didn't care anyway. */
05429       if (callno == cur->callno) 
05430          cur->retries = -1;
05431    }
05432    AST_LIST_UNLOCK(&iaxq.queue);
05433    return 0; 
05434 }
05435 
05436 /*! \brief Acknowledgment received for OUR registration */
05437 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05438 {
05439    struct iax2_registry *reg;
05440    /* Start pessimistic */
05441    char peer[256] = "";
05442    char msgstatus[60];
05443    int refresh = 60;
05444    char ourip[256] = "<Unspecified>";
05445    struct sockaddr_in oldus;
05446    struct sockaddr_in us;
05447    int oldmsgs;
05448 
05449    memset(&us, 0, sizeof(us));
05450    if (ies->apparent_addr)
05451       bcopy(ies->apparent_addr, &us, sizeof(us));
05452    if (ies->username)
05453       ast_copy_string(peer, ies->username, sizeof(peer));
05454    if (ies->refresh)
05455       refresh = ies->refresh;
05456    if (ies->calling_number) {
05457       /* We don't do anything with it really, but maybe we should */
05458    }
05459    reg = iaxs[callno]->reg;
05460    if (!reg) {
05461       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05462       return -1;
05463    }
05464    memcpy(&oldus, &reg->us, sizeof(oldus));
05465    oldmsgs = reg->messages;
05466    if (inaddrcmp(&reg->addr, sin)) {
05467       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05468       return -1;
05469    }
05470    memcpy(&reg->us, &us, sizeof(reg->us));
05471    if (ies->msgcount >= 0)
05472       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05473    /* always refresh the registration at the interval requested by the server
05474       we are registering to
05475    */
05476    reg->refresh = refresh;
05477    if (reg->expire > -1)
05478       ast_sched_del(sched, reg->expire);
05479    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05480    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05481       if (option_verbose > 2) {
05482          if (reg->messages > 255)
05483             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05484          else if (reg->messages > 1)
05485             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05486          else if (reg->messages > 0)
05487             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05488          else
05489             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05490          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05491          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05492       }
05493       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05494    }
05495    reg->regstate = REG_STATE_REGISTERED;
05496    return 0;
05497 }
05498 
05499 static int iax2_register(char *value, int lineno)
05500 {
05501    struct iax2_registry *reg;
05502    char copy[256];
05503    char *username, *hostname, *secret;
05504    char *porta;
05505    char *stringp=NULL;
05506    
05507    if (!value)
05508       return -1;
05509    ast_copy_string(copy, value, sizeof(copy));
05510    stringp=copy;
05511    username = strsep(&stringp, "@");
05512    hostname = strsep(&stringp, "@");
05513    if (!hostname) {
05514       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05515       return -1;
05516    }
05517    stringp=username;
05518    username = strsep(&stringp, ":");
05519    secret = strsep(&stringp, ":");
05520    stringp=hostname;
05521    hostname = strsep(&stringp, ":");
05522    porta = strsep(&stringp, ":");
05523    
05524    if (porta && !atoi(porta)) {
05525       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05526       return -1;
05527    }
05528    if (!(reg = ast_calloc(1, sizeof(*reg))))
05529       return -1;
05530    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05531       free(reg);
05532       return -1;
05533    }
05534    ast_copy_string(reg->username, username, sizeof(reg->username));
05535    if (secret)
05536       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05537    reg->expire = -1;
05538    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05539    reg->addr.sin_family = AF_INET;
05540    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05541    AST_LIST_LOCK(&registrations);
05542    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05543    AST_LIST_UNLOCK(&registrations);
05544    
05545    return 0;
05546 }
05547 
05548 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05549 {
05550    char multi[256];
05551    char *stringp, *ext;
05552    if (!ast_strlen_zero(regcontext)) {
05553       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05554       stringp = multi;
05555       while((ext = strsep(&stringp, "&"))) {
05556          if (onoff) {
05557             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05558                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05559                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05560          } else
05561             ast_context_remove_extension(regcontext, ext, 1, NULL);
05562       }
05563    }
05564 }
05565 static void prune_peers(void);
05566 
05567 static void __expire_registry(void *data)
05568 {
05569    char *name = data;
05570    struct iax2_peer *p = NULL;
05571 
05572    /* Go through and grab this peer... and if it needs to be removed... then do it */
05573    AST_LIST_LOCK(&peers);
05574    AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
05575       if (!strcasecmp(p->name, name)) {
05576          p->expire = -1;
05577          break;
05578       }
05579    }
05580    AST_LIST_TRAVERSE_SAFE_END
05581    AST_LIST_UNLOCK(&peers);
05582 
05583    /* Peer is already gone for whatever reason */
05584    if (!p)
05585       return;
05586 
05587    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05588    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05589       realtime_update_peer(p->name, &p->addr, 0);
05590    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
05591    /* Reset the address */
05592    memset(&p->addr, 0, sizeof(p->addr));
05593    /* Reset expiry value */
05594    p->expiry = min_reg_expire;
05595    if (!ast_test_flag(p, IAX_TEMPONLY))
05596       ast_db_del("IAX/Registry", p->name);
05597    register_peer_exten(p, 0);
05598    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05599    if (iax2_regfunk)
05600       iax2_regfunk(p->name, 0);
05601 
05602    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05603       ast_set_flag(p, IAX_DELME);
05604       prune_peers();
05605    }
05606 }
05607 
05608 static int expire_registry(void *data)
05609 {
05610 #ifdef SCHED_MULTITHREADED
05611    if (schedule_action(__expire_registry, data))
05612 #endif      
05613       __expire_registry(data);
05614    return 0;
05615 }
05616 
05617 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05618 
05619 static void reg_source_db(struct iax2_peer *p)
05620 {
05621    char data[80];
05622    struct in_addr in;
05623    char *c, *d;
05624    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05625       c = strchr(data, ':');
05626       if (c) {
05627          *c = '\0';
05628          c++;
05629          if (inet_aton(data, &in)) {
05630             d = strchr(c, ':');
05631             if (d) {
05632                *d = '\0';
05633                d++;
05634                if (option_verbose > 2)
05635                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05636                   ast_inet_ntoa(in), atoi(c), atoi(d));
05637                iax2_poke_peer(p, 0);
05638                p->expiry = atoi(d);
05639                memset(&p->addr, 0, sizeof(p->addr));
05640                p->addr.sin_family = AF_INET;
05641                p->addr.sin_addr = in;
05642                p->addr.sin_port = htons(atoi(c));
05643                if (p->expire > -1)
05644                   ast_sched_del(sched, p->expire);
05645                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05646                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05647                if (iax2_regfunk)
05648                   iax2_regfunk(p->name, 1);
05649                register_peer_exten(p, 1);
05650             }              
05651                
05652          }
05653       }
05654    }
05655 }
05656 
05657 static int update_registry(const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05658 {
05659    /* Called from IAX thread only, with proper iaxsl lock */
05660    struct iax_ie_data ied;
05661    struct iax2_peer *p;
05662    int msgcount;
05663    char data[80];
05664    int version;
05665 
05666    memset(&ied, 0, sizeof(ied));
05667 
05668    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05669    if (!(p = find_peer(name, 1))) {
05670       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05671       return -1;
05672    }
05673 
05674    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05675       if (sin->sin_addr.s_addr) {
05676          time_t nowtime;
05677          time(&nowtime);
05678          realtime_update_peer(name, sin, nowtime);
05679       } else {
05680          realtime_update_peer(name, sin, 0);
05681       }
05682    }
05683    if (inaddrcmp(&p->addr, sin)) {
05684       if (iax2_regfunk)
05685          iax2_regfunk(p->name, 1);
05686       /* Stash the IP address from which they registered */
05687       memcpy(&p->addr, sin, sizeof(p->addr));
05688       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05689       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05690          ast_db_put("IAX/Registry", p->name, data);
05691          if  (option_verbose > 2)
05692             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05693                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
05694          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05695          register_peer_exten(p, 1);
05696          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05697       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05698          if  (option_verbose > 2)
05699             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05700                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05701          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05702          register_peer_exten(p, 0);
05703          ast_db_del("IAX/Registry", p->name);
05704          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05705       }
05706       /* Update the host */
05707       /* Verify that the host is really there */
05708       iax2_poke_peer(p, callno);
05709    }     
05710 
05711    /* Make sure our call still exists, an INVAL at the right point may make it go away */
05712    if (!iaxs[callno])
05713       return 0;
05714 
05715    /* Store socket fd */
05716    p->sockfd = fd;
05717    /* Setup the expiry */
05718    if (p->expire > -1)
05719       ast_sched_del(sched, p->expire);
05720    /* treat an unspecified refresh interval as the minimum */
05721    if (!refresh)
05722       refresh = min_reg_expire;
05723    if (refresh > max_reg_expire) {
05724       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05725          p->name, max_reg_expire, refresh);
05726       p->expiry = max_reg_expire;
05727    } else if (refresh < min_reg_expire) {
05728       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05729          p->name, min_reg_expire, refresh);
05730       p->expiry = min_reg_expire;
05731    } else {
05732       p->expiry = refresh;
05733    }
05734    if (p->expiry && sin->sin_addr.s_addr)
05735       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05736    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05737    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05738    if (sin->sin_addr.s_addr) {
05739       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05740       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05741       if (!ast_strlen_zero(p->mailbox)) {
05742          int new, old;
05743          ast_app_inboxcount(p->mailbox, &new, &old);
05744          if (new > 255)
05745             new = 255;
05746          if (old > 255)
05747             old = 255;
05748          msgcount = (old << 8) | new;
05749          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05750       }
05751       if (ast_test_flag(p, IAX_HASCALLERID)) {
05752          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05753          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05754       }
05755    }
05756    version = iax_check_version(devtype);
05757    if (version) 
05758       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05759    if (ast_test_flag(p, IAX_TEMPONLY))
05760       destroy_peer(p);
05761    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05762 }
05763 
05764 static int registry_authrequest(const char *name, int callno)
05765 {
05766    struct iax_ie_data ied;
05767    struct iax2_peer *p;
05768    char challenge[10];
05769    /* SLD: third call to find_peer in registration */
05770    p = find_peer(name, 1);
05771    if (p) {
05772       memset(&ied, 0, sizeof(ied));
05773       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05774       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05775          /* Build the challenge */
05776          snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05777          ast_string_field_set(iaxs[callno], challenge, challenge);
05778          /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
05779          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05780       }
05781       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05782       if (ast_test_flag(p, IAX_TEMPONLY))
05783          destroy_peer(p);
05784       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05785    } 
05786    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05787    return 0;
05788 }
05789 
05790 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
05791 {
05792    struct iax2_registry *reg;
05793    /* Start pessimistic */
05794    struct iax_ie_data ied;
05795    char peer[256] = "";
05796    char challenge[256] = "";
05797    int res;
05798    int authmethods = 0;
05799    if (ies->authmethods)
05800       authmethods = ies->authmethods;
05801    if (ies->username)
05802       ast_copy_string(peer, ies->username, sizeof(peer));
05803    if (ies->challenge)
05804       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05805    memset(&ied, 0, sizeof(ied));
05806    reg = iaxs[callno]->reg;
05807    if (reg) {
05808          if (inaddrcmp(&reg->addr, sin)) {
05809             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05810             return -1;
05811          }
05812          if (ast_strlen_zero(reg->secret)) {
05813             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05814             reg->regstate = REG_STATE_NOAUTH;
05815             return -1;
05816          }
05817          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05818          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05819          if (reg->secret[0] == '[') {
05820             char tmpkey[256];
05821             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05822             tmpkey[strlen(tmpkey) - 1] = '\0';
05823             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05824          } else
05825             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05826          if (!res) {
05827             reg->regstate = REG_STATE_AUTHSENT;
05828             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05829          } else
05830             return -1;
05831          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05832    } else   
05833       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05834    return -1;
05835 }
05836 
05837 static void stop_stuff(int callno)
05838 {
05839    iax2_destroy_helper(iaxs[callno]);
05840 }
05841 
05842 static void __auth_reject(void *nothing)
05843 {
05844    /* Called from IAX thread only, without iaxs lock */
05845    int callno = (int)(long)(nothing);
05846    struct iax_ie_data ied;
05847    ast_mutex_lock(&iaxsl[callno]);
05848    if (iaxs[callno]) {
05849       memset(&ied, 0, sizeof(ied));
05850       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05851          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05852          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05853       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05854          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05855          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05856       }
05857       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05858    }
05859    ast_mutex_unlock(&iaxsl[callno]);
05860 }
05861 
05862 static int auth_reject(void *data)
05863 {
05864    int callno = (int)(long)(data);
05865    ast_mutex_lock(&iaxsl[callno]);
05866    if (iaxs[callno])
05867       iaxs[callno]->authid = -1;
05868    ast_mutex_unlock(&iaxsl[callno]);
05869 #ifdef SCHED_MULTITHREADED
05870    if (schedule_action(__auth_reject, data))
05871 #endif      
05872       __auth_reject(data);
05873    return 0;
05874 }
05875 
05876 static int auth_fail(int callno, int failcode)
05877 {
05878    /* Schedule sending the authentication failure in one second, to prevent
05879       guessing */
05880    ast_mutex_lock(&iaxsl[callno]);
05881    if (iaxs[callno]) {
05882       iaxs[callno]->authfail = failcode;
05883       if (delayreject) {
05884          if (iaxs[callno]->authid > -1)
05885             ast_sched_del(sched, iaxs[callno]->authid);
05886          iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05887       } else
05888          auth_reject((void *)(long)callno);
05889    }
05890    ast_mutex_unlock(&iaxsl[callno]);
05891    return 0;
05892 }
05893 
05894 static void __auto_hangup(void *nothing)
05895 {
05896    /* Called from IAX thread only, without iaxs lock */
05897    int callno = (int)(long)(nothing);
05898    struct iax_ie_data ied;
05899    ast_mutex_lock(&iaxsl[callno]);
05900    if (iaxs[callno]) {
05901       memset(&ied, 0, sizeof(ied));
05902       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05903       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05904       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05905    }
05906    ast_mutex_unlock(&iaxsl[callno]);
05907 }
05908 
05909 static int auto_hangup(void *data)
05910 {
05911    int callno = (int)(long)(data);
05912    ast_mutex_lock(&iaxsl[callno]);
05913    if (iaxs[callno]) {
05914       iaxs[callno]->autoid = -1;
05915    }
05916    ast_mutex_unlock(&iaxsl[callno]);
05917 #ifdef SCHED_MULTITHREADED
05918    if (schedule_action(__auto_hangup, data))
05919 #endif      
05920       __auto_hangup(data);
05921    return 0;
05922 }
05923 
05924 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
05925 {
05926    struct iax_ie_data ied;
05927    /* Auto-hangup with 30 seconds of inactivity */
05928    if (iaxs[callno]->autoid > -1)
05929       ast_sched_del(sched, iaxs[callno]->autoid);
05930    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05931    memset(&ied, 0, sizeof(ied));
05932    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05933    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05934    dp->flags |= CACHE_FLAG_TRANSMITTED;
05935 }
05936 
05937 static int iax2_vnak(int callno)
05938 {
05939    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05940 }
05941 
05942 static void vnak_retransmit(int callno, int last)
05943 {
05944    struct iax_frame *f;
05945 
05946    AST_LIST_LOCK(&iaxq.queue);
05947    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
05948       /* Send a copy immediately */
05949       if ((f->callno == callno) && iaxs[f->callno] &&
05950          ((unsigned char ) (f->oseqno - last) < 128) &&
05951          (f->retries >= 0)) {
05952          send_packet(f);
05953       }
05954    }
05955    AST_LIST_UNLOCK(&iaxq.queue);
05956 }
05957 
05958 static void __iax2_poke_peer_s(void *data)
05959 {
05960    struct iax2_peer *peer = data;
05961    iax2_poke_peer(peer, 0);
05962 }
05963 
05964 static int iax2_poke_peer_s(void *data)
05965 {
05966    struct iax2_peer *peer = data;
05967    peer->pokeexpire = -1;
05968 #ifdef SCHED_MULTITHREADED
05969    if (schedule_action(__iax2_poke_peer_s, data))
05970 #endif      
05971       __iax2_poke_peer_s(data);
05972    return 0;
05973 }
05974 
05975 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
05976 {
05977    int res = 0;
05978    struct iax_frame *fr;
05979    struct ast_iax2_meta_hdr *meta;
05980    struct ast_iax2_meta_trunk_hdr *mth;
05981    int calls = 0;
05982    
05983    /* Point to frame */
05984    fr = (struct iax_frame *)tpeer->trunkdata;
05985    /* Point to meta data */
05986    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
05987    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
05988    if (tpeer->trunkdatalen) {
05989       /* We're actually sending a frame, so fill the meta trunk header and meta header */
05990       meta->zeros = 0;
05991       meta->metacmd = IAX_META_TRUNK;
05992       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
05993          meta->cmddata = IAX_META_TRUNK_MINI;
05994       else
05995          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
05996       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
05997       /* And the rest of the ast_iax2 header */
05998       fr->direction = DIRECTION_OUTGRESS;
05999       fr->retrans = -1;
06000       fr->transfer = 0;
06001       /* Any appropriate call will do */
06002       fr->data = fr->afdata;
06003       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06004       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06005       calls = tpeer->calls;
06006 #if 0
06007       ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
06008 #endif      
06009       /* Reset transmit trunk side data */
06010       tpeer->trunkdatalen = 0;
06011       tpeer->calls = 0;
06012    }
06013    if (res < 0)
06014       return res;
06015    return calls;
06016 }
06017 
06018 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06019 {
06020    /* Drop when trunk is about 5 seconds idle */
06021    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06022       return 1;
06023    return 0;
06024 }
06025 
06026 static int timing_read(int *id, int fd, short events, void *cbdata)
06027 {
06028    char buf[1024];
06029    int res;
06030    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06031    int processed = 0;
06032    int totalcalls = 0;
06033 #ifdef ZT_TIMERACK
06034    int x = 1;
06035 #endif
06036    struct timeval now;
06037    if (iaxtrunkdebug)
06038       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06039    gettimeofday(&now, NULL);
06040    if (events & AST_IO_PRI) {
06041 #ifdef ZT_TIMERACK
06042       /* Great, this is a timing interface, just call the ioctl */
06043       if (ioctl(fd, ZT_TIMERACK, &x)) 
06044          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06045       res = 0;
06046 #endif      
06047    } else {
06048       /* Read and ignore from the pseudo channel for timing */
06049       res = read(fd, buf, sizeof(buf));
06050       if (res < 1) {
06051          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06052          return 1;
06053       }
06054    }
06055    /* For each peer that supports trunking... */
06056    ast_mutex_lock(&tpeerlock);
06057    tpeer = tpeers;
06058    while(tpeer) {
06059       processed++;
06060       res = 0;
06061       ast_mutex_lock(&tpeer->lock);
06062       /* We can drop a single tpeer per pass.  That makes all this logic
06063          substantially easier */
06064       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06065          /* Take it out of the list, but don't free it yet, because it
06066             could be in use */
06067          if (prev)
06068             prev->next = tpeer->next;
06069          else
06070             tpeers = tpeer->next;
06071          drop = tpeer;
06072       } else {
06073          res = send_trunk(tpeer, &now);
06074          if (iaxtrunkdebug)
06075             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(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
06076       }     
06077       totalcalls += res;   
06078       res = 0;
06079       ast_mutex_unlock(&tpeer->lock);
06080       prev = tpeer;
06081       tpeer = tpeer->next;
06082    }
06083    ast_mutex_unlock(&tpeerlock);
06084    if (drop) {
06085       ast_mutex_lock(&drop->lock);
06086       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06087          because by the time they could get tpeerlock, we've already grabbed it */
06088       ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06089       free(drop->trunkdata);
06090       ast_mutex_unlock(&drop->lock);
06091       ast_mutex_destroy(&drop->lock);
06092       free(drop);
06093       
06094    }
06095    if (iaxtrunkdebug)
06096       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06097    iaxtrunkdebug =0;
06098    return 1;
06099 }
06100 
06101 struct dpreq_data {
06102    int callno;
06103    char context[AST_MAX_EXTENSION];
06104    char callednum[AST_MAX_EXTENSION];
06105    char *callerid;
06106 };
06107 
06108 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06109 {
06110    unsigned short dpstatus = 0;
06111    struct iax_ie_data ied1;
06112    int mm;
06113 
06114    memset(&ied1, 0, sizeof(ied1));
06115    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06116    /* Must be started */
06117    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06118       dpstatus = IAX_DPSTATUS_EXISTS;
06119    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06120       dpstatus = IAX_DPSTATUS_CANEXIST;
06121    } else {
06122       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06123    }
06124    if (ast_ignore_pattern(context, callednum))
06125       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06126    if (mm)
06127       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06128    if (!skiplock)
06129       ast_mutex_lock(&iaxsl[callno]);
06130    if (iaxs[callno]) {
06131       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06132       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06133       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06134       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06135    }
06136    if (!skiplock)
06137       ast_mutex_unlock(&iaxsl[callno]);
06138 }
06139 
06140 static void *dp_lookup_thread(void *data)
06141 {
06142    /* Look up for dpreq */
06143    struct dpreq_data *dpr = data;
06144    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06145    if (dpr->callerid)
06146       free(dpr->callerid);
06147    free(dpr);
06148    return NULL;
06149 }
06150 
06151 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06152 {
06153    pthread_t newthread;
06154    struct dpreq_data *dpr;
06155    pthread_attr_t attr;
06156    
06157    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06158       return;
06159 
06160    pthread_attr_init(&attr);
06161    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06162 
06163    dpr->callno = callno;
06164    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06165    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06166    if (callerid)
06167       dpr->callerid = ast_strdup(callerid);
06168    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06169       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06170    }
06171 
06172    pthread_attr_destroy(&attr);
06173 }
06174 
06175 struct iax_dual {
06176    struct ast_channel *chan1;
06177    struct ast_channel *chan2;
06178 };
06179 
06180 static void *iax_park_thread(void *stuff)
06181 {
06182    struct ast_channel *chan1, *chan2;
06183    struct iax_dual *d;
06184    struct ast_frame *f;
06185    int ext;
06186    int res;
06187    d = stuff;
06188    chan1 = d->chan1;
06189    chan2 = d->chan2;
06190    free(d);
06191    f = ast_read(chan1);
06192    if (f)
06193       ast_frfree(f);
06194    res = ast_park_call(chan1, chan2, 0, &ext);
06195    ast_hangup(chan2);
06196    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06197    return NULL;
06198 }
06199 
06200 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06201 {
06202    struct iax_dual *d;
06203    struct ast_channel *chan1m, *chan2m;
06204    pthread_t th;
06205    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06206    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06207    if (chan2m && chan1m) {
06208       /* Make formats okay */
06209       chan1m->readformat = chan1->readformat;
06210       chan1m->writeformat = chan1->writeformat;
06211       ast_channel_masquerade(chan1m, chan1);
06212       /* Setup the extensions and such */
06213       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06214       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06215       chan1m->priority = chan1->priority;
06216       
06217       /* We make a clone of the peer channel too, so we can play
06218          back the announcement */
06219       /* Make formats okay */
06220       chan2m->readformat = chan2->readformat;
06221       chan2m->writeformat = chan2->writeformat;
06222       ast_channel_masquerade(chan2m, chan2);
06223       /* Setup the extensions and such */
06224       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06225       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06226       chan2m->priority = chan2->priority;
06227       if (ast_do_masquerade(chan2m)) {
06228          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06229          ast_hangup(chan2m);
06230          return -1;
06231       }
06232    } else {
06233       if (chan1m)
06234          ast_hangup(chan1m);
06235       if (chan2m)
06236          ast_hangup(chan2m);
06237       return -1;
06238    }
06239    if ((d = ast_calloc(1, sizeof(*d)))) {
06240       pthread_attr_t attr;
06241 
06242       pthread_attr_init(&attr);
06243       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06244 
06245       d->chan1 = chan1m;
06246       d->chan2 = chan2m;
06247       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06248          pthread_attr_destroy(&attr);
06249          return 0;
06250       }
06251       pthread_attr_destroy(&attr);
06252       free(d);
06253    }
06254    return -1;
06255 }
06256 
06257 
06258 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06259 
06260 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06261 {
06262    unsigned int ourver;
06263    char rsi[80];
06264    snprintf(rsi, sizeof(rsi), "si-%s", si);
06265    if (iax_provision_version(&ourver, rsi, 1))
06266       return 0;
06267    if (option_debug)
06268       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06269    if (ourver != ver) 
06270       iax2_provision(sin, sockfd, NULL, rsi, 1);
06271    return 0;
06272 }
06273 
06274 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06275 {
06276    jb_info stats;
06277    jb_getinfo(pvt->jb, &stats);
06278    
06279    memset(iep, 0, sizeof(*iep));
06280 
06281    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06282    if(stats.frames_in == 0) stats.frames_in = 1;
06283    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06284    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06285    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06286    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06287    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06288 }
06289 
06290 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06291 {
06292    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06293    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06294    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06295    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06296    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06297    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06298    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06299 }
06300 
06301 static int socket_process(struct iax2_thread *thread);
06302 
06303 /*!
06304  * \brief Handle any deferred full frames for this thread
06305  */
06306 static void handle_deferred_full_frames(struct iax2_thread *thread)
06307 {
06308    struct iax2_pkt_buf *pkt_buf;
06309 
06310    ast_mutex_lock(&thread->lock);
06311 
06312    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06313       ast_mutex_unlock(&thread->lock);
06314 
06315       thread->buf = pkt_buf->buf;
06316       thread->buf_len = pkt_buf->len;
06317       thread->buf_size = pkt_buf->len + 1;
06318       
06319       socket_process(thread);
06320 
06321       thread->buf = NULL;
06322       ast_free(pkt_buf);
06323 
06324       ast_mutex_lock(&thread->lock);
06325    }
06326 
06327    ast_mutex_unlock(&thread->lock);
06328 }
06329 
06330 /*!
06331  * \brief Queue the last read full frame for processing by a certain thread
06332  *
06333  * If there are already any full frames queued, they are sorted
06334  * by sequence number.
06335  */
06336 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06337 {
06338    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06339    struct ast_iax2_full_hdr *fh, *cur_fh;
06340 
06341    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06342       return;
06343 
06344    pkt_buf->len = from_here->buf_len;
06345    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06346 
06347    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06348    ast_mutex_lock(&to_here->lock);
06349    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06350       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06351       if (fh->oseqno < cur_fh->oseqno) {
06352          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06353          break;
06354       }
06355    }
06356    AST_LIST_TRAVERSE_SAFE_END
06357 
06358    if (!cur_pkt_buf)
06359       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06360    
06361    ast_mutex_unlock(&to_here->lock);
06362 }
06363 
06364 static int socket_read(int *id, int fd, short events, void *cbdata)
06365 {
06366    struct iax2_thread *thread;
06367    socklen_t len;
06368    time_t t;
06369    static time_t last_errtime = 0;
06370    struct ast_iax2_full_hdr *fh;
06371 
06372    if (!(thread = find_idle_thread())) {
06373       time(&t);
06374       if (t != last_errtime)
06375          ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
06376       last_errtime = t;
06377       usleep(1);
06378       return 1;
06379    }
06380 
06381    len = sizeof(thread->iosin);
06382    thread->iofd = fd;
06383    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06384    thread->buf_size = sizeof(thread->readbuf);
06385    thread->buf = thread->readbuf;
06386    if (thread->buf_len < 0) {
06387       if (errno != ECONNREFUSED && errno != EAGAIN)
06388          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06389       handle_error();
06390       thread->iostate = IAX_IOSTATE_IDLE;
06391       signal_condition(&thread->lock, &thread->cond);
06392       return 1;
06393    }
06394    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06395       thread->iostate = IAX_IOSTATE_IDLE;
06396       signal_condition(&thread->lock, &thread->cond);
06397       return 1;
06398    }
06399    
06400    /* Determine if this frame is a full frame; if so, and any thread is currently
06401       processing a full frame for the same callno from this peer, then drop this
06402       frame (and the peer will retransmit it) */
06403    fh = (struct ast_iax2_full_hdr *) thread->buf;
06404    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06405       struct iax2_thread *cur = NULL;
06406       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06407       
06408       AST_LIST_LOCK(&active_list);
06409       AST_LIST_TRAVERSE(&active_list, cur, list) {
06410          if ((cur->ffinfo.callno == callno) &&
06411              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06412             break;
06413       }
06414       if (cur) {
06415          /* we found another thread processing a full frame for this call,
06416             so queue it up for processing later. */
06417          defer_full_frame(thread, cur);
06418          AST_LIST_UNLOCK(&active_list);
06419          thread->iostate = IAX_IOSTATE_IDLE;
06420          signal_condition(&thread->lock, &thread->cond);
06421          return 1;
06422       } else {
06423          /* this thread is going to process this frame, so mark it */
06424          thread->ffinfo.callno = callno;
06425          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06426          thread->ffinfo.type = fh->type;
06427          thread->ffinfo.csub = fh->csub;
06428       }
06429       AST_LIST_UNLOCK(&active_list);
06430    }
06431    
06432    /* Mark as ready and send on its way */
06433    thread->iostate = IAX_IOSTATE_READY;
06434 #ifdef DEBUG_SCHED_MULTITHREAD
06435    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06436 #endif
06437    signal_condition(&thread->lock, &thread->cond);
06438 
06439    return 1;
06440 }
06441 
06442 static int socket_process(struct iax2_thread *thread)
06443 {
06444    struct sockaddr_in sin;
06445    int res;
06446    int updatehistory=1;
06447    int new = NEW_PREVENT;
06448    void *ptr;
06449    int dcallno = 0;
06450    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06451    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06452    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06453    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06454    struct ast_iax2_meta_trunk_hdr *mth;
06455    struct ast_iax2_meta_trunk_entry *mte;
06456    struct ast_iax2_meta_trunk_mini *mtm;
06457    struct iax_frame *fr;
06458    struct iax_frame *cur;
06459    struct ast_frame f = { 0, };
06460    struct ast_channel *c;
06461    struct iax2_dpcache *dp;
06462    struct iax2_peer *peer;
06463    struct iax2_trunk_peer *tpeer;
06464    struct timeval rxtrunktime;
06465    struct iax_ies ies;
06466    struct iax_ie_data ied0, ied1;
06467    int format;
06468    int fd;
06469    int exists;
06470    int minivid = 0;
06471    unsigned int ts;
06472    char empty[32]="";      /* Safety measure */
06473    struct iax_frame *duped_fr;
06474    char host_pref_buf[128];
06475    char caller_pref_buf[128];
06476    struct ast_codec_pref pref;
06477    char *using_prefs = "mine";
06478 
06479    /* allocate an iax_frame with 4096 bytes of data buffer */
06480    fr = alloca(sizeof(*fr) + 4096);
06481    fr->callno = 0;
06482    fr->afdatalen = 4096; /* From alloca() above */
06483 
06484    /* Copy frequently used parameters to the stack */
06485    res = thread->buf_len;
06486    fd = thread->iofd;
06487    memcpy(&sin, &thread->iosin, sizeof(sin));
06488 
06489    if (res < sizeof(*mh)) {
06490       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06491       return 1;
06492    }
06493    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06494       if (res < sizeof(*vh)) {
06495          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06496          return 1;
06497       }
06498 
06499       /* This is a video frame, get call number */
06500       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06501       minivid = 1;
06502    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06503       unsigned char metatype;
06504 
06505       if (res < sizeof(*meta)) {
06506          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06507          return 1;
06508       }
06509 
06510       /* This is a meta header */
06511       switch(meta->metacmd) {
06512       case IAX_META_TRUNK:
06513          if (res < (sizeof(*meta) + sizeof(*mth))) {
06514             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06515                sizeof(*meta) + sizeof(*mth));
06516             return 1;
06517          }
06518          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06519          ts = ntohl(mth->ts);
06520          metatype = meta->cmddata;
06521          res -= (sizeof(*meta) + sizeof(*mth));
06522          ptr = mth->data;
06523          tpeer = find_tpeer(&sin, fd);
06524          if (!tpeer) {
06525             ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06526             return 1;
06527          }
06528          tpeer->trunkact = ast_tvnow();
06529          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06530             tpeer->rxtrunktime = tpeer->trunkact;
06531          rxtrunktime = tpeer->rxtrunktime;
06532          ast_mutex_unlock(&tpeer->lock);
06533          while(res >= sizeof(*mte)) {
06534             /* Process channels */
06535             unsigned short callno, trunked_ts, len;
06536 
06537             if (metatype == IAX_META_TRUNK_MINI) {
06538                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06539                ptr += sizeof(*mtm);
06540                res -= sizeof(*mtm);
06541                len = ntohs(mtm->len);
06542                callno = ntohs(mtm->mini.callno);
06543                trunked_ts = ntohs(mtm->mini.ts);
06544             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06545                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06546                ptr += sizeof(*mte);
06547                res -= sizeof(*mte);
06548                len = ntohs(mte->len);
06549                callno = ntohs(mte->callno);
06550                trunked_ts = 0;
06551             } else {
06552                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06553                break;
06554             }
06555             /* Stop if we don't have enough data */
06556             if (len > res)
06557                break;
06558             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06559             if (fr->callno) {
06560                ast_mutex_lock(&iaxsl[fr->callno]);
06561                /* If it's a valid call, deliver the contents.  If not, we
06562                   drop it, since we don't have a scallno to use for an INVAL */
06563                /* Process as a mini frame */
06564                memset(&f, 0, sizeof(f));
06565                f.frametype = AST_FRAME_VOICE;
06566                if (iaxs[fr->callno]) {
06567                   if (iaxs[fr->callno]->voiceformat > 0) {
06568                      f.subclass = iaxs[fr->callno]->voiceformat;
06569                      f.datalen = len;
06570                      if (f.datalen >= 0) {
06571                         if (f.datalen)
06572                            f.data = ptr;
06573                         if(trunked_ts) {
06574                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06575                         } else
06576                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06577                         /* Don't pass any packets until we're started */
06578                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06579                            /* Common things */
06580                            f.src = "IAX2";
06581                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06582                               f.samples = ast_codec_get_samples(&f);
06583                            iax_frame_wrap(fr, &f);
06584                            duped_fr = iaxfrdup2(fr);
06585                            if (duped_fr) {
06586                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06587                            }
06588                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
06589                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06590                               iaxs[fr->callno]->last = fr->ts;
06591 #if 1
06592                               if (option_debug && iaxdebug)
06593                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06594 #endif
06595                            }
06596                         }
06597                      } else {
06598                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06599                      }
06600                   } else {
06601                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06602                      iax2_vnak(fr->callno);
06603                   }
06604                }
06605                ast_mutex_unlock(&iaxsl[fr->callno]);
06606             }
06607             ptr += len;
06608             res -= len;
06609          }
06610          
06611       }
06612       return 1;
06613    }
06614 
06615 #ifdef DEBUG_SUPPORT
06616    if (iaxdebug && (res >= sizeof(*fh)))
06617       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06618 #endif
06619    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06620       if (res < sizeof(*fh)) {
06621          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06622          return 1;
06623       }
06624 
06625       /* Get the destination call number */
06626       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06627       /* Retrieve the type and subclass */
06628       f.frametype = fh->type;
06629       if (f.frametype == AST_FRAME_VIDEO) {
06630          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06631       } else {
06632          f.subclass = uncompress_subclass(fh->csub);
06633       }
06634       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06635                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06636                          (f.subclass == IAX_COMMAND_REGREL)))
06637          new = NEW_ALLOW;
06638    } else {
06639       /* Don't know anything about it yet */
06640       f.frametype = AST_FRAME_NULL;
06641       f.subclass = 0;
06642    }
06643 
06644    if (!fr->callno)
06645       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06646 
06647    if (fr->callno > 0)
06648       ast_mutex_lock(&iaxsl[fr->callno]);
06649 
06650    if (!fr->callno || !iaxs[fr->callno]) {
06651       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06652          frame, reply with an inval */
06653       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06654          /* We can only raw hangup control frames */
06655          if (((f.subclass != IAX_COMMAND_INVAL) &&
06656              (f.subclass != IAX_COMMAND_TXCNT) &&
06657              (f.subclass != IAX_COMMAND_TXACC) &&
06658              (f.subclass != IAX_COMMAND_FWDOWNL))||
06659              (f.frametype != AST_FRAME_IAX))
06660             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06661             fd);
06662       }
06663       if (fr->callno > 0) 
06664          ast_mutex_unlock(&iaxsl[fr->callno]);
06665       return 1;
06666    }
06667    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06668       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06669          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06670          ast_mutex_unlock(&iaxsl[fr->callno]);
06671          return 1;
06672       }
06673 #ifdef DEBUG_SUPPORT
06674       else if (iaxdebug)
06675          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06676 #endif
06677    }
06678 
06679    /* count this frame */
06680    iaxs[fr->callno]->frames_received++;
06681 
06682    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06683       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06684       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06685       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06686    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06687       if (option_debug  && iaxdebug)
06688          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06689       /* Check if it's out of order (and not an ACK or INVAL) */
06690       fr->oseqno = fh->oseqno;
06691       fr->iseqno = fh->iseqno;
06692       fr->ts = ntohl(fh->ts);
06693 #ifdef IAXTESTS
06694       if (test_resync) {
06695          if (option_debug)
06696             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06697          fr->ts += test_resync;
06698       }
06699 #endif /* IAXTESTS */
06700 #if 0
06701       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06702            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06703                         (f.subclass == IAX_COMMAND_NEW ||
06704                          f.subclass == IAX_COMMAND_AUTHREQ ||
06705                          f.subclass == IAX_COMMAND_ACCEPT ||
06706                          f.subclass == IAX_COMMAND_REJECT))      ) )
06707 #endif
06708       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06709          updatehistory = 0;
06710       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06711          (iaxs[fr->callno]->iseqno ||
06712             ((f.subclass != IAX_COMMAND_TXCNT) &&
06713             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06714             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06715             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06716             (f.subclass != IAX_COMMAND_TXACC)) ||
06717             (f.frametype != AST_FRAME_IAX))) {
06718          if (
06719           ((f.subclass != IAX_COMMAND_ACK) &&
06720            (f.subclass != IAX_COMMAND_INVAL) &&
06721            (f.subclass != IAX_COMMAND_TXCNT) &&
06722            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06723            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06724            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06725            (f.subclass != IAX_COMMAND_TXACC) &&
06726            (f.subclass != IAX_COMMAND_VNAK)) ||
06727            (f.frametype != AST_FRAME_IAX)) {
06728             /* If it's not an ACK packet, it's out of order. */
06729             if (option_debug)
06730                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06731                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06732             /* Check to see if we need to request retransmission,
06733              * and take sequence number wraparound into account */
06734             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
06735                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06736                if ((f.frametype != AST_FRAME_IAX) || 
06737                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06738                   if (option_debug)
06739                      ast_log(LOG_DEBUG, "Acking anyway\n");
06740                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06741                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06742                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06743                }
06744             } else {
06745                /* Send a VNAK requesting retransmission */
06746                iax2_vnak(fr->callno);
06747             }
06748             ast_mutex_unlock(&iaxsl[fr->callno]);
06749             return 1;
06750          }
06751       } else {
06752          /* Increment unless it's an ACK or VNAK */
06753          if (((f.subclass != IAX_COMMAND_ACK) &&
06754              (f.subclass != IAX_COMMAND_INVAL) &&
06755              (f.subclass != IAX_COMMAND_TXCNT) &&
06756              (f.subclass != IAX_COMMAND_TXACC) &&
06757             (f.subclass != IAX_COMMAND_VNAK)) ||
06758              (f.frametype != AST_FRAME_IAX))
06759             iaxs[fr->callno]->iseqno++;
06760       }
06761       /* A full frame */
06762       if (res < sizeof(*fh)) {
06763          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06764          ast_mutex_unlock(&iaxsl[fr->callno]);
06765          return 1;
06766       }
06767       /* Ensure text frames are NULL-terminated */
06768       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
06769          if (res < thread->buf_size)
06770             thread->buf[res++] = '\0';
06771          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
06772             thread->buf[res - 1] = '\0';
06773       }
06774       f.datalen = res - sizeof(*fh);
06775 
06776       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
06777          from the real peer, not the transfer peer */
06778       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06779           ((f.subclass != IAX_COMMAND_INVAL) ||
06780            (f.frametype != AST_FRAME_IAX))) {
06781          unsigned char x;
06782          int call_to_destroy;
06783          /* XXX This code is not very efficient.  Surely there is a better way which still
06784                 properly handles boundary conditions? XXX */
06785          /* First we have to qualify that the ACKed value is within our window */
06786          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
06787             if (fr->iseqno == x)
06788                break;
06789          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
06790             /* The acknowledgement is within our window.  Time to acknowledge everything
06791                that it says to */
06792             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
06793                /* Ack the packet with the given timestamp */
06794                if (option_debug && iaxdebug)
06795                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06796                call_to_destroy = 0;
06797                AST_LIST_LOCK(&iaxq.queue);
06798                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06799                   /* If it's our call, and our timestamp, mark -1 retries */
06800                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
06801                      cur->retries = -1;
06802                      /* Destroy call if this is the end */
06803                      if (cur->final)
06804                         call_to_destroy = fr->callno;
06805                   }
06806                }
06807                AST_LIST_UNLOCK(&iaxq.queue);
06808                if (call_to_destroy) {
06809                   if (iaxdebug && option_debug)
06810                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
06811                   iax2_destroy(call_to_destroy);
06812                }
06813             }
06814             /* Note how much we've received acknowledgement for */
06815             if (iaxs[fr->callno])
06816                iaxs[fr->callno]->rseqno = fr->iseqno;
06817             else {
06818                /* Stop processing now */
06819                ast_mutex_unlock(&iaxsl[fr->callno]);
06820                return 1;
06821             }
06822          } else
06823             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
06824       }
06825       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06826          ((f.frametype != AST_FRAME_IAX) || 
06827           ((f.subclass != IAX_COMMAND_TXACC) &&
06828            (f.subclass != IAX_COMMAND_TXCNT)))) {
06829          /* Only messages we accept from a transfer host are TXACC and TXCNT */
06830          ast_mutex_unlock(&iaxsl[fr->callno]);
06831          return 1;
06832       }
06833 
06834       if (f.datalen) {
06835          if (f.frametype == AST_FRAME_IAX) {
06836             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
06837                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
06838                ast_mutex_unlock(&iaxsl[fr->callno]);
06839                return 1;
06840             }
06841             f.data = NULL;
06842             f.datalen = 0;
06843          } else
06844             f.data = thread->buf + sizeof(*fh);
06845       } else {
06846          if (f.frametype == AST_FRAME_IAX)
06847             f.data = NULL;
06848          else
06849             f.data = empty;
06850          memset(&ies, 0, sizeof(ies));
06851       }
06852 
06853       /* when we receive the first full frame for a new incoming channel,
06854          it is safe to start the PBX on the channel because we have now
06855          completed a 3-way handshake with the peer */
06856       if ((f.frametype == AST_FRAME_VOICE) ||
06857           (f.frametype == AST_FRAME_VIDEO) ||
06858           (f.frametype == AST_FRAME_IAX)) {
06859          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
06860             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
06861             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
06862                ast_mutex_unlock(&iaxsl[fr->callno]);
06863                return 1;
06864             }
06865          }
06866       }
06867 
06868       if (f.frametype == AST_FRAME_VOICE) {
06869          if (f.subclass != iaxs[fr->callno]->voiceformat) {
06870                iaxs[fr->callno]->voiceformat = f.subclass;
06871                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06872                if (iaxs[fr->callno]->owner) {
06873                   int orignative;
06874 retryowner:
06875                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
06876                      ast_mutex_unlock(&iaxsl[fr->callno]);
06877                      usleep(1);
06878                      ast_mutex_lock(&iaxsl[fr->callno]);
06879                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
06880                   }
06881                   if (iaxs[fr->callno]) {
06882                      if (iaxs[fr->callno]->owner) {
06883                         orignative = iaxs[fr->callno]->owner->nativeformats;
06884                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
06885                         if (iaxs[fr->callno]->owner->readformat)
06886                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
06887                         iaxs[fr->callno]->owner->nativeformats = orignative;
06888                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
06889                      }
06890                   } else {
06891                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06892                      ast_mutex_unlock(&iaxsl[fr->callno]);
06893                      return 1;
06894                   }
06895                }
06896          }
06897       }
06898       if (f.frametype == AST_FRAME_VIDEO) {
06899          if (f.subclass != iaxs[fr->callno]->videoformat) {
06900             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06901             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
06902          }
06903       }
06904       if (f.frametype == AST_FRAME_IAX) {
06905          if (iaxs[fr->callno]->initid > -1) {
06906             /* Don't auto congest anymore since we've gotten something usefulb ack */
06907             ast_sched_del(sched, iaxs[fr->callno]->initid);
06908             iaxs[fr->callno]->initid = -1;
06909          }
06910          /* Handle the IAX pseudo frame itself */
06911          if (option_debug && iaxdebug)
06912             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06913 
06914                         /* Update last ts unless the frame's timestamp originated with us. */
06915          if (iaxs[fr->callno]->last < fr->ts &&
06916                             f.subclass != IAX_COMMAND_ACK &&
06917                             f.subclass != IAX_COMMAND_PONG &&
06918                             f.subclass != IAX_COMMAND_LAGRP) {
06919             iaxs[fr->callno]->last = fr->ts;
06920             if (option_debug && iaxdebug)
06921                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06922          }
06923 
06924          switch(f.subclass) {
06925          case IAX_COMMAND_ACK:
06926             /* Do nothing */
06927             break;
06928          case IAX_COMMAND_QUELCH:
06929             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06930                     /* Generate Manager Hold event, if necessary*/
06931                if (iaxs[fr->callno]->owner) {
06932                   manager_event(EVENT_FLAG_CALL, "Hold",
06933                      "Channel: %s\r\n"
06934                      "Uniqueid: %s\r\n",
06935                      iaxs[fr->callno]->owner->name, 
06936                      iaxs[fr->callno]->owner->uniqueid);
06937                }
06938 
06939                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
06940                if (ies.musiconhold) {
06941                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
06942                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
06943                      ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD, 
06944                         S_OR(mohsuggest, NULL),
06945                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
06946                   }
06947                }
06948             }
06949             break;
06950          case IAX_COMMAND_UNQUELCH:
06951             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06952                     /* Generate Manager Unhold event, if necessary*/
06953                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
06954                   manager_event(EVENT_FLAG_CALL, "Unhold",
06955                      "Channel: %s\r\n"
06956                      "Uniqueid: %s\r\n",
06957                      iaxs[fr->callno]->owner->name, 
06958                      iaxs[fr->callno]->owner->uniqueid);
06959                }
06960 
06961                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
06962                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner))
06963                   ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD);
06964             }
06965             break;
06966          case IAX_COMMAND_TXACC:
06967             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
06968                /* Ack the packet with the given timestamp */
06969                AST_LIST_LOCK(&iaxq.queue);
06970                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06971                   /* Cancel any outstanding txcnt's */
06972                   if ((fr->callno == cur->callno) && (cur->transfer))
06973                      cur->retries = -1;
06974                }
06975                AST_LIST_UNLOCK(&iaxq.queue);
06976                memset(&ied1, 0, sizeof(ied1));
06977                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
06978                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06979                iaxs[fr->callno]->transferring = TRANSFER_READY;
06980             }
06981             break;
06982          case IAX_COMMAND_NEW:
06983             /* Ignore if it's already up */
06984             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06985                break;
06986             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06987                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06988             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
06989             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
06990                int new_callno;
06991                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
06992                   fr->callno = new_callno;
06993             }
06994             /* For security, always ack immediately */
06995             if (delayreject)
06996                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06997             if (check_access(fr->callno, &sin, &ies)) {
06998                /* They're not allowed on */
06999                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07000                if (authdebug)
07001                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07002                break;
07003             }
07004             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07005                const char *context, *exten, *cid_num;
07006 
07007                context = ast_strdupa(iaxs[fr->callno]->context);
07008                exten = ast_strdupa(iaxs[fr->callno]->exten);
07009                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07010 
07011                /* This might re-enter the IAX code and need the lock */
07012                ast_mutex_unlock(&iaxsl[fr->callno]);
07013                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07014                ast_mutex_lock(&iaxsl[fr->callno]);
07015 
07016                if (!iaxs[fr->callno]) {
07017                   ast_mutex_unlock(&iaxsl[fr->callno]);
07018                   return 1;
07019                }
07020             } else
07021                exists = 0;
07022             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07023                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07024                   memset(&ied0, 0, sizeof(ied0));
07025                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07026                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07027                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07028                   if (authdebug)
07029                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07030                } else {
07031                   /* Select an appropriate format */
07032 
07033                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07034                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07035                         using_prefs = "reqonly";
07036                      } else {
07037                         using_prefs = "disabled";
07038                      }
07039                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07040                      memset(&pref, 0, sizeof(pref));
07041                      strcpy(caller_pref_buf, "disabled");
07042                      strcpy(host_pref_buf, "disabled");
07043                   } else {
07044                      using_prefs = "mine";
07045                      /* If the information elements are in here... use them */
07046                      if (ies.codec_prefs)
07047                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07048                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07049                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07050                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07051                            pref = iaxs[fr->callno]->rprefs;
07052                            using_prefs = "caller";
07053                         } else {
07054                            pref = iaxs[fr->callno]->prefs;
07055                         }
07056                      } else
07057                         pref = iaxs[fr->callno]->prefs;
07058                      
07059                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07060                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07061                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07062                   }
07063                   if (!format) {
07064                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07065                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07066                      if (!format) {
07067                         memset(&ied0, 0, sizeof(ied0));
07068                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07069                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07070                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07071                         if (authdebug) {
07072                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07073                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07074                            else 
07075                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07076                         }
07077                      } else {
07078                         /* Pick one... */
07079                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07080                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07081                               format = 0;
07082                         } else {
07083                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07084                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07085                               memset(&pref, 0, sizeof(pref));
07086                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07087                               strcpy(caller_pref_buf,"disabled");
07088                               strcpy(host_pref_buf,"disabled");
07089                            } else {
07090                               using_prefs = "mine";
07091                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07092                                  /* Do the opposite of what we tried above. */
07093                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07094                                     pref = iaxs[fr->callno]->prefs;                       
07095                                  } else {
07096                                     pref = iaxs[fr->callno]->rprefs;
07097                                     using_prefs = "caller";
07098                                  }
07099                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07100                            
07101                               } else /* if no codec_prefs IE do it the old way */
07102                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07103                            }
07104                         }
07105 
07106                         if (!format) {
07107                            memset(&ied0, 0, sizeof(ied0));
07108                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07109                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07110                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07111                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07112                            if (authdebug)
07113                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07114                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07115                            break;
07116                         }
07117                      }
07118                   }
07119                   if (format) {
07120                      /* No authentication required, let them in */
07121                      memset(&ied1, 0, sizeof(ied1));
07122                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07123                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07124                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07125                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07126                         if (option_verbose > 2) 
07127                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07128                                     "%srequested format = %s,\n"
07129                                     "%srequested prefs = %s,\n"
07130                                     "%sactual format = %s,\n"
07131                                     "%shost prefs = %s,\n"
07132                                     "%spriority = %s\n",
07133                                     ast_inet_ntoa(sin.sin_addr), 
07134                                     VERBOSE_PREFIX_4,
07135                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07136                                     VERBOSE_PREFIX_4,
07137                                     caller_pref_buf,
07138                                     VERBOSE_PREFIX_4,
07139                                     ast_getformatname(format), 
07140                                     VERBOSE_PREFIX_4,
07141                                     host_pref_buf, 
07142                                     VERBOSE_PREFIX_4,
07143                                     using_prefs);
07144                         
07145                         iaxs[fr->callno]->chosenformat = format;
07146                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07147                      } else {
07148                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07149                         /* If this is a TBD call, we're ready but now what...  */
07150                         if (option_verbose > 2)
07151                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07152                      }
07153                   }
07154                }
07155                break;
07156             }
07157             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07158                merge_encryption(iaxs[fr->callno],ies.encmethods);
07159             else
07160                iaxs[fr->callno]->encmethods = 0;
07161             if (!authenticate_request(iaxs[fr->callno]))
07162                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07163             break;
07164          case IAX_COMMAND_DPREQ:
07165             /* Request status in the dialplan */
07166             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07167                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07168                if (iaxcompat) {
07169                   /* Spawn a thread for the lookup */
07170                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07171                } else {
07172                   /* Just look it up */
07173                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07174                }
07175             }
07176             break;
07177          case IAX_COMMAND_HANGUP:
07178             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07179             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07180             /* Set hangup cause according to remote */
07181             if (ies.causecode && iaxs[fr->callno]->owner)
07182                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07183             /* Send ack immediately, before we destroy */
07184             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07185             iax2_destroy(fr->callno);
07186             break;
07187          case IAX_COMMAND_REJECT:
07188             /* Set hangup cause according to remote */
07189             if (ies.causecode && iaxs[fr->callno]->owner)
07190                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07191 
07192             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07193                if (iaxs[fr->callno]->owner && authdebug)
07194                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07195                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07196                      ies.cause ? ies.cause : "<Unknown>");
07197                ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07198                   fr->callno);
07199             }
07200             /* Send ack immediately, before we destroy */
07201             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07202                          fr->ts, NULL, 0, fr->iseqno);
07203             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07204                iaxs[fr->callno]->error = EPERM;
07205             iax2_destroy(fr->callno);
07206             break;
07207          case IAX_COMMAND_TRANSFER:
07208             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07209                /* Set BLINDTRANSFER channel variables */
07210                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07211                pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07212                if (!strcmp(ies.called_number, ast_parking_ext())) {
07213                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07214                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07215                   } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
07216                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07217                } else {
07218                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07219                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07220                         ies.called_number, iaxs[fr->callno]->context);
07221                   else
07222                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07223                         ies.called_number, iaxs[fr->callno]->context);
07224                }
07225             } else
07226                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07227             break;
07228          case IAX_COMMAND_ACCEPT:
07229             /* Ignore if call is already up or needs authentication or is a TBD */
07230             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07231                break;
07232             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07233                /* Send ack immediately, before we destroy */
07234                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07235                iax2_destroy(fr->callno);
07236                break;
07237             }
07238             if (ies.format) {
07239                iaxs[fr->callno]->peerformat = ies.format;
07240             } else {
07241                if (iaxs[fr->callno]->owner)
07242                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07243                else
07244                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07245             }
07246             if (option_verbose > 2)
07247                ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
07248             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07249                memset(&ied0, 0, sizeof(ied0));
07250                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07251                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07252                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07253                if (authdebug)
07254                   ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07255             } else {
07256                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07257                if (iaxs[fr->callno]->owner) {
07258                   /* Switch us to use a compatible format */
07259                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07260                   if (option_verbose > 2)
07261                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07262 retryowner2:
07263                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07264                      ast_mutex_unlock(&iaxsl[fr->callno]);
07265                      usleep(1);
07266                      ast_mutex_lock(&iaxsl[fr->callno]);
07267                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07268                   }
07269                   
07270                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07271                      /* Setup read/write formats properly. */
07272                      if (iaxs[fr->callno]->owner->writeformat)
07273                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07274                      if (iaxs[fr->callno]->owner->readformat)
07275                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07276                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07277                   }
07278                }
07279             }
07280             if (iaxs[fr->callno]) {
07281                ast_mutex_lock(&dpcache_lock);
07282                dp = iaxs[fr->callno]->dpentries;
07283                while(dp) {
07284                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07285                      iax2_dprequest(dp, fr->callno);
07286                   }
07287                   dp = dp->peer;
07288                }
07289                ast_mutex_unlock(&dpcache_lock);
07290             }
07291             break;
07292          case IAX_COMMAND_POKE:
07293             /* Send back a pong packet with the original timestamp */
07294             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07295             break;
07296          case IAX_COMMAND_PING:
07297          {
07298             struct iax_ie_data pingied;
07299             construct_rr(iaxs[fr->callno], &pingied);
07300             /* Send back a pong packet with the original timestamp */
07301             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07302          }
07303             break;
07304          case IAX_COMMAND_PONG:
07305             /* Calculate ping time */
07306             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07307             /* save RR info */
07308             save_rr(fr, &ies);
07309 
07310             if (iaxs[fr->callno]->peerpoke) {
07311                peer = iaxs[fr->callno]->peerpoke;
07312                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07313                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07314                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07315                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07316                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07317                   }
07318                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07319                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07320                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07321                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07322                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07323                   }
07324                }
07325                peer->lastms = iaxs[fr->callno]->pingtime;
07326                if (peer->smoothing && (peer->lastms > -1))
07327                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07328                else if (peer->smoothing && peer->lastms < 0)
07329                   peer->historicms = (0 + peer->historicms) / 2;
07330                else              
07331                   peer->historicms = iaxs[fr->callno]->pingtime;
07332 
07333                /* Remove scheduled iax2_poke_noanswer */
07334                if (peer->pokeexpire > -1)
07335                   ast_sched_del(sched, peer->pokeexpire);
07336                /* Schedule the next cycle */
07337                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07338                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07339                else
07340                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07341                /* and finally send the ack */
07342                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07343                /* And wrap up the qualify call */
07344                iax2_destroy(fr->callno);
07345                peer->callno = 0;
07346                if (option_debug)
07347                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07348             }
07349             break;
07350          case IAX_COMMAND_LAGRQ:
07351          case IAX_COMMAND_LAGRP:
07352             f.src = "LAGRQ";
07353             f.mallocd = 0;
07354             f.offset = 0;
07355             f.samples = 0;
07356             iax_frame_wrap(fr, &f);
07357             if(f.subclass == IAX_COMMAND_LAGRQ) {
07358                /* Received a LAGRQ - echo back a LAGRP */
07359                fr->af.subclass = IAX_COMMAND_LAGRP;
07360                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07361             } else {
07362                /* Received LAGRP in response to our LAGRQ */
07363                unsigned int ts;
07364                /* This is a reply we've been given, actually measure the difference */
07365                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07366                iaxs[fr->callno]->lag = ts - fr->ts;
07367                if (option_debug && iaxdebug)
07368                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07369                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07370             }
07371             break;
07372          case IAX_COMMAND_AUTHREQ:
07373             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07374                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>");
07375                break;
07376             }
07377             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07378                ast_log(LOG_WARNING, 
07379                   "I don't know how to authenticate %s to %s\n", 
07380                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07381             }
07382             break;
07383          case IAX_COMMAND_AUTHREP:
07384             /* For security, always ack immediately */
07385             if (delayreject)
07386                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07387             /* Ignore once we've started */
07388             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07389                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>");
07390                break;
07391             }
07392             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07393                if (authdebug)
07394                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
07395                memset(&ied0, 0, sizeof(ied0));
07396                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07397                break;
07398             }
07399             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07400                /* This might re-enter the IAX code and need the lock */
07401                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07402             } else
07403                exists = 0;
07404             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07405                if (authdebug)
07406                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07407                memset(&ied0, 0, sizeof(ied0));
07408                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07409                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07410                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07411             } else {
07412                /* Select an appropriate format */
07413                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07414                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07415                      using_prefs = "reqonly";
07416                   } else {
07417                      using_prefs = "disabled";
07418                   }
07419                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07420                   memset(&pref, 0, sizeof(pref));
07421                   strcpy(caller_pref_buf, "disabled");
07422                   strcpy(host_pref_buf, "disabled");
07423                } else {
07424                   using_prefs = "mine";
07425                   if (ies.codec_prefs)
07426                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07427                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07428                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07429                         pref = iaxs[fr->callno]->rprefs;
07430                         using_prefs = "caller";
07431                      } else {
07432                         pref = iaxs[fr->callno]->prefs;
07433                      }
07434                   } else /* if no codec_prefs IE do it the old way */
07435                      pref = iaxs[fr->callno]->prefs;
07436                
07437                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07438                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07439                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07440                }
07441                if (!format) {
07442                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07443                      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);
07444                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07445                   }
07446                   if (!format) {
07447                      if (authdebug) {
07448                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07449                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07450                         else
07451                            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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07452                      }
07453                      memset(&ied0, 0, sizeof(ied0));
07454                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07455                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07456                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07457                   } else {
07458                      /* Pick one... */
07459                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07460                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07461                            format = 0;
07462                      } else {
07463                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07464                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07465                            memset(&pref, 0, sizeof(pref));
07466                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07467                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07468                            strcpy(caller_pref_buf,"disabled");
07469                            strcpy(host_pref_buf,"disabled");
07470                         } else {
07471                            using_prefs = "mine";
07472                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07473                               /* Do the opposite of what we tried above. */
07474                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07475                                  pref = iaxs[fr->callno]->prefs;                 
07476                               } else {
07477                                  pref = iaxs[fr->callno]->rprefs;
07478                                  using_prefs = "caller";
07479                               }
07480                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07481                            } else /* if no codec_prefs IE do it the old way */
07482                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07483                         }
07484                      }
07485                      if (!format) {
07486                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07487                         if (authdebug) {
07488                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07489                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07490                            else
07491                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07492                         }
07493                         memset(&ied0, 0, sizeof(ied0));
07494                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07495                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07496                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07497                      }
07498                   }
07499                }
07500                if (format) {
07501                   /* Authentication received */
07502                   memset(&ied1, 0, sizeof(ied1));
07503                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07504                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07505                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07506                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07507                      if (option_verbose > 2) 
07508                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07509                                  "%srequested format = %s,\n"
07510                                  "%srequested prefs = %s,\n"
07511                                  "%sactual format = %s,\n"
07512                                  "%shost prefs = %s,\n"
07513                                  "%spriority = %s\n", 
07514                                  ast_inet_ntoa(sin.sin_addr), 
07515                                  VERBOSE_PREFIX_4,
07516                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07517                                  VERBOSE_PREFIX_4,
07518                                  caller_pref_buf,
07519                                  VERBOSE_PREFIX_4,
07520                                  ast_getformatname(format),
07521                                  VERBOSE_PREFIX_4,
07522                                  host_pref_buf,
07523                                  VERBOSE_PREFIX_4,
07524                                  using_prefs);
07525 
07526                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07527                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07528                         iax2_destroy(fr->callno);
07529                   } else {
07530                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07531                      /* If this is a TBD call, we're ready but now what...  */
07532                      if (option_verbose > 2)
07533                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07534                   }
07535                }
07536             }
07537             break;
07538          case IAX_COMMAND_DIAL:
07539             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07540                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07541                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07542                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07543                   if (authdebug)
07544                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07545                   memset(&ied0, 0, sizeof(ied0));
07546                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07547                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07548                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07549                } else {
07550                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07551                   if (option_verbose > 2) 
07552                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
07553                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07554                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07555                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07556                      iax2_destroy(fr->callno);
07557                }
07558             }
07559             break;
07560          case IAX_COMMAND_INVAL:
07561             iaxs[fr->callno]->error = ENOTCONN;
07562             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07563             iax2_destroy(fr->callno);
07564             if (option_debug)
07565                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07566             break;
07567          case IAX_COMMAND_VNAK:
07568             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07569             /* Force retransmission */
07570             vnak_retransmit(fr->callno, fr->iseqno);
07571             break;
07572          case IAX_COMMAND_REGREQ:
07573          case IAX_COMMAND_REGREL:
07574             /* For security, always ack immediately */
07575             if (delayreject)
07576                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07577             if (register_verify(fr->callno, &sin, &ies)) {
07578                /* Send delayed failure */
07579                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07580                break;
07581             }
07582             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
07583                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
07584                if (f.subclass == IAX_COMMAND_REGREL)
07585                   memset(&sin, 0, sizeof(sin));
07586                if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
07587                   ast_log(LOG_WARNING, "Registry error\n");
07588                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07589                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07590                break;
07591             }
07592             registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
07593             break;
07594          case IAX_COMMAND_REGACK:
07595             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
07596                ast_log(LOG_WARNING, "Registration failure\n");
07597             /* Send ack immediately, before we destroy */
07598             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07599             iax2_destroy(fr->callno);
07600             break;
07601          case IAX_COMMAND_REGREJ:
07602             if (iaxs[fr->callno]->reg) {
07603                if (authdebug) {
07604                   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(sin.sin_addr));
07605                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
07606                }
07607                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07608             }
07609             /* Send ack immediately, before we destroy */
07610             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07611             iax2_destroy(fr->callno);
07612             break;
07613          case IAX_COMMAND_REGAUTH:
07614             /* Authentication request */
07615             if (registry_rerequest(&ies, fr->callno, &sin)) {
07616                memset(&ied0, 0, sizeof(ied0));
07617                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07618                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07619                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07620             }
07621             break;
07622          case IAX_COMMAND_TXREJ:
07623             iaxs[fr->callno]->transferring = 0;
07624             if (option_verbose > 2) 
07625                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07626             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07627             if (iaxs[fr->callno]->bridgecallno) {
07628                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07629                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07630                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07631                }
07632             }
07633             break;
07634          case IAX_COMMAND_TXREADY:
07635             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
07636                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
07637                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
07638                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
07639                else
07640                   iaxs[fr->callno]->transferring = TRANSFER_READY;
07641                if (option_verbose > 2) 
07642                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07643                if (iaxs[fr->callno]->bridgecallno) {
07644                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
07645                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
07646                      /* They're both ready, now release them. */
07647                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
07648                         if (option_verbose > 2) 
07649                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07650                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07651 
07652                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
07653                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
07654 
07655                         memset(&ied0, 0, sizeof(ied0));
07656                         memset(&ied1, 0, sizeof(ied1));
07657                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07658                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07659                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
07660                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
07661                      } else {
07662                         if (option_verbose > 2) 
07663                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07664                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07665 
07666                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07667                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07668                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07669                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07670 
07671                         /* Stop doing lag & ping requests */
07672                         stop_stuff(fr->callno);
07673                         stop_stuff(iaxs[fr->callno]->bridgecallno);
07674 
07675                         memset(&ied0, 0, sizeof(ied0));
07676                         memset(&ied1, 0, sizeof(ied1));
07677                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07678                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07679                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07680                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07681                      }
07682 
07683                   }
07684                }
07685             }
07686             break;
07687          case IAX_COMMAND_TXREQ:
07688             try_transfer(iaxs[fr->callno], &ies);
07689             break;
07690          case IAX_COMMAND_TXCNT:
07691             if (iaxs[fr->callno]->transferring)
07692                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07693             break;
07694          case IAX_COMMAND_TXREL:
07695             /* Send ack immediately, rather than waiting until we've changed addresses */
07696             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07697             complete_transfer(fr->callno, &ies);
07698             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
07699             break;   
07700          case IAX_COMMAND_TXMEDIA:
07701             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
07702                                         AST_LIST_LOCK(&iaxq.queue);
07703                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07704                                                 /* Cancel any outstanding frames and start anew */
07705                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
07706                                                         cur->retries = -1;
07707                                                 }
07708                                         }
07709                                         AST_LIST_UNLOCK(&iaxq.queue);
07710                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
07711                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
07712             }
07713             break;   
07714          case IAX_COMMAND_DPREP:
07715             complete_dpreply(iaxs[fr->callno], &ies);
07716             break;
07717          case IAX_COMMAND_UNSUPPORT:
07718             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07719             break;
07720          case IAX_COMMAND_FWDOWNL:
07721             /* Firmware download */
07722             memset(&ied0, 0, sizeof(ied0));
07723             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07724             if (res < 0)
07725                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07726             else if (res > 0)
07727                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07728             else
07729                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07730             break;
07731          default:
07732             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
07733             memset(&ied0, 0, sizeof(ied0));
07734             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07735             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07736          }
07737          /* Don't actually pass these frames along */
07738          if ((f.subclass != IAX_COMMAND_ACK) && 
07739            (f.subclass != IAX_COMMAND_TXCNT) && 
07740            (f.subclass != IAX_COMMAND_TXACC) && 
07741            (f.subclass != IAX_COMMAND_INVAL) &&
07742            (f.subclass != IAX_COMMAND_VNAK)) { 
07743             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07744                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07745          }
07746          ast_mutex_unlock(&iaxsl[fr->callno]);
07747          return 1;
07748       }
07749       /* Unless this is an ACK or INVAL frame, ack it */
07750       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07751          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07752    } else if (minivid) {
07753       f.frametype = AST_FRAME_VIDEO;
07754       if (iaxs[fr->callno]->videoformat > 0) 
07755          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07756       else {
07757          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07758          iax2_vnak(fr->callno);
07759          ast_mutex_unlock(&iaxsl[fr->callno]);
07760          return 1;
07761       }
07762       f.datalen = res - sizeof(*vh);
07763       if (f.datalen)
07764          f.data = thread->buf + sizeof(*vh);
07765       else
07766          f.data = NULL;
07767 #ifdef IAXTESTS
07768       if (test_resync) {
07769          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
07770       } else
07771 #endif /* IAXTESTS */
07772          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
07773    } else {
07774       /* A mini frame */
07775       f.frametype = AST_FRAME_VOICE;
07776       if (iaxs[fr->callno]->voiceformat > 0)
07777          f.subclass = iaxs[fr->callno]->voiceformat;
07778       else {
07779          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07780          iax2_vnak(fr->callno);
07781          ast_mutex_unlock(&iaxsl[fr->callno]);
07782          return 1;
07783       }
07784       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07785       if (f.datalen < 0) {
07786          ast_log(LOG_WARNING, "Datalen < 0?\n");
07787          ast_mutex_unlock(&iaxsl[fr->callno]);
07788          return 1;
07789       }
07790       if (f.datalen)
07791          f.data = thread->buf + sizeof(*mh);
07792       else
07793          f.data = NULL;
07794 #ifdef IAXTESTS
07795       if (test_resync) {
07796          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07797       } else
07798 #endif /* IAXTESTS */
07799       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07800       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
07801    }
07802    /* Don't pass any packets until we're started */
07803    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07804       ast_mutex_unlock(&iaxsl[fr->callno]);
07805       return 1;
07806    }
07807    /* Common things */
07808    f.src = "IAX2";
07809    f.mallocd = 0;
07810    f.offset = 0;
07811    f.len = 0;
07812    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07813       f.samples = ast_codec_get_samples(&f);
07814       /* We need to byteswap incoming slinear samples from network byte order */
07815       if (f.subclass == AST_FORMAT_SLINEAR)
07816          ast_frame_byteswap_be(&f);
07817    } else
07818       f.samples = 0;
07819    iax_frame_wrap(fr, &f);
07820 
07821    /* If this is our most recent packet, use it as our basis for timestamping */
07822    if (iaxs[fr->callno]->last < fr->ts) {
07823       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
07824       fr->outoforder = 0;
07825    } else {
07826       if (option_debug && iaxdebug)
07827          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);
07828       fr->outoforder = -1;
07829    }
07830    duped_fr = iaxfrdup2(fr);
07831    if (duped_fr) {
07832       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07833    }
07834    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07835       iaxs[fr->callno]->last = fr->ts;
07836 #if 1
07837       if (option_debug && iaxdebug)
07838          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07839 #endif
07840    }
07841 
07842    /* Always run again */
07843    ast_mutex_unlock(&iaxsl[fr->callno]);
07844    return 1;
07845 }
07846 
07847 /* Function to clean up process thread if it is cancelled */
07848 static void iax2_process_thread_cleanup(void *data)
07849 {
07850    struct iax2_thread *thread = data;
07851    ast_mutex_destroy(&thread->lock);
07852    ast_cond_destroy(&thread->cond);
07853    free(thread);
07854    ast_atomic_dec_and_test(&iaxactivethreadcount);
07855 }
07856 
07857 static void *iax2_process_thread(void *data)
07858 {
07859    struct iax2_thread *thread = data;
07860    struct timeval tv;
07861    struct timespec ts;
07862    int put_into_idle = 0;
07863 
07864    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
07865    pthread_cleanup_push(iax2_process_thread_cleanup, data);
07866    for(;;) {
07867       /* Wait for something to signal us to be awake */
07868       ast_mutex_lock(&thread->lock);
07869 
07870       /* Flag that we're ready to accept signals */
07871       thread->ready_for_signal = 1;
07872       
07873       /* Put into idle list if applicable */
07874       if (put_into_idle)
07875          insert_idle_thread(thread);
07876 
07877       if (thread->type == IAX_TYPE_DYNAMIC) {
07878          struct iax2_thread *t = NULL;
07879          /* Wait to be signalled or time out */
07880          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
07881          ts.tv_sec = tv.tv_sec;
07882          ts.tv_nsec = tv.tv_usec * 1000;
07883          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
07884             /* This thread was never put back into the available dynamic
07885              * thread list, so just go away. */
07886             if (!put_into_idle) {
07887                ast_mutex_unlock(&thread->lock);
07888                break;
07889             }
07890             AST_LIST_LOCK(&dynamic_list);
07891             /* Account for the case where this thread is acquired *right* after a timeout */
07892             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
07893                iaxdynamicthreadcount--;
07894             AST_LIST_UNLOCK(&dynamic_list);
07895             if (t) {
07896                /* This dynamic thread timed out waiting for a task and was
07897                 * not acquired immediately after the timeout, 
07898                 * so it's time to go away. */
07899                ast_mutex_unlock(&thread->lock);
07900                break;
07901             }
07902             /* Someone grabbed our thread *right* after we timed out.
07903              * Wait for them to set us up with something to do and signal
07904              * us to continue. */
07905             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
07906             ts.tv_sec = tv.tv_sec;
07907             ts.tv_nsec = tv.tv_usec * 1000;
07908             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
07909             {
07910                ast_mutex_unlock(&thread->lock);
07911                break;
07912             }
07913          }
07914       } else {
07915          ast_cond_wait(&thread->cond, &thread->lock);
07916       }
07917 
07918       /* Go back into our respective list */
07919       put_into_idle = 1;
07920 
07921       ast_mutex_unlock(&thread->lock);
07922 
07923       if (thread->iostate == IAX_IOSTATE_IDLE)
07924          continue;
07925 
07926       /* Add ourselves to the active list now */
07927       AST_LIST_LOCK(&active_list);
07928       AST_LIST_INSERT_HEAD(&active_list, thread, list);
07929       AST_LIST_UNLOCK(&active_list);
07930 
07931       /* See what we need to do */
07932       switch(thread->iostate) {
07933       case IAX_IOSTATE_READY:
07934          thread->actions++;
07935          thread->iostate = IAX_IOSTATE_PROCESSING;
07936          socket_process(thread);
07937          handle_deferred_full_frames(thread);
07938          break;
07939       case IAX_IOSTATE_SCHEDREADY:
07940          thread->actions++;
07941          thread->iostate = IAX_IOSTATE_PROCESSING;
07942 #ifdef SCHED_MULTITHREADED
07943          thread->schedfunc(thread->scheddata);
07944 #endif      
07945          break;
07946       }
07947       time(&thread->checktime);
07948       thread->iostate = IAX_IOSTATE_IDLE;
07949 #ifdef DEBUG_SCHED_MULTITHREAD
07950       thread->curfunc[0]='\0';
07951 #endif      
07952 
07953       /* Now... remove ourselves from the active list, and return to the idle list */
07954       AST_LIST_LOCK(&active_list);
07955       AST_LIST_REMOVE(&active_list, thread, list);
07956       AST_LIST_UNLOCK(&active_list);
07957 
07958       /* Make sure another frame didn't sneak in there after we thought we were done. */
07959       handle_deferred_full_frames(thread);
07960    }
07961 
07962    /* I am exiting here on my own volition, I need to clean up my own data structures
07963    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
07964    */
07965    pthread_cleanup_pop(1);
07966 
07967    return NULL;
07968 }
07969 
07970 static int iax2_do_register(struct iax2_registry *reg)
07971 {
07972    struct iax_ie_data ied;
07973    if (option_debug && iaxdebug)
07974       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07975 
07976    if (reg->dnsmgr && 
07977        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
07978       /* Maybe the IP has changed, force DNS refresh */
07979       ast_dnsmgr_refresh(reg->dnsmgr);
07980    }
07981    
07982    /*
07983     * if IP has Changed, free allocated call to create a new one with new IP
07984     * call has the pointer to IP and must be updated to the new one
07985     */
07986    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
07987       ast_mutex_lock(&iaxsl[reg->callno]);
07988       iax2_destroy(reg->callno);
07989       ast_mutex_unlock(&iaxsl[reg->callno]);
07990       reg->callno = 0;
07991    }
07992    if (!reg->addr.sin_addr.s_addr) {
07993       if (option_debug && iaxdebug)
07994          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
07995       /* Setup the next registration attempt */
07996       if (reg->expire > -1)
07997          ast_sched_del(sched, reg->expire);
07998       reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07999       return -1;
08000    }
08001 
08002    if (!reg->callno) {
08003       if (option_debug)
08004          ast_log(LOG_DEBUG, "Allocate call number\n");
08005       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
08006       if (reg->callno < 1) {
08007          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08008          return -1;
08009       } else if (option_debug)
08010          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08011       iaxs[reg->callno]->reg = reg;
08012    }
08013    /* Schedule the next registration attempt */
08014    if (reg->expire > -1)
08015       ast_sched_del(sched, reg->expire);
08016    /* Setup the next registration a little early */
08017    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08018    /* Send the request */
08019    memset(&ied, 0, sizeof(ied));
08020    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08021    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08022    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08023    reg->regstate = REG_STATE_REGSENT;
08024    return 0;
08025 }
08026 
08027 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08028 {
08029    if (pos != 3)
08030       return NULL;
08031    return iax_prov_complete_template(line, word, pos, state);
08032 }
08033 
08034 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08035 {
08036    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08037       is found for template */
08038    struct iax_ie_data provdata;
08039    struct iax_ie_data ied;
08040    unsigned int sig;
08041    struct sockaddr_in sin;
08042    int callno;
08043    struct create_addr_info cai;
08044 
08045    memset(&cai, 0, sizeof(cai));
08046 
08047    if (option_debug)
08048       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08049 
08050    if (iax_provision_build(&provdata, &sig, template, force)) {
08051       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08052       return 0;
08053    }
08054 
08055    if (end) {
08056       memcpy(&sin, end, sizeof(sin));
08057       cai.sockfd = sockfd;
08058    } else if (create_addr(dest, &sin, &cai))
08059       return -1;
08060 
08061    /* Build the rest of the message */
08062    memset(&ied, 0, sizeof(ied));
08063    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08064 
08065    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08066    if (!callno)
08067       return -1;
08068 
08069    ast_mutex_lock(&iaxsl[callno]);
08070    if (iaxs[callno]) {
08071       /* Schedule autodestruct in case they don't ever give us anything back */
08072       if (iaxs[callno]->autoid > -1)
08073          ast_sched_del(sched, iaxs[callno]->autoid);
08074       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08075       ast_set_flag(iaxs[callno], IAX_PROVISION);
08076       /* Got a call number now, so go ahead and send the provisioning information */
08077       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08078    }
08079    ast_mutex_unlock(&iaxsl[callno]);
08080 
08081    return 1;
08082 }
08083 
08084 static char *papp = "IAX2Provision";
08085 static char *psyn = "Provision a calling IAXy with a given template";
08086 static char *pdescrip = 
08087 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08088 "the calling entity is in fact an IAXy) with the given template or\n"
08089 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08090 
08091 /*! iax2provision
08092 \ingroup applications
08093 */
08094 static int iax2_prov_app(struct ast_channel *chan, void *data)
08095 {
08096    int res;
08097    char *sdata;
08098    char *opts;
08099    int force =0;
08100    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08101    if (ast_strlen_zero(data))
08102       data = "default";
08103    sdata = ast_strdupa(data);
08104    opts = strchr(sdata, '|');
08105    if (opts)
08106       *opts='\0';
08107 
08108    if (chan->tech != &iax2_tech) {
08109       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08110       return -1;
08111    } 
08112    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08113       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08114       return -1;
08115    }
08116    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08117    if (option_verbose > 2)
08118       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08119       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08120       sdata, res);
08121    return res;
08122 }
08123 
08124 
08125 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08126 {
08127    int force = 0;
08128    int res;
08129    if (argc < 4)
08130       return RESULT_SHOWUSAGE;
08131    if ((argc > 4)) {
08132       if (!strcasecmp(argv[4], "forced"))
08133          force = 1;
08134       else
08135          return RESULT_SHOWUSAGE;
08136    }
08137    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08138    if (res < 0)
08139       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08140    else if (res < 1)
08141       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08142    else
08143       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08144    return RESULT_SUCCESS;
08145 }
08146 
08147 static void __iax2_poke_noanswer(void *data)
08148 {
08149    struct iax2_peer *peer = data;
08150    if (peer->lastms > -1) {
08151       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08152       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08153       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08154    }
08155    if (peer->callno > 0) {
08156       ast_mutex_lock(&iaxsl[peer->callno]);
08157       iax2_destroy(peer->callno);
08158       ast_mutex_unlock(&iaxsl[peer->callno]);
08159    }
08160    peer->callno = 0;
08161    peer->lastms = -1;
08162    /* Try again quickly */
08163    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
08164 }
08165 
08166 static int iax2_poke_noanswer(void *data)
08167 {
08168    struct iax2_peer *peer = data;
08169    peer->pokeexpire = -1;
08170 #ifdef SCHED_MULTITHREADED
08171    if (schedule_action(__iax2_poke_noanswer, data))
08172 #endif      
08173       __iax2_poke_noanswer(data);
08174    return 0;
08175 }
08176 
08177 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08178 {
08179    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
08180       /* IF we have no IP, or this isn't to be monitored, return
08181         immediately after clearing things out */
08182       peer->lastms = 0;
08183       peer->historicms = 0;
08184       peer->pokeexpire = -1;
08185       peer->callno = 0;
08186       return 0;
08187    }
08188    if (peer->callno > 0) {
08189       ast_log(LOG_NOTICE, "Still have a callno...\n");
08190       ast_mutex_lock(&iaxsl[peer->callno]);
08191       iax2_destroy(peer->callno);
08192       ast_mutex_unlock(&iaxsl[peer->callno]);
08193    }
08194    if (heldcall)
08195       ast_mutex_unlock(&iaxsl[heldcall]);
08196    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
08197    if (heldcall)
08198       ast_mutex_lock(&iaxsl[heldcall]);
08199    if (peer->callno < 1) {
08200       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08201       return -1;
08202    }
08203 
08204    /* Speed up retransmission times for this qualify call */
08205    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08206    iaxs[peer->callno]->peerpoke = peer;
08207    
08208    /* Remove any pending pokeexpire task */
08209    if (peer->pokeexpire > -1)
08210       ast_sched_del(sched, peer->pokeexpire);
08211 
08212    /* Queue up a new task to handle no reply */
08213    /* If the host is already unreachable then use the unreachable interval instead */
08214    if (peer->lastms < 0) {
08215       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
08216    } else
08217       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
08218 
08219    /* And send the poke */
08220    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08221 
08222    return 0;
08223 }
08224 
08225 static void free_context(struct iax2_context *con)
08226 {
08227    struct iax2_context *conl;
08228    while(con) {
08229       conl = con;
08230       con = con->next;
08231       free(conl);
08232    }
08233 }
08234 
08235 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08236 {
08237    int callno;
08238    int res;
08239    int fmt, native;
08240    struct sockaddr_in sin;
08241    struct ast_channel *c;
08242    struct parsed_dial_string pds;
08243    struct create_addr_info cai;
08244    char *tmpstr;
08245 
08246    memset(&pds, 0, sizeof(pds));
08247    tmpstr = ast_strdupa(data);
08248    parse_dial_string(tmpstr, &pds);
08249 
08250    memset(&cai, 0, sizeof(cai));
08251    cai.capability = iax2_capability;
08252 
08253    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08254 
08255    if (!pds.peer) {
08256       ast_log(LOG_WARNING, "No peer given\n");
08257       return NULL;
08258    }
08259           
08260    
08261    /* Populate our address from the given */
08262    if (create_addr(pds.peer, &sin, &cai)) {
08263       *cause = AST_CAUSE_UNREGISTERED;
08264       return NULL;
08265    }
08266 
08267    if (pds.port)
08268       sin.sin_port = htons(atoi(pds.port));
08269 
08270    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08271    if (callno < 1) {
08272       ast_log(LOG_WARNING, "Unable to create call\n");
08273       *cause = AST_CAUSE_CONGESTION;
08274       return NULL;
08275    }
08276 
08277    ast_mutex_lock(&iaxsl[callno]);
08278 
08279    /* If this is a trunk, update it now */
08280    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08281    if (ast_test_flag(&cai, IAX_TRUNK)) {
08282       int new_callno;
08283       if ((new_callno = make_trunk(callno, 1)) != -1)
08284          callno = new_callno;
08285    }
08286    iaxs[callno]->maxtime = cai.maxtime;
08287    if (cai.found)
08288       ast_string_field_set(iaxs[callno], host, pds.peer);
08289 
08290    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08291 
08292    ast_mutex_unlock(&iaxsl[callno]);
08293 
08294    if (c) {
08295       /* Choose a format we can live with */
08296       if (c->nativeformats & format) 
08297          c->nativeformats &= format;
08298       else {
08299          native = c->nativeformats;
08300          fmt = format;
08301          res = ast_translator_best_choice(&fmt, &native);
08302          if (res < 0) {
08303             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08304                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08305             ast_hangup(c);
08306             return NULL;
08307          }
08308          c->nativeformats = native;
08309       }
08310       c->readformat = ast_best_codec(c->nativeformats);
08311       c->writeformat = c->readformat;
08312    }
08313 
08314    return c;
08315 }
08316 
08317 static void *sched_thread(void *ignore)
08318 {
08319    int count;
08320    int res;
08321    struct timeval tv;
08322    struct timespec ts;
08323 
08324    for (;;) {
08325       res = ast_sched_wait(sched);
08326       if ((res > 1000) || (res < 0))
08327          res = 1000;
08328       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08329       ts.tv_sec = tv.tv_sec;
08330       ts.tv_nsec = tv.tv_usec * 1000;
08331 
08332       pthread_testcancel();
08333       ast_mutex_lock(&sched_lock);
08334       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08335       ast_mutex_unlock(&sched_lock);
08336       pthread_testcancel();
08337 
08338       count = ast_sched_runq(sched);
08339       if (count >= 20)
08340          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08341    }
08342    return NULL;
08343 }
08344 
08345 static void *network_thread(void *ignore)
08346 {
08347    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08348       from the network, and queue them for delivery to the channels */
08349    int res, count, wakeup;
08350    struct iax_frame *f;
08351 
08352    if (timingfd > -1)
08353       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08354    
08355    for(;;) {
08356       pthread_testcancel();
08357 
08358       /* Go through the queue, sending messages which have not yet been
08359          sent, and scheduling retransmissions if appropriate */
08360       AST_LIST_LOCK(&iaxq.queue);
08361       count = 0;
08362       wakeup = -1;
08363       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08364          if (f->sentyet)
08365             continue;
08366          
08367          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
08368          if (ast_mutex_trylock(&iaxsl[f->callno])) {
08369             wakeup = 1;
08370             continue;
08371          }
08372 
08373          f->sentyet++;
08374 
08375          if (iaxs[f->callno]) {
08376             send_packet(f);
08377             count++;
08378          } 
08379 
08380          ast_mutex_unlock(&iaxsl[f->callno]);
08381 
08382          if (f->retries < 0) {
08383             /* This is not supposed to be retransmitted */
08384             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
08385             iaxq.count--;
08386             /* Free the iax frame */
08387             iax_frame_free(f);
08388          } else {
08389             /* We need reliable delivery.  Schedule a retransmission */
08390             f->retries++;
08391             f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08392             signal_condition(&sched_lock, &sched_cond);
08393          }
08394       }
08395       AST_LIST_TRAVERSE_SAFE_END
08396       AST_LIST_UNLOCK(&iaxq.queue);
08397 
08398       pthread_testcancel();
08399 
08400       if (count >= 20)
08401          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08402 
08403       /* Now do the IO, and run scheduled tasks */
08404       res = ast_io_wait(io, wakeup);
08405       if (res >= 0) {
08406          if (res >= 20)
08407             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08408       }
08409    }
08410    return NULL;
08411 }
08412 
08413 static int start_network_thread(void)
08414 {
08415    pthread_attr_t attr;
08416    int threadcount = 0;
08417    int x;
08418    for (x = 0; x < iaxthreadcount; x++) {
08419       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08420       if (thread) {
08421          thread->type = IAX_TYPE_POOL;
08422          thread->threadnum = ++threadcount;
08423          ast_mutex_init(&thread->lock);
08424          ast_cond_init(&thread->cond, NULL);
08425          pthread_attr_init(&attr);
08426          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08427          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08428             ast_log(LOG_WARNING, "Failed to create new thread!\n");
08429             free(thread);
08430             thread = NULL;
08431          }
08432          AST_LIST_LOCK(&idle_list);
08433          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08434          AST_LIST_UNLOCK(&idle_list);
08435       }
08436    }
08437    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08438    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08439    if (option_verbose > 1)
08440       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08441    return 0;
08442 }
08443 
08444 static struct iax2_context *build_context(char *context)
08445 {
08446    struct iax2_context *con;
08447 
08448    if ((con = ast_calloc(1, sizeof(*con))))
08449       ast_copy_string(con->context, context, sizeof(con->context));
08450    
08451    return con;
08452 }
08453 
08454 static int get_auth_methods(char *value)
08455 {
08456    int methods = 0;
08457    if (strstr(value, "rsa"))
08458       methods |= IAX_AUTH_RSA;
08459    if (strstr(value, "md5"))
08460       methods |= IAX_AUTH_MD5;
08461    if (strstr(value, "plaintext"))
08462       methods |= IAX_AUTH_PLAINTEXT;
08463    return methods;
08464 }
08465 
08466 
08467 /*! \brief Check if address can be used as packet source.
08468  \return 0  address available, 1  address unavailable, -1  error
08469 */
08470 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08471 {
08472    int sd;
08473    int res;
08474    
08475    sd = socket(AF_INET, SOCK_DGRAM, 0);
08476    if (sd < 0) {
08477       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08478       return -1;
08479    }
08480 
08481    res = bind(sd, sa, salen);
08482    if (res < 0) {
08483       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08484       close(sd);
08485       return 1;
08486    }
08487 
08488    close(sd);
08489    return 0;
08490 }
08491 
08492 /*! \brief Parse the "sourceaddress" value,
08493   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08494   not found. */
08495 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08496 {
08497    struct sockaddr_in sin;
08498    int nonlocal = 1;
08499    int port = IAX_DEFAULT_PORTNO;
08500    int sockfd = defaultsockfd;
08501    char *tmp;
08502    char *addr;
08503    char *portstr;
08504 
08505    if (!(tmp = ast_strdupa(srcaddr)))
08506       return -1;
08507 
08508    addr = strsep(&tmp, ":");
08509    portstr = tmp;
08510 
08511    if (portstr) {
08512       port = atoi(portstr);
08513       if (port < 1)
08514          port = IAX_DEFAULT_PORTNO;
08515    }
08516    
08517    if (!ast_get_ip(&sin, addr)) {
08518       struct ast_netsock *sock;
08519       int res;
08520 
08521       sin.sin_port = 0;
08522       sin.sin_family = AF_INET;
08523       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08524       if (res == 0) {
08525          /* ip address valid. */
08526          sin.sin_port = htons(port);
08527          if (!(sock = ast_netsock_find(netsock, &sin)))
08528             sock = ast_netsock_find(outsock, &sin);
08529          if (sock) {
08530             sockfd = ast_netsock_sockfd(sock);
08531             nonlocal = 0;
08532          } else {
08533             unsigned int orig_saddr = sin.sin_addr.s_addr;
08534             /* INADDR_ANY matches anyway! */
08535             sin.sin_addr.s_addr = INADDR_ANY;
08536             if (ast_netsock_find(netsock, &sin)) {
08537                sin.sin_addr.s_addr = orig_saddr;
08538                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
08539                if (sock) {
08540                   sockfd = ast_netsock_sockfd(sock);
08541                   ast_netsock_unref(sock);
08542                   nonlocal = 0;
08543                } else {
08544                   nonlocal = 2;
08545                }
08546             }
08547          }
08548       }
08549    }
08550       
08551    peer->sockfd = sockfd;
08552 
08553    if (nonlocal == 1) {
08554       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08555          srcaddr, peer->name);
08556       return -1;
08557         } else if (nonlocal == 2) {
08558       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
08559          srcaddr, peer->name);
08560          return -1;
08561    } else {
08562       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08563       return 0;
08564    }
08565 }
08566 
08567       
08568 /*! \brief Create peer structure based on configuration */
08569 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08570 {
08571    struct iax2_peer *peer = NULL;
08572    struct ast_ha *oldha = NULL;
08573    int maskfound=0;
08574    int found=0;
08575    int firstpass=1;
08576 
08577    AST_LIST_LOCK(&peers);
08578    if (!temponly) {
08579       AST_LIST_TRAVERSE(&peers, peer, entry) {
08580          if (!strcmp(peer->name, name)) { 
08581             if (!ast_test_flag(peer, IAX_DELME))
08582                firstpass = 0;
08583             break;
08584          }
08585       }
08586    } else
08587       peer = NULL;   
08588    if (peer) {
08589       found++;
08590       if (firstpass) {
08591          oldha = peer->ha;
08592          peer->ha = NULL;
08593       }
08594       AST_LIST_REMOVE(&peers, peer, entry);
08595       AST_LIST_UNLOCK(&peers);
08596    } else {
08597       AST_LIST_UNLOCK(&peers);
08598       if ((peer = ast_calloc(1, sizeof(*peer)))) {
08599          peer->expire = -1;
08600          peer->pokeexpire = -1;
08601          peer->sockfd = defaultsockfd;
08602          if (ast_string_field_init(peer, 32)) {
08603             free(peer);
08604             peer = NULL;
08605          }
08606       }
08607    }
08608    if (peer) {
08609       if (firstpass) {
08610          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08611          peer->encmethods = iax2_encryption;
08612          peer->adsi = adsi;
08613          ast_string_field_set(peer,secret,"");
08614          if (!found) {
08615             ast_string_field_set(peer, name, name);
08616             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08617             peer->expiry = min_reg_expire;
08618          }
08619          peer->prefs = prefs;
08620          peer->capability = iax2_capability;
08621          peer->smoothing = 0;
08622          peer->pokefreqok = DEFAULT_FREQ_OK;
08623          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08624          ast_string_field_set(peer,context,"");
08625          ast_string_field_set(peer,peercontext,"");
08626          ast_clear_flag(peer, IAX_HASCALLERID);
08627          ast_string_field_set(peer, cid_name, "");
08628          ast_string_field_set(peer, cid_num, "");
08629       }
08630 
08631       if (!v) {
08632          v = alt;
08633          alt = NULL;
08634       }
08635       while(v) {
08636          if (!strcasecmp(v->name, "secret")) {
08637             ast_string_field_set(peer, secret, v->value);
08638          } else if (!strcasecmp(v->name, "mailbox")) {
08639             ast_string_field_set(peer, mailbox, v->value);
08640          } else if (!strcasecmp(v->name, "mohinterpret")) {
08641             ast_string_field_set(peer, mohinterpret, v->value);
08642          } else if (!strcasecmp(v->name, "mohsuggest")) {
08643             ast_string_field_set(peer, mohsuggest, v->value);
08644          } else if (!strcasecmp(v->name, "dbsecret")) {
08645             ast_string_field_set(peer, dbsecret, v->value);
08646          } else if (!strcasecmp(v->name, "trunk")) {
08647             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08648             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08649                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08650                ast_clear_flag(peer, IAX_TRUNK);
08651             }
08652          } else if (!strcasecmp(v->name, "auth")) {
08653             peer->authmethods = get_auth_methods(v->value);
08654          } else if (!strcasecmp(v->name, "encryption")) {
08655             peer->encmethods = get_encrypt_methods(v->value);
08656          } else if (!strcasecmp(v->name, "notransfer")) {
08657             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08658             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
08659             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08660          } else if (!strcasecmp(v->name, "transfer")) {
08661             if (!strcasecmp(v->value, "mediaonly")) {
08662                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
08663             } else if (ast_true(v->value)) {
08664                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08665             } else 
08666                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08667          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08668             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08669          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08670             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08671          } else if (!strcasecmp(v->name, "host")) {
08672             if (!strcasecmp(v->value, "dynamic")) {
08673                /* They'll register with us */
08674                ast_set_flag(peer, IAX_DYNAMIC); 
08675                if (!found) {
08676                   /* Initialize stuff iff we're not found, otherwise
08677                      we keep going with what we had */
08678                   memset(&peer->addr.sin_addr, 0, 4);
08679                   if (peer->addr.sin_port) {
08680                      /* If we've already got a port, make it the default rather than absolute */
08681                      peer->defaddr.sin_port = peer->addr.sin_port;
08682                      peer->addr.sin_port = 0;
08683                   }
08684                }
08685             } else {
08686                /* Non-dynamic.  Make sure we become that way if we're not */
08687                if (peer->expire > -1)
08688                   ast_sched_del(sched, peer->expire);
08689                peer->expire = -1;
08690                ast_clear_flag(peer, IAX_DYNAMIC);
08691                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08692                   ast_string_field_free_pools(peer);
08693                   free(peer);
08694                   return NULL;
08695                }
08696                if (!peer->addr.sin_port)
08697                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08698             }
08699             if (!maskfound)
08700                inet_aton("255.255.255.255", &peer->mask);
08701          } else if (!strcasecmp(v->name, "defaultip")) {
08702             if (ast_get_ip(&peer->defaddr, v->value)) {
08703                ast_string_field_free_pools(peer);
08704                free(peer);
08705                return NULL;
08706             }
08707          } else if (!strcasecmp(v->name, "sourceaddress")) {
08708             peer_set_srcaddr(peer, v->value);
08709          } else if (!strcasecmp(v->name, "permit") ||
08710                   !strcasecmp(v->name, "deny")) {
08711             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08712          } else if (!strcasecmp(v->name, "mask")) {
08713             maskfound++;
08714             inet_aton(v->value, &peer->mask);
08715          } else if (!strcasecmp(v->name, "context")) {
08716             ast_string_field_set(peer, context, v->value);
08717          } else if (!strcasecmp(v->name, "regexten")) {
08718             ast_string_field_set(peer, regexten, v->value);
08719          } else if (!strcasecmp(v->name, "peercontext")) {
08720             ast_string_field_set(peer, peercontext, v->value);
08721          } else if (!strcasecmp(v->name, "port")) {
08722             if (ast_test_flag(peer, IAX_DYNAMIC))
08723                peer->defaddr.sin_port = htons(atoi(v->value));
08724             else
08725                peer->addr.sin_port = htons(atoi(v->value));
08726          } else if (!strcasecmp(v->name, "username")) {
08727             ast_string_field_set(peer, username, v->value);
08728          } else if (!strcasecmp(v->name, "allow")) {
08729             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08730          } else if (!strcasecmp(v->name, "disallow")) {
08731             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08732          } else if (!strcasecmp(v->name, "callerid")) {
08733             if (!ast_strlen_zero(v->value)) {
08734                char name2[80];
08735                char num2[80];
08736                ast_callerid_split(v->value, name2, 80, num2, 80);
08737                ast_string_field_set(peer, cid_name, name2);
08738                ast_string_field_set(peer, cid_num, num2);
08739                ast_set_flag(peer, IAX_HASCALLERID);
08740             } else {
08741                ast_clear_flag(peer, IAX_HASCALLERID);
08742                ast_string_field_set(peer, cid_name, "");
08743                ast_string_field_set(peer, cid_num, "");
08744             }
08745          } else if (!strcasecmp(v->name, "fullname")) {
08746             if (!ast_strlen_zero(v->value)) {
08747                ast_string_field_set(peer, cid_name, v->value);
08748                ast_set_flag(peer, IAX_HASCALLERID);
08749             } else {
08750                ast_string_field_set(peer, cid_name, "");
08751                if (ast_strlen_zero(peer->cid_num))
08752                   ast_clear_flag(peer, IAX_HASCALLERID);
08753             }
08754          } else if (!strcasecmp(v->name, "cid_number")) {
08755             if (!ast_strlen_zero(v->value)) {
08756                ast_string_field_set(peer, cid_num, v->value);
08757                ast_set_flag(peer, IAX_HASCALLERID);
08758             } else {
08759                ast_string_field_set(peer, cid_num, "");
08760                if (ast_strlen_zero(peer->cid_name))
08761                   ast_clear_flag(peer, IAX_HASCALLERID);
08762             }
08763          } else if (!strcasecmp(v->name, "sendani")) {
08764             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08765          } else if (!strcasecmp(v->name, "inkeys")) {
08766             ast_string_field_set(peer, inkeys, v->value);
08767          } else if (!strcasecmp(v->name, "outkey")) {
08768             ast_string_field_set(peer, outkey, v->value);
08769          } else if (!strcasecmp(v->name, "qualify")) {
08770             if (!strcasecmp(v->value, "no")) {
08771                peer->maxms = 0;
08772             } else if (!strcasecmp(v->value, "yes")) {
08773                peer->maxms = DEFAULT_MAXMS;
08774             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08775                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);
08776                peer->maxms = 0;
08777             }
08778          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08779             peer->smoothing = ast_true(v->value);
08780          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08781             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08782                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);
08783             }
08784          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08785             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08786                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);
08787             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08788          } else if (!strcasecmp(v->name, "timezone")) {
08789             ast_string_field_set(peer, zonetag, v->value);
08790          } else if (!strcasecmp(v->name, "adsi")) {
08791             peer->adsi = ast_true(v->value);
08792          }/* else if (strcasecmp(v->name,"type")) */
08793          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08794          v = v->next;
08795          if (!v) {
08796             v = alt;
08797             alt = NULL;
08798          }
08799       }
08800       if (!peer->authmethods)
08801          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08802       ast_clear_flag(peer, IAX_DELME); 
08803       /* Make sure these are IPv4 addresses */
08804       peer->addr.sin_family = AF_INET;
08805    }
08806    if (oldha)
08807       ast_free_ha(oldha);
08808    return peer;
08809 }
08810 
08811 /*! \brief Create in-memory user structure from configuration */
08812 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08813 {
08814    struct iax2_user *user = NULL;
08815    struct iax2_context *con, *conl = NULL;
08816    struct ast_ha *oldha = NULL;
08817    struct iax2_context *oldcon = NULL;
08818    int format;
08819    int firstpass=1;
08820    int oldcurauthreq = 0;
08821    char *varname = NULL, *varval = NULL;
08822    struct ast_variable *tmpvar = NULL;
08823    
08824    AST_LIST_LOCK(&users);
08825    if (!temponly) {
08826       AST_LIST_TRAVERSE(&users, user, entry) {
08827          if (!strcmp(user->name, name)) { 
08828             if (!ast_test_flag(user, IAX_DELME))
08829                firstpass = 0;
08830             break;
08831          }
08832       }
08833    } else
08834       user = NULL;
08835 
08836    if (user) {
08837       if (firstpass) {
08838          oldcurauthreq = user->curauthreq;
08839          oldha = user->ha;
08840          oldcon = user->contexts;
08841          user->ha = NULL;
08842          user->contexts = NULL;
08843       }
08844       /* Already in the list, remove it and it will be added back (or FREE'd) */
08845       AST_LIST_REMOVE(&users, user, entry);
08846       AST_LIST_UNLOCK(&users);
08847    } else {
08848       AST_LIST_UNLOCK(&users);
08849       /* This is going to memset'd to 0 in the next block */
08850       user = ast_calloc(sizeof(*user),1);
08851    }
08852    
08853    if (user) {
08854       if (firstpass) {
08855          ast_string_field_free_pools(user);
08856          memset(user, 0, sizeof(struct iax2_user));
08857          if (ast_string_field_init(user, 32)) {
08858             free(user);
08859             user = NULL;
08860          }
08861          user->maxauthreq = maxauthreq;
08862          user->curauthreq = oldcurauthreq;
08863          user->prefs = prefs;
08864          user->capability = iax2_capability;
08865          user->encmethods = iax2_encryption;
08866          user->adsi = adsi;
08867          ast_string_field_set(user, name, name);
08868          ast_string_field_set(user, language, language);
08869          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08870          ast_clear_flag(user, IAX_HASCALLERID);
08871          ast_string_field_set(user, cid_name, "");
08872          ast_string_field_set(user, cid_num, "");
08873       }
08874       if (!v) {
08875          v = alt;
08876          alt = NULL;
08877       }
08878       while(v) {
08879          if (!strcasecmp(v->name, "context")) {
08880             con = build_context(v->value);
08881             if (con) {
08882                if (conl)
08883                   conl->next = con;
08884                else
08885                   user->contexts = con;
08886                conl = con;
08887             }
08888          } else if (!strcasecmp(v->name, "permit") ||
08889                   !strcasecmp(v->name, "deny")) {
08890             user->ha = ast_append_ha(v->name, v->value, user->ha);
08891          } else if (!strcasecmp(v->name, "setvar")) {
08892             varname = ast_strdupa(v->value);
08893             if (varname && (varval = strchr(varname,'='))) {
08894                *varval = '\0';
08895                varval++;
08896                if((tmpvar = ast_variable_new(varname, varval))) {
08897                   tmpvar->next = user->vars; 
08898                   user->vars = tmpvar;
08899                }
08900             }
08901          } else if (!strcasecmp(v->name, "allow")) {
08902             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08903          } else if (!strcasecmp(v->name, "disallow")) {
08904             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08905          } else if (!strcasecmp(v->name, "trunk")) {
08906             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08907             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08908                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08909                ast_clear_flag(user, IAX_TRUNK);
08910             }
08911          } else if (!strcasecmp(v->name, "auth")) {
08912             user->authmethods = get_auth_methods(v->value);
08913          } else if (!strcasecmp(v->name, "encryption")) {
08914             user->encmethods = get_encrypt_methods(v->value);
08915          } else if (!strcasecmp(v->name, "notransfer")) {
08916             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08917             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
08918             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08919          } else if (!strcasecmp(v->name, "transfer")) {
08920             if (!strcasecmp(v->value, "mediaonly")) {
08921                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
08922             } else if (ast_true(v->value)) {
08923                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08924             } else 
08925                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08926          } else if (!strcasecmp(v->name, "codecpriority")) {
08927             if(!strcasecmp(v->value, "caller"))
08928                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08929             else if(!strcasecmp(v->value, "disabled"))
08930                ast_set_flag(user, IAX_CODEC_NOPREFS);
08931             else if(!strcasecmp(v->value, "reqonly")) {
08932                ast_set_flag(user, IAX_CODEC_NOCAP);
08933                ast_set_flag(user, IAX_CODEC_NOPREFS);
08934             }
08935          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08936             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
08937          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08938             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
08939          } else if (!strcasecmp(v->name, "dbsecret")) {
08940             ast_string_field_set(user, dbsecret, v->value);
08941          } else if (!strcasecmp(v->name, "secret")) {
08942             if (!ast_strlen_zero(user->secret)) {
08943                char *old = ast_strdupa(user->secret);
08944 
08945                ast_string_field_build(user, secret, "%s;%s", old, v->value);
08946             } else
08947                ast_string_field_set(user, secret, v->value);
08948          } else if (!strcasecmp(v->name, "callerid")) {
08949             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
08950                char name2[80];
08951                char num2[80];
08952                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
08953                ast_string_field_set(user, cid_name, name2);
08954                ast_string_field_set(user, cid_num, num2);
08955                ast_set_flag(user, IAX_HASCALLERID);
08956             } else {
08957                ast_clear_flag(user, IAX_HASCALLERID);
08958                ast_string_field_set(user, cid_name, "");
08959                ast_string_field_set(user, cid_num, "");
08960             }
08961          } else if (!strcasecmp(v->name, "fullname")) {
08962             if (!ast_strlen_zero(v->value)) {
08963                ast_string_field_set(user, cid_name, v->value);
08964                ast_set_flag(user, IAX_HASCALLERID);
08965             } else {
08966                ast_string_field_set(user, cid_name, "");
08967                if (ast_strlen_zero(user->cid_num))
08968                   ast_clear_flag(user, IAX_HASCALLERID);
08969             }
08970          } else if (!strcasecmp(v->name, "cid_number")) {
08971             if (!ast_strlen_zero(v->value)) {
08972                ast_string_field_set(user, cid_num, v->value);
08973                ast_set_flag(user, IAX_HASCALLERID);
08974             } else {
08975                ast_string_field_set(user, cid_num, "");
08976                if (ast_strlen_zero(user->cid_name))
08977                   ast_clear_flag(user, IAX_HASCALLERID);
08978             }
08979          } else if (!strcasecmp(v->name, "accountcode")) {
08980             ast_string_field_set(user, accountcode, v->value);
08981          } else if (!strcasecmp(v->name, "mohinterpret")) {
08982             ast_string_field_set(user, mohinterpret, v->value);
08983          } else if (!strcasecmp(v->name, "mohsuggest")) {
08984             ast_string_field_set(user, mohsuggest, v->value);
08985          } else if (!strcasecmp(v->name, "language")) {
08986             ast_string_field_set(user, language, v->value);
08987          } else if (!strcasecmp(v->name, "amaflags")) {
08988             format = ast_cdr_amaflags2int(v->value);
08989             if (format < 0) {
08990                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08991             } else {
08992                user->amaflags = format;
08993             }
08994          } else if (!strcasecmp(v->name, "inkeys")) {
08995             ast_string_field_set(user, inkeys, v->value);
08996          } else if (!strcasecmp(v->name, "maxauthreq")) {
08997             user->maxauthreq = atoi(v->value);
08998             if (user->maxauthreq < 0)
08999                user->maxauthreq = 0;
09000          } else if (!strcasecmp(v->name, "adsi")) {
09001             user->adsi = ast_true(v->value);
09002          }/* else if (strcasecmp(v->name,"type")) */
09003          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09004          v = v->next;
09005          if (!v) {
09006             v = alt;
09007             alt = NULL;
09008          }
09009       }
09010       if (!user->authmethods) {
09011          if (!ast_strlen_zero(user->secret)) {
09012             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09013             if (!ast_strlen_zero(user->inkeys))
09014                user->authmethods |= IAX_AUTH_RSA;
09015          } else if (!ast_strlen_zero(user->inkeys)) {
09016             user->authmethods = IAX_AUTH_RSA;
09017          } else {
09018             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09019          }
09020       }
09021       ast_clear_flag(user, IAX_DELME);
09022    }
09023    if (oldha)
09024       ast_free_ha(oldha);
09025    if (oldcon)
09026       free_context(oldcon);
09027    return user;
09028 }
09029 
09030 static void delete_users(void)
09031 {
09032    struct iax2_user *user;
09033    struct iax2_peer *peer;
09034    struct iax2_registry *reg;
09035 
09036    AST_LIST_LOCK(&users);
09037    AST_LIST_TRAVERSE(&users, user, entry)
09038       ast_set_flag(user, IAX_DELME);
09039    AST_LIST_UNLOCK(&users);
09040 
09041    AST_LIST_LOCK(&registrations);
09042    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09043       if (reg->expire > -1)
09044          ast_sched_del(sched, reg->expire);
09045       if (reg->callno) {
09046          ast_mutex_lock(&iaxsl[reg->callno]);
09047          if (iaxs[reg->callno]) {
09048             iaxs[reg->callno]->reg = NULL;
09049             iax2_destroy(reg->callno);
09050          }
09051          ast_mutex_unlock(&iaxsl[reg->callno]);
09052       }
09053       if (reg->dnsmgr)
09054          ast_dnsmgr_release(reg->dnsmgr);
09055       free(reg);
09056    }
09057    AST_LIST_UNLOCK(&registrations);
09058 
09059    AST_LIST_LOCK(&peers);
09060    AST_LIST_TRAVERSE(&peers, peer, entry)
09061       ast_set_flag(peer, IAX_DELME);
09062    AST_LIST_UNLOCK(&peers);
09063 }
09064 
09065 static void destroy_user(struct iax2_user *user)
09066 {
09067    ast_free_ha(user->ha);
09068    free_context(user->contexts);
09069    if(user->vars) {
09070       ast_variables_destroy(user->vars);
09071       user->vars = NULL;
09072    }
09073    ast_string_field_free_pools(user);
09074    free(user);
09075 }
09076 
09077 static void prune_users(void)
09078 {
09079    struct iax2_user *user = NULL;
09080 
09081    AST_LIST_LOCK(&users);
09082    AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) {
09083       if (ast_test_flag(user, IAX_DELME)) {
09084          destroy_user(user);
09085          AST_LIST_REMOVE_CURRENT(&users, entry);
09086       }
09087    }
09088    AST_LIST_TRAVERSE_SAFE_END
09089    AST_LIST_UNLOCK(&users);
09090 
09091 }
09092 
09093 static void destroy_peer(struct iax2_peer *peer)
09094 {
09095    ast_free_ha(peer->ha);
09096 
09097    /* Delete it, it needs to disappear */
09098    if (peer->expire > -1)
09099       ast_sched_del(sched, peer->expire);
09100    if (peer->pokeexpire > -1)
09101       ast_sched_del(sched, peer->pokeexpire);
09102    if (peer->callno > 0) {
09103       ast_mutex_lock(&iaxsl[peer->callno]);
09104       iax2_destroy(peer->callno);
09105       ast_mutex_unlock(&iaxsl[peer->callno]);
09106    }
09107 
09108    register_peer_exten(peer, 0);
09109 
09110    if (peer->dnsmgr)
09111       ast_dnsmgr_release(peer->dnsmgr);
09112 
09113    ast_string_field_free_pools(peer);
09114 
09115    free(peer);
09116 }
09117 
09118 static void prune_peers(void){
09119    /* Prune peers who still are supposed to be deleted */
09120    struct iax2_peer *peer = NULL;
09121 
09122    AST_LIST_LOCK(&peers);
09123    AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) {
09124       if (ast_test_flag(peer, IAX_DELME)) {
09125          destroy_peer(peer);
09126          AST_LIST_REMOVE_CURRENT(&peers, entry);
09127       }
09128    }
09129    AST_LIST_TRAVERSE_SAFE_END
09130    AST_LIST_UNLOCK(&peers);
09131 }
09132 
09133 static void set_timing(void)
09134 {
09135 #ifdef HAVE_ZAPTEL
09136    int bs = trunkfreq * 8;
09137    if (timingfd > -1) {
09138       if (
09139 #ifdef ZT_TIMERACK
09140          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09141 #endif         
09142          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09143          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09144    }
09145 #endif
09146 }
09147 
09148 
09149 /*! \brief Load configuration */
09150 static int set_config(char *config_file, int reload)
09151 {
09152    struct ast_config *cfg, *ucfg;
09153    int capability=iax2_capability;
09154    struct ast_variable *v;
09155    char *cat;
09156    const char *utype;
09157    const char *tosval;
09158    int format;
09159    int portno = IAX_DEFAULT_PORTNO;
09160    int  x;
09161    struct iax2_user *user;
09162    struct iax2_peer *peer;
09163    struct ast_netsock *ns;
09164 #if 0
09165    static unsigned short int last_port=0;
09166 #endif
09167 
09168    cfg = ast_config_load(config_file);
09169    
09170    if (!cfg) {
09171       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09172       return -1;
09173    }
09174 
09175    /* Reset global codec prefs */   
09176    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09177    
09178    /* Reset Global Flags */
09179    memset(&globalflags, 0, sizeof(globalflags));
09180    ast_set_flag(&globalflags, IAX_RTUPDATE);
09181 
09182 #ifdef SO_NO_CHECK
09183    nochecksums = 0;
09184 #endif
09185 
09186    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09187    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09188 
09189    maxauthreq = 3;
09190 
09191    v = ast_variable_browse(cfg, "general");
09192 
09193    /* Seed initial tos value */
09194    tosval = ast_variable_retrieve(cfg, "general", "tos");
09195    if (tosval) {
09196       if (ast_str2tos(tosval, &tos))
09197          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09198    }
09199    while(v) {
09200       if (!strcasecmp(v->name, "bindport")){ 
09201          if (reload)
09202             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09203          else
09204             portno = atoi(v->value);
09205       } else if (!strcasecmp(v->name, "pingtime")) 
09206          ping_time = atoi(v->value);
09207       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09208          if (reload) {
09209             if (atoi(v->value) != iaxthreadcount)
09210                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09211          } else {
09212             iaxthreadcount = atoi(v->value);
09213             if (iaxthreadcount < 1) {
09214                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09215                iaxthreadcount = 1;
09216             } else if (iaxthreadcount > 256) {
09217                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09218                iaxthreadcount = 256;
09219             }
09220          }
09221       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09222          if (reload) {
09223             AST_LIST_LOCK(&dynamic_list);
09224             iaxmaxthreadcount = atoi(v->value);
09225             AST_LIST_UNLOCK(&dynamic_list);
09226          } else {
09227             iaxmaxthreadcount = atoi(v->value);
09228             if (iaxmaxthreadcount < 0) {
09229                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09230                iaxmaxthreadcount = 0;
09231             } else if (iaxmaxthreadcount > 256) {
09232                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09233                iaxmaxthreadcount = 256;
09234             }
09235          }
09236       } else if (!strcasecmp(v->name, "nochecksums")) {
09237 #ifdef SO_NO_CHECK
09238          if (ast_true(v->value))
09239             nochecksums = 1;
09240          else
09241             nochecksums = 0;
09242 #else
09243          if (ast_true(v->value))
09244             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09245 #endif
09246       }
09247       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09248          maxjitterbuffer = atoi(v->value);
09249       else if (!strcasecmp(v->name, "resyncthreshold")) 
09250          resyncthreshold = atoi(v->value);
09251       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09252          maxjitterinterps = atoi(v->value);
09253       else if (!strcasecmp(v->name, "lagrqtime")) 
09254          lagrq_time = atoi(v->value);
09255       else if (!strcasecmp(v->name, "maxregexpire")) 
09256          max_reg_expire = atoi(v->value);
09257       else if (!strcasecmp(v->name, "minregexpire")) 
09258          min_reg_expire = atoi(v->value);
09259       else if (!strcasecmp(v->name, "bindaddr")) {
09260          if (reload) {
09261             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09262          } else {
09263             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09264                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09265             } else {
09266                if (option_verbose > 1) {
09267                   if (strchr(v->value, ':'))
09268                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09269                   else
09270                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09271                }
09272                if (defaultsockfd < 0) 
09273                   defaultsockfd = ast_netsock_sockfd(ns);
09274                ast_netsock_unref(ns);
09275             }
09276          }
09277       } else if (!strcasecmp(v->name, "authdebug"))
09278          authdebug = ast_true(v->value);
09279       else if (!strcasecmp(v->name, "encryption"))
09280          iax2_encryption = get_encrypt_methods(v->value);
09281       else if (!strcasecmp(v->name, "notransfer")) {
09282          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09283          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09284          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09285       } else if (!strcasecmp(v->name, "transfer")) {
09286          if (!strcasecmp(v->value, "mediaonly")) {
09287             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09288          } else if (ast_true(v->value)) {
09289             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09290          } else 
09291             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09292       } else if (!strcasecmp(v->name, "codecpriority")) {
09293          if(!strcasecmp(v->value, "caller"))
09294             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09295          else if(!strcasecmp(v->value, "disabled"))
09296             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09297          else if(!strcasecmp(v->value, "reqonly")) {
09298             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09299             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09300          }
09301       } else if (!strcasecmp(v->name, "jitterbuffer"))
09302          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
09303       else if (!strcasecmp(v->name, "forcejitterbuffer"))
09304          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
09305       else if (!strcasecmp(v->name, "delayreject"))
09306          delayreject = ast_true(v->value);
09307       else if (!strcasecmp(v->name, "rtcachefriends"))
09308          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
09309       else if (!strcasecmp(v->name, "rtignoreregexpire"))
09310          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
09311       else if (!strcasecmp(v->name, "rtupdate"))
09312          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09313       else if (!strcasecmp(v->name, "trunktimestamps"))
09314          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09315       else if (!strcasecmp(v->name, "rtautoclear")) {
09316          int i = atoi(v->value);
09317          if(i > 0)
09318             global_rtautoclear = i;
09319          else
09320             i = 0;
09321          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
09322       } else if (!strcasecmp(v->name, "trunkfreq")) {
09323          trunkfreq = atoi(v->value);
09324          if (trunkfreq < 10)
09325             trunkfreq = 10;
09326       } else if (!strcasecmp(v->name, "autokill")) {
09327          if (sscanf(v->value, "%d", &x) == 1) {
09328             if (x >= 0)
09329                autokill = x;
09330             else
09331                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09332          } else if (ast_true(v->value)) {
09333             autokill = DEFAULT_MAXMS;
09334          } else {
09335             autokill = 0;
09336          }
09337       } else if (!strcasecmp(v->name, "bandwidth")) {
09338          if (!strcasecmp(v->value, "low")) {
09339             capability = IAX_CAPABILITY_LOWBANDWIDTH;
09340          } else if (!strcasecmp(v->value, "medium")) {
09341             capability = IAX_CAPABILITY_MEDBANDWIDTH;
09342          } else if (!strcasecmp(v->value, "high")) {
09343             capability = IAX_CAPABILITY_FULLBANDWIDTH;
09344          } else
09345             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09346       } else if (!strcasecmp(v->name, "allow")) {
09347          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09348       } else if (!strcasecmp(v->name, "disallow")) {
09349          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09350       } else if (!strcasecmp(v->name, "register")) {
09351          iax2_register(v->value, v->lineno);
09352       } else if (!strcasecmp(v->name, "iaxcompat")) {
09353          iaxcompat = ast_true(v->value);
09354       } else if (!strcasecmp(v->name, "regcontext")) {
09355          ast_copy_string(regcontext, v->value, sizeof(regcontext));
09356          /* Create context if it doesn't exist already */
09357          if (!ast_context_find(regcontext))
09358             ast_context_create(NULL, regcontext, "IAX2");
09359       } else if (!strcasecmp(v->name, "tos")) {
09360          if (ast_str2tos(v->value, &tos))
09361             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09362       } else if (!strcasecmp(v->name, "accountcode")) {
09363          ast_copy_string(accountcode, v->value, sizeof(accountcode));
09364       } else if (!strcasecmp(v->name, "mohinterpret")) {
09365          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09366       } else if (!strcasecmp(v->name, "mohsuggest")) {
09367          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09368       } else if (!strcasecmp(v->name, "amaflags")) {
09369          format = ast_cdr_amaflags2int(v->value);
09370          if (format < 0) {
09371             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09372          } else {
09373             amaflags = format;
09374          }
09375       } else if (!strcasecmp(v->name, "language")) {
09376          ast_copy_string(language, v->value, sizeof(language));
09377       } else if (!strcasecmp(v->name, "maxauthreq")) {
09378          maxauthreq = atoi(v->value);
09379          if (maxauthreq < 0)
09380             maxauthreq = 0;
09381       } else if (!strcasecmp(v->name, "adsi")) {
09382          adsi = ast_true(v->value);
09383       } /*else if (strcasecmp(v->name,"type")) */
09384       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09385       v = v->next;
09386    }
09387    
09388    if (defaultsockfd < 0) {
09389       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09390          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09391       } else {
09392          if (option_verbose > 1)
09393             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09394          defaultsockfd = ast_netsock_sockfd(ns);
09395          ast_netsock_unref(ns);
09396       }
09397    }
09398    if (reload) {
09399       ast_netsock_release(outsock);
09400       outsock = ast_netsock_list_alloc();
09401       if (!outsock) {
09402          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09403          return -1;
09404       }
09405       ast_netsock_init(outsock);
09406    }
09407 
09408    if (min_reg_expire > max_reg_expire) {
09409       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09410          min_reg_expire, max_reg_expire, max_reg_expire);
09411       min_reg_expire = max_reg_expire;
09412    }
09413    iax2_capability = capability;
09414    
09415    ucfg = ast_config_load("users.conf");
09416    if (ucfg) {
09417       struct ast_variable *gen;
09418       int genhasiax;
09419       int genregisteriax;
09420       const char *hasiax, *registeriax;
09421       
09422       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09423       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09424       gen = ast_variable_browse(ucfg, "general");
09425       cat = ast_category_browse(ucfg, NULL);
09426       while (cat) {
09427          if (strcasecmp(cat, "general")) {
09428             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09429             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09430             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09431                /* Start with general parameters, then specific parameters, user and peer */
09432                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09433                if (user) {
09434                   AST_LIST_LOCK(&users);
09435                   AST_LIST_INSERT_HEAD(&users, user, entry);
09436                   AST_LIST_UNLOCK(&users);
09437                }
09438                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09439                if (peer) {
09440                   AST_LIST_LOCK(&peers);
09441                   AST_LIST_INSERT_HEAD(&peers, peer, entry);
09442                   AST_LIST_UNLOCK(&peers);
09443                   if (ast_test_flag(peer, IAX_DYNAMIC))
09444                      reg_source_db(peer);
09445                }
09446             }
09447             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09448                char tmp[256];
09449                const char *host = ast_variable_retrieve(ucfg, cat, "host");
09450                const char *username = ast_variable_retrieve(ucfg, cat, "username");
09451                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09452                if (!host)
09453                   host = ast_variable_retrieve(ucfg, "general", "host");
09454                if (!username)
09455                   username = ast_variable_retrieve(ucfg, "general", "username");
09456                if (!secret)
09457                   secret = ast_variable_retrieve(ucfg, "general", "secret");
09458                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09459                   if (!ast_strlen_zero(secret))
09460                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09461                   else
09462                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09463                   iax2_register(tmp, 0);
09464                }
09465             }
09466          }
09467          cat = ast_category_browse(ucfg, cat);
09468       }
09469       ast_config_destroy(ucfg);
09470    }
09471    
09472    cat = ast_category_browse(cfg, NULL);
09473    while(cat) {
09474       if (strcasecmp(cat, "general")) {
09475          utype = ast_variable_retrieve(cfg, cat, "type");
09476          if (utype) {
09477             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09478                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09479                if (user) {
09480                   AST_LIST_LOCK(&users);
09481                   AST_LIST_INSERT_HEAD(&users, user, entry);
09482                   AST_LIST_UNLOCK(&users);
09483                }
09484             }
09485             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09486                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09487                if (peer) {
09488                   AST_LIST_LOCK(&peers);
09489                   AST_LIST_INSERT_HEAD(&peers, peer, entry);
09490                   AST_LIST_UNLOCK(&peers);
09491                   if (ast_test_flag(peer, IAX_DYNAMIC))
09492                      reg_source_db(peer);
09493                }
09494             } else if (strcasecmp(utype, "user")) {
09495                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
09496             }
09497          } else
09498             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
09499       }
09500       cat = ast_category_browse(cfg, cat);
09501    }
09502    ast_config_destroy(cfg);
09503    set_timing();
09504    return capability;
09505 }
09506 
09507 static int reload_config(void)
09508 {
09509    char *config = "iax.conf";
09510    struct iax2_registry *reg;
09511    struct iax2_peer *peer;
09512 
09513    strcpy(accountcode, "");
09514    strcpy(language, "");
09515    strcpy(mohinterpret, "default");
09516    strcpy(mohsuggest, "");
09517    amaflags = 0;
09518    delayreject = 0;
09519    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09520    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09521    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09522    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09523    delete_users();
09524    set_config(config, 1);
09525    prune_peers();
09526    prune_users();
09527    AST_LIST_LOCK(&registrations);
09528    AST_LIST_TRAVERSE(&registrations, reg, entry)
09529       iax2_do_register(reg);
09530    AST_LIST_UNLOCK(&registrations);
09531    /* Qualify hosts, too */
09532    AST_LIST_LOCK(&peers);
09533    AST_LIST_TRAVERSE(&peers, peer, entry)
09534       iax2_poke_peer(peer, 0);
09535    AST_LIST_UNLOCK(&peers);
09536    reload_firmware();
09537    iax_provision_reload();
09538 
09539    return 0;
09540 }
09541 
09542 static int iax2_reload(int fd, int argc, char *argv[])
09543 {
09544    return reload_config();
09545 }
09546 
09547 static int reload(void)
09548 {
09549    return reload_config();
09550 }
09551 
09552 static int cache_get_callno_locked(const char *data)
09553 {
09554    struct sockaddr_in sin;
09555    int x;
09556    int callno;
09557    struct iax_ie_data ied;
09558    struct create_addr_info cai;
09559    struct parsed_dial_string pds;
09560    char *tmpstr;
09561 
09562    for (x=0; x<IAX_MAX_CALLS; x++) {
09563       /* Look for an *exact match* call.  Once a call is negotiated, it can only
09564          look up entries for a single context */
09565       if (!ast_mutex_trylock(&iaxsl[x])) {
09566          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09567             return x;
09568          ast_mutex_unlock(&iaxsl[x]);
09569       }
09570    }
09571 
09572    /* No match found, we need to create a new one */
09573 
09574    memset(&cai, 0, sizeof(cai));
09575    memset(&ied, 0, sizeof(ied));
09576    memset(&pds, 0, sizeof(pds));
09577 
09578    tmpstr = ast_strdupa(data);
09579    parse_dial_string(tmpstr, &pds);
09580 
09581    /* Populate our address from the given */
09582    if (create_addr(pds.peer, &sin, &cai))
09583       return -1;
09584 
09585    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09586       pds.peer, pds.username, pds.password, pds.context);
09587 
09588    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09589    if (callno < 1) {
09590       ast_log(LOG_WARNING, "Unable to create call\n");
09591       return -1;
09592    }
09593 
09594    ast_mutex_lock(&iaxsl[callno]);
09595    ast_string_field_set(iaxs[callno], dproot, data);
09596    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09597 
09598    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09599    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09600    /* the string format is slightly different from a standard dial string,
09601       because the context appears in the 'exten' position
09602    */
09603    if (pds.exten)
09604       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09605    if (pds.username)
09606       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09607    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09608    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09609    /* Keep password handy */
09610    if (pds.password)
09611       ast_string_field_set(iaxs[callno], secret, pds.password);
09612    if (pds.key)
09613       ast_string_field_set(iaxs[callno], outkey, pds.key);
09614    /* Start the call going */
09615    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09616 
09617    return callno;
09618 }
09619 
09620 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
09621 {
09622    struct iax2_dpcache *dp, *prev = NULL, *next;
09623    struct timeval tv;
09624    int x;
09625    int com[2];
09626    int timeout;
09627    int old=0;
09628    int outfd;
09629    int abort;
09630    int callno;
09631    struct ast_channel *c;
09632    struct ast_frame *f;
09633    gettimeofday(&tv, NULL);
09634    dp = dpcache;
09635    while(dp) {
09636       next = dp->next;
09637       /* Expire old caches */
09638       if (ast_tvcmp(tv, dp->expiry) > 0) {
09639             /* It's expired, let it disappear */
09640             if (prev)
09641                prev->next = dp->next;
09642             else
09643                dpcache = dp->next;
09644             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09645                /* Free memory and go again */
09646                free(dp);
09647             } else {
09648                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);
09649             }
09650             dp = next;
09651             continue;
09652       }
09653       /* We found an entry that matches us! */
09654       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
09655          break;
09656       prev = dp;
09657       dp = next;
09658    }
09659    if (!dp) {
09660       /* No matching entry.  Create a new one. */
09661       /* First, can we make a callno? */
09662       callno = cache_get_callno_locked(data);
09663       if (callno < 0) {
09664          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09665          return NULL;
09666       }
09667       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
09668          ast_mutex_unlock(&iaxsl[callno]);
09669          return NULL;
09670       }
09671       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09672       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09673       gettimeofday(&dp->expiry, NULL);
09674       dp->orig = dp->expiry;
09675       /* Expires in 30 mins by default */
09676       dp->expiry.tv_sec += iaxdefaultdpcache;
09677       dp->next = dpcache;
09678       dp->flags = CACHE_FLAG_PENDING;
09679       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09680          dp->waiters[x] = -1;
09681       dpcache = dp;
09682       dp->peer = iaxs[callno]->dpentries;
09683       iaxs[callno]->dpentries = dp;
09684       /* Send the request if we're already up */
09685       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09686          iax2_dprequest(dp, callno);
09687       ast_mutex_unlock(&iaxsl[callno]);
09688    }
09689    /* By here we must have a dp */
09690    if (dp->flags & CACHE_FLAG_PENDING) {
09691       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09692          for a reply to come back so long as it's pending */
09693       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09694          /* Find an empty slot */
09695          if (dp->waiters[x] < 0)
09696             break;
09697       }
09698       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09699          ast_log(LOG_WARNING, "No more waiter positions available\n");
09700          return NULL;
09701       }
09702       if (pipe(com)) {
09703          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09704          return NULL;
09705       }
09706       dp->waiters[x] = com[1];
09707       /* Okay, now we wait */
09708       timeout = iaxdefaulttimeout * 1000;
09709       /* Temporarily unlock */
09710       ast_mutex_unlock(&dpcache_lock);
09711       /* Defer any dtmf */
09712       if (chan)
09713          old = ast_channel_defer_dtmf(chan);
09714       abort = 0;
09715       while(timeout) {
09716          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09717          if (outfd > -1) {
09718             break;
09719          }
09720          if (c) {
09721             f = ast_read(c);
09722             if (f)
09723                ast_frfree(f);
09724             else {
09725                /* Got hung up on, abort! */
09726                break;
09727                abort = 1;
09728             }
09729          }
09730       }
09731       if (!timeout) {
09732          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09733       }
09734       ast_mutex_lock(&dpcache_lock);
09735       dp->waiters[x] = -1;
09736       close(com[1]);
09737       close(com[0]);
09738       if (abort) {
09739          /* Don't interpret anything, just abort.  Not sure what th epoint
09740            of undeferring dtmf on a hung up channel is but hey whatever */
09741          if (!old && chan)
09742             ast_channel_undefer_dtmf(chan);
09743          return NULL;
09744       }
09745       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09746          /* Now to do non-independent analysis the results of our wait */
09747          if (dp->flags & CACHE_FLAG_PENDING) {
09748             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09749                pending.  Don't let it take as long to timeout. */
09750             dp->flags &= ~CACHE_FLAG_PENDING;
09751             dp->flags |= CACHE_FLAG_TIMEOUT;
09752             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09753                systems without leaving it unavailable once the server comes back online */
09754             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09755             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09756                if (dp->waiters[x] > -1)
09757                   write(dp->waiters[x], "asdf", 4);
09758          }
09759       }
09760       /* Our caller will obtain the rest */
09761       if (!old && chan)
09762          ast_channel_undefer_dtmf(chan);
09763    }
09764    return dp;  
09765 }
09766 
09767 /*! \brief Part of the IAX2 switch interface */
09768 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09769 {
09770    struct iax2_dpcache *dp;
09771    int res = 0;
09772 #if 0
09773    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09774 #endif
09775    if ((priority != 1) && (priority != 2))
09776       return 0;
09777    ast_mutex_lock(&dpcache_lock);
09778    dp = find_cache(chan, data, context, exten, priority);
09779    if (dp) {
09780       if (dp->flags & CACHE_FLAG_EXISTS)
09781          res= 1;
09782    }
09783    ast_mutex_unlock(&dpcache_lock);
09784    if (!dp) {
09785       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09786    }
09787    return res;
09788 }
09789 
09790 /*! \brief part of the IAX2 dial plan switch interface */
09791 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09792 {
09793    int res = 0;
09794    struct iax2_dpcache *dp;
09795 #if 0
09796    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09797 #endif
09798    if ((priority != 1) && (priority != 2))
09799       return 0;
09800    ast_mutex_lock(&dpcache_lock);
09801    dp = find_cache(chan, data, context, exten, priority);
09802    if (dp) {
09803       if (dp->flags & CACHE_FLAG_CANEXIST)
09804          res= 1;
09805    }
09806    ast_mutex_unlock(&dpcache_lock);
09807    if (!dp) {
09808       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09809    }
09810    return res;
09811 }
09812 
09813 /*! \brief Part of the IAX2 Switch interface */
09814 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09815 {
09816    int res = 0;
09817    struct iax2_dpcache *dp;
09818 #if 0
09819    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09820 #endif
09821    if ((priority != 1) && (priority != 2))
09822       return 0;
09823    ast_mutex_lock(&dpcache_lock);
09824    dp = find_cache(chan, data, context, exten, priority);
09825    if (dp) {
09826       if (dp->flags & CACHE_FLAG_MATCHMORE)
09827          res= 1;
09828    }
09829    ast_mutex_unlock(&dpcache_lock);
09830    if (!dp) {
09831       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09832    }
09833    return res;
09834 }
09835 
09836 /*! \brief Execute IAX2 dialplan switch */
09837 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09838 {
09839    char odata[256];
09840    char req[256];
09841    char *ncontext;
09842    struct iax2_dpcache *dp;
09843    struct ast_app *dial;
09844 #if 0
09845    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);
09846 #endif
09847    if (priority == 2) {
09848       /* Indicate status, can be overridden in dialplan */
09849       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09850       if (dialstatus) {
09851          dial = pbx_findapp(dialstatus);
09852          if (dial) 
09853             pbx_exec(chan, dial, "");
09854       }
09855       return -1;
09856    } else if (priority != 1)
09857       return -1;
09858    ast_mutex_lock(&dpcache_lock);
09859    dp = find_cache(chan, data, context, exten, priority);
09860    if (dp) {
09861       if (dp->flags & CACHE_FLAG_EXISTS) {
09862          ast_copy_string(odata, data, sizeof(odata));
09863          ncontext = strchr(odata, '/');
09864          if (ncontext) {
09865             *ncontext = '\0';
09866             ncontext++;
09867             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09868          } else {
09869             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09870          }
09871          if (option_verbose > 2)
09872             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09873       } else {
09874          ast_mutex_unlock(&dpcache_lock);
09875          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09876          return -1;
09877       }
09878    }
09879    ast_mutex_unlock(&dpcache_lock);
09880    dial = pbx_findapp("Dial");
09881    if (dial) {
09882       return pbx_exec(chan, dial, req);
09883    } else {
09884       ast_log(LOG_WARNING, "No dial application registered\n");
09885    }
09886    return -1;
09887 }
09888 
09889 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
09890 {
09891    struct iax2_peer *peer;
09892    char *peername, *colname;
09893 
09894    peername = ast_strdupa(data);
09895 
09896    /* if our channel, return the IP address of the endpoint of current channel */
09897    if (!strcmp(peername,"CURRENTCHANNEL")) {
09898            unsigned short callno;
09899       if (chan->tech != &iax2_tech)
09900          return -1;
09901       callno = PTR_TO_CALLNO(chan->tech_pvt);   
09902       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
09903       return 0;
09904    }
09905 
09906    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
09907       *colname++ = '\0';
09908    else if ((colname = strchr(peername, '|')))
09909       *colname++ = '\0';
09910    else
09911       colname = "ip";
09912 
09913    if (!(peer = find_peer(peername, 1)))
09914       return -1;
09915 
09916    if (!strcasecmp(colname, "ip")) {
09917       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
09918    } else  if (!strcasecmp(colname, "status")) {
09919       peer_status(peer, buf, len); 
09920    } else  if (!strcasecmp(colname, "mailbox")) {
09921       ast_copy_string(buf, peer->mailbox, len);
09922    } else  if (!strcasecmp(colname, "context")) {
09923       ast_copy_string(buf, peer->context, len);
09924    } else  if (!strcasecmp(colname, "expire")) {
09925       snprintf(buf, len, "%d", peer->expire);
09926    } else  if (!strcasecmp(colname, "dynamic")) {
09927       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09928    } else  if (!strcasecmp(colname, "callerid_name")) {
09929       ast_copy_string(buf, peer->cid_name, len);
09930    } else  if (!strcasecmp(colname, "callerid_num")) {
09931       ast_copy_string(buf, peer->cid_num, len);
09932    } else  if (!strcasecmp(colname, "codecs")) {
09933       ast_getformatname_multiple(buf, len -1, peer->capability);
09934    } else  if (!strncasecmp(colname, "codec[", 6)) {
09935       char *codecnum, *ptr;
09936       int index = 0, codec = 0;
09937       
09938       codecnum = strchr(colname, '[');
09939       *codecnum = '\0';
09940       codecnum++;
09941       if ((ptr = strchr(codecnum, ']'))) {
09942          *ptr = '\0';
09943       }
09944       index = atoi(codecnum);
09945       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09946          ast_copy_string(buf, ast_getformatname(codec), len);
09947       }
09948    }
09949 
09950    return 0;
09951 }
09952 
09953 struct ast_custom_function iaxpeer_function = {
09954    .name = "IAXPEER",
09955    .synopsis = "Gets IAX peer information",
09956    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
09957    .read = function_iaxpeer,
09958    .desc = "If peername specified, valid items are:\n"
09959    "- ip (default)          The IP address.\n"
09960    "- status                The peer's status (if qualify=yes)\n"
09961    "- mailbox               The configured mailbox.\n"
09962    "- context               The configured context.\n"
09963    "- expire                The epoch time of the next expire.\n"
09964    "- dynamic               Is it dynamic? (yes/no).\n"
09965    "- callerid_name         The configured Caller ID name.\n"
09966    "- callerid_num          The configured Caller ID number.\n"
09967    "- codecs                The configured codecs.\n"
09968    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
09969    "\n"
09970    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
09971    "\n"
09972 };
09973 
09974 
09975 /*! \brief Part of the device state notification system ---*/
09976 static int iax2_devicestate(void *data) 
09977 {
09978    struct parsed_dial_string pds;
09979    char *tmp = ast_strdupa(data);
09980    struct iax2_peer *p;
09981    int res = AST_DEVICE_INVALID;
09982 
09983    memset(&pds, 0, sizeof(pds));
09984    parse_dial_string(tmp, &pds);
09985    if (ast_strlen_zero(pds.peer))
09986       return res;
09987    
09988    if (option_debug > 2)
09989       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09990 
09991    /* SLD: FIXME: second call to find_peer during registration */
09992    if (!(p = find_peer(pds.peer, 1)))
09993       return res;
09994 
09995    res = AST_DEVICE_UNAVAILABLE;
09996    if (option_debug > 2) 
09997       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09998          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09999    
10000    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10001        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10002       /* Peer is registered, or have default IP address
10003          and a valid registration */
10004       if (p->historicms == 0 || p->historicms <= p->maxms)
10005          /* let the core figure out whether it is in use or not */
10006          res = AST_DEVICE_UNKNOWN;  
10007    }
10008 
10009    if (ast_test_flag(p, IAX_TEMPONLY))
10010       destroy_peer(p);
10011 
10012    return res;
10013 }
10014 
10015 static struct ast_switch iax2_switch = 
10016 {
10017    name:          "IAX2",
10018    description:      "IAX Remote Dialplan Switch",
10019    exists:        iax2_exists,
10020    canmatch:      iax2_canmatch,
10021    exec:       iax2_exec,
10022    matchmore:     iax2_matchmore,
10023 };
10024 
10025 static char show_stats_usage[] =
10026 "Usage: iax2 show stats\n"
10027 "       Display statistics on IAX channel driver.\n";
10028 
10029 static char show_cache_usage[] =
10030 "Usage: iax2 show cache\n"
10031 "       Display currently cached IAX Dialplan results.\n";
10032 
10033 static char show_peer_usage[] =
10034 "Usage: iax2 show peer <name>\n"
10035 "       Display details on specific IAX peer\n";
10036 
10037 static char prune_realtime_usage[] =
10038 "Usage: iax2 prune realtime [<peername>|all]\n"
10039 "       Prunes object(s) from the cache\n";
10040 
10041 static char iax2_reload_usage[] =
10042 "Usage: iax2 reload\n"
10043 "       Reloads IAX configuration from iax.conf\n";
10044 
10045 static char show_prov_usage[] =
10046 "Usage: iax2 provision <host> <template> [forced]\n"
10047 "       Provisions the given peer or IP address using a template\n"
10048 "       matching either 'template' or '*' if the template is not\n"
10049 "       found.  If 'forced' is specified, even empty provisioning\n"
10050 "       fields will be provisioned as empty fields.\n";
10051 
10052 static char show_users_usage[] = 
10053 "Usage: iax2 show users [like <pattern>]\n"
10054 "       Lists all known IAX2 users.\n"
10055 "       Optional regular expression pattern is used to filter the user list.\n";
10056 
10057 static char show_channels_usage[] = 
10058 "Usage: iax2 show channels\n"
10059 "       Lists all currently active IAX channels.\n";
10060 
10061 static char show_netstats_usage[] = 
10062 "Usage: iax2 show netstats\n"
10063 "       Lists network status for all currently active IAX channels.\n";
10064 
10065 static char show_threads_usage[] = 
10066 "Usage: iax2 show threads\n"
10067 "       Lists status of IAX helper threads\n";
10068 
10069 static char show_peers_usage[] = 
10070 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10071 "       Lists all known IAX2 peers.\n"
10072 "       Optional 'registered' argument lists only peers with known addresses.\n"
10073 "       Optional regular expression pattern is used to filter the peer list.\n";
10074 
10075 static char show_firmware_usage[] = 
10076 "Usage: iax2 show firmware\n"
10077 "       Lists all known IAX firmware images.\n";
10078 
10079 static char show_reg_usage[] =
10080 "Usage: iax2 show registry\n"
10081 "       Lists all registration requests and status.\n";
10082 
10083 static char debug_usage[] = 
10084 "Usage: iax2 set debug\n"
10085 "       Enables dumping of IAX packets for debugging purposes\n";
10086 
10087 static char no_debug_usage[] = 
10088 "Usage: iax2 set debug off\n"
10089 "       Disables dumping of IAX packets for debugging purposes\n";
10090 
10091 static char debug_trunk_usage[] =
10092 "Usage: iax2 set debug trunk\n"
10093 "       Requests current status of IAX trunking\n";
10094 
10095 static char no_debug_trunk_usage[] =
10096 "Usage: iax2 set debug trunk off\n"
10097 "       Requests current status of IAX trunking\n";
10098 
10099 static char debug_jb_usage[] =
10100 "Usage: iax2 set debug jb\n"
10101 "       Enables jitterbuffer debugging information\n";
10102 
10103 static char no_debug_jb_usage[] =
10104 "Usage: iax2 set debug jb off\n"
10105 "       Disables jitterbuffer debugging information\n";
10106 
10107 static char iax2_test_losspct_usage[] =
10108 "Usage: iax2 test losspct <percentage>\n"
10109 "       For testing, throws away <percentage> percent of incoming packets\n";
10110 
10111 #ifdef IAXTESTS
10112 static char iax2_test_late_usage[] =
10113 "Usage: iax2 test late <ms>\n"
10114 "       For testing, count the next frame as <ms> ms late\n";
10115 
10116 static char iax2_test_resync_usage[] =
10117 "Usage: iax2 test resync <ms>\n"
10118 "       For testing, adjust all future frames by <ms> ms\n";
10119 
10120 static char iax2_test_jitter_usage[] =
10121 "Usage: iax2 test jitter <ms> <pct>\n"
10122 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10123 #endif /* IAXTESTS */
10124 
10125 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10126    { "iax2", "trunk", "debug", NULL },
10127    iax2_do_trunk_debug, NULL,
10128    NULL };
10129 
10130 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10131    { "iax2", "jb", "debug", NULL },
10132    iax2_do_jb_debug, NULL,
10133    NULL };
10134 
10135 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10136    { "iax2", "no", "debug", NULL },
10137    iax2_no_debug, NULL,
10138    NULL };
10139 
10140 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10141    { "iax2", "no", "trunk", "debug", NULL },
10142    iax2_no_trunk_debug, NULL,
10143    NULL };
10144 
10145 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10146    { "iax2", "no", "jb", "debug", NULL },
10147    iax2_no_jb_debug, NULL,
10148    NULL };
10149 
10150 static struct ast_cli_entry cli_iax2[] = {
10151    { { "iax2", "show", "cache", NULL },
10152    iax2_show_cache, "Display IAX cached dialplan",
10153    show_cache_usage, NULL, },
10154 
10155    { { "iax2", "show", "channels", NULL },
10156    iax2_show_channels, "List active IAX channels",
10157    show_channels_usage, NULL, },
10158 
10159    { { "iax2", "show", "firmware", NULL },
10160    iax2_show_firmware, "List available IAX firmwares",
10161    show_firmware_usage, NULL, },
10162 
10163    { { "iax2", "show", "netstats", NULL },
10164    iax2_show_netstats, "List active IAX channel netstats",
10165    show_netstats_usage, NULL, },
10166 
10167    { { "iax2", "show", "peers", NULL },
10168    iax2_show_peers, "List defined IAX peers",
10169    show_peers_usage, NULL, },
10170 
10171    { { "iax2", "show", "registry", NULL },
10172    iax2_show_registry, "Display IAX registration status",
10173    show_reg_usage, NULL, },
10174 
10175    { { "iax2", "show", "stats", NULL },
10176    iax2_show_stats, "Display IAX statistics",
10177    show_stats_usage, NULL, },
10178 
10179    { { "iax2", "show", "threads", NULL },
10180    iax2_show_threads, "Display IAX helper thread info",
10181    show_threads_usage, NULL, },
10182 
10183    { { "iax2", "show", "users", NULL },
10184    iax2_show_users, "List defined IAX users",
10185    show_users_usage, NULL, },
10186 
10187    { { "iax2", "prune", "realtime", NULL },
10188    iax2_prune_realtime, "Prune a cached realtime lookup",
10189    prune_realtime_usage, complete_iax2_show_peer },
10190 
10191    { { "iax2", "reload", NULL },
10192    iax2_reload, "Reload IAX configuration",
10193    iax2_reload_usage },
10194 
10195    { { "iax2", "show", "peer", NULL },
10196    iax2_show_peer, "Show details on specific IAX peer",
10197    show_peer_usage, complete_iax2_show_peer },
10198 
10199    { { "iax2", "set", "debug", NULL },
10200    iax2_do_debug, "Enable IAX debugging",
10201    debug_usage },
10202 
10203    { { "iax2", "set", "debug", "trunk", NULL },
10204    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10205    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10206 
10207    { { "iax2", "set", "debug", "jb", NULL },
10208    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10209    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10210 
10211    { { "iax2", "set", "debug", "off", NULL },
10212    iax2_no_debug, "Disable IAX debugging",
10213    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10214 
10215    { { "iax2", "set", "debug", "trunk", "off", NULL },
10216    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10217    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10218 
10219    { { "iax2", "set", "debug", "jb", "off", NULL },
10220    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10221    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10222 
10223    { { "iax2", "test", "losspct", NULL },
10224    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10225    iax2_test_losspct_usage },
10226 
10227    { { "iax2", "provision", NULL },
10228    iax2_prov_cmd, "Provision an IAX device",
10229    show_prov_usage, iax2_prov_complete_template_3rd },
10230 
10231 #ifdef IAXTESTS
10232    { { "iax2", "test", "late", NULL },
10233    iax2_test_late, "Test the receipt of a late frame",
10234    iax2_test_late_usage },
10235 
10236    { { "iax2", "test", "resync", NULL },
10237    iax2_test_resync, "Test a resync in received timestamps",
10238    iax2_test_resync_usage },
10239 
10240    { { "iax2", "test", "jitter", NULL },
10241    iax2_test_jitter, "Simulates jitter for testing",
10242    iax2_test_jitter_usage },
10243 #endif /* IAXTESTS */
10244 };
10245 
10246 static int __unload_module(void)
10247 {
10248    struct iax2_thread *thread = NULL;
10249    int x;
10250 
10251    /* Make sure threads do not hold shared resources when they are canceled */
10252    
10253    /* Grab the sched lock resource to keep it away from threads about to die */
10254    /* Cancel the network thread, close the net socket */
10255    if (netthreadid != AST_PTHREADT_NULL) {
10256       AST_LIST_LOCK(&iaxq.queue);
10257       ast_mutex_lock(&sched_lock);
10258       pthread_cancel(netthreadid);
10259       ast_cond_signal(&sched_cond);
10260       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10261       AST_LIST_UNLOCK(&iaxq.queue);
10262       pthread_join(netthreadid, NULL);
10263    }
10264    if (schedthreadid != AST_PTHREADT_NULL) {
10265       ast_mutex_lock(&sched_lock);  
10266       pthread_cancel(schedthreadid);
10267       ast_cond_signal(&sched_cond);
10268       ast_mutex_unlock(&sched_lock);   
10269       pthread_join(schedthreadid, NULL);
10270    }
10271    
10272    /* Call for all threads to halt */
10273    AST_LIST_LOCK(&idle_list);
10274    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10275       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10276       pthread_cancel(thread->threadid);
10277    }
10278    AST_LIST_TRAVERSE_SAFE_END
10279    AST_LIST_UNLOCK(&idle_list);
10280 
10281    AST_LIST_LOCK(&active_list);
10282    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10283       AST_LIST_REMOVE_CURRENT(&active_list, list);
10284       pthread_cancel(thread->threadid);
10285    }
10286    AST_LIST_TRAVERSE_SAFE_END
10287    AST_LIST_UNLOCK(&active_list);
10288 
10289    AST_LIST_LOCK(&dynamic_list);
10290         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10291       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10292       pthread_cancel(thread->threadid);
10293         }
10294    AST_LIST_TRAVERSE_SAFE_END
10295         AST_LIST_UNLOCK(&dynamic_list);
10296 
10297    AST_LIST_HEAD_DESTROY(&iaxq.queue);
10298 
10299    /* Wait for threads to exit */
10300    while(0 < iaxactivethreadcount)
10301       usleep(10000);
10302    
10303    ast_netsock_release(netsock);
10304    ast_netsock_release(outsock);
10305    for (x=0;x<IAX_MAX_CALLS;x++)
10306       if (iaxs[x])
10307          iax2_destroy(x);
10308    ast_manager_unregister( "IAXpeers" );
10309    ast_manager_unregister( "IAXnetstats" );
10310    ast_unregister_application(papp);
10311    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10312    ast_unregister_switch(&iax2_switch);
10313    ast_channel_unregister(&iax2_tech);
10314    delete_users();
10315    iax_provision_unload();
10316    sched_context_destroy(sched);
10317 
10318    ast_mutex_destroy(&waresl.lock);
10319 
10320    for (x = 0; x < IAX_MAX_CALLS; x++)
10321       ast_mutex_destroy(&iaxsl[x]);
10322 
10323    return 0;
10324 }
10325 
10326 static int unload_module(void)
10327 {
10328    ast_custom_function_unregister(&iaxpeer_function);
10329    return __unload_module();
10330 }
10331 
10332 
10333 /*! \brief Load IAX2 module, load configuraiton ---*/
10334 static int load_module(void)
10335 {
10336    char *config = "iax.conf";
10337    int res = 0;
10338    int x;
10339    struct iax2_registry *reg = NULL;
10340    struct iax2_peer *peer = NULL;
10341    
10342    ast_custom_function_register(&iaxpeer_function);
10343 
10344    iax_set_output(iax_debug_output);
10345    iax_set_error(iax_error_output);
10346    jb_setoutput(jb_error_output, jb_warning_output, NULL);
10347    
10348 #ifdef HAVE_ZAPTEL
10349 #ifdef ZT_TIMERACK
10350    timingfd = open("/dev/zap/timer", O_RDWR);
10351    if (timingfd < 0)
10352 #endif
10353       timingfd = open("/dev/zap/pseudo", O_RDWR);
10354    if (timingfd < 0) 
10355       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10356 #endif      
10357 
10358    memset(iaxs, 0, sizeof(iaxs));
10359 
10360    for (x=0;x<IAX_MAX_CALLS;x++)
10361       ast_mutex_init(&iaxsl[x]);
10362    
10363    ast_cond_init(&sched_cond, NULL);
10364 
10365    io = io_context_create();
10366    sched = sched_context_create();
10367    
10368    if (!io || !sched) {
10369       ast_log(LOG_ERROR, "Out of memory\n");
10370       return -1;
10371    }
10372 
10373    netsock = ast_netsock_list_alloc();
10374    if (!netsock) {
10375       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10376       return -1;
10377    }
10378    ast_netsock_init(netsock);
10379 
10380    outsock = ast_netsock_list_alloc();
10381    if (!outsock) {
10382       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10383       return -1;
10384    }
10385    ast_netsock_init(outsock);
10386 
10387    ast_mutex_init(&waresl.lock);
10388 
10389    AST_LIST_HEAD_INIT(&iaxq.queue);
10390    
10391    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10392 
10393    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10394    
10395    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10396    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10397 
10398    if(set_config(config, 0) == -1)
10399       return AST_MODULE_LOAD_DECLINE;
10400 
10401    if (ast_channel_register(&iax2_tech)) {
10402       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10403       __unload_module();
10404       return -1;
10405    }
10406 
10407    if (ast_register_switch(&iax2_switch)) 
10408       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10409 
10410    res = start_network_thread();
10411    if (!res) {
10412       if (option_verbose > 1) 
10413          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10414    } else {
10415       ast_log(LOG_ERROR, "Unable to start network thread\n");
10416       ast_netsock_release(netsock);
10417       ast_netsock_release(outsock);
10418    }
10419 
10420    AST_LIST_LOCK(&registrations);
10421    AST_LIST_TRAVERSE(&registrations, reg, entry)
10422       iax2_do_register(reg);
10423    AST_LIST_UNLOCK(&registrations); 
10424 
10425    AST_LIST_LOCK(&peers);
10426    AST_LIST_TRAVERSE(&peers, peer, entry) {
10427       if (peer->sockfd < 0)
10428          peer->sockfd = defaultsockfd;
10429       iax2_poke_peer(peer, 0);
10430    }
10431    AST_LIST_UNLOCK(&peers);
10432    reload_firmware();
10433    iax_provision_reload();
10434    return res;
10435 }
10436 
10437 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10438       .load = load_module,
10439       .unload = unload_module,
10440       .reload = reload,
10441           );

Generated on Wed Aug 15 01:24:17 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3