Tue Nov 4 13:20:15 2008

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         <depend>res_features</depend>
00034  ***/
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061 
00062 #ifdef HAVE_ZAPTEL
00063 #include <sys/ioctl.h>
00064 #include <zaptel/zaptel.h>
00065 #endif
00066 
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h" 
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099 
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104 
00105 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00106    multithreaded mode. */
00107 #define SCHED_MULTITHREADED
00108 
00109 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00110    thread is actually doing. */
00111 #define DEBUG_SCHED_MULTITHREAD
00112 
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116 
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120 
00121 
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124 
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130 
00131 #define DEBUG_SUPPORT
00132 
00133 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00134 
00135 /* Sample over last 100 units to determine historic jitter */
00136 #define GAMMA (0.01)
00137 
00138 static struct ast_codec_pref prefs;
00139 
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00141 
00142 static char context[80] = "default";
00143 
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146 
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158 
00159 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00160 
00161 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00162 
00163 static unsigned int tos = 0;
00164 
00165 static int min_reg_expire;
00166 static int max_reg_expire;
00167 
00168 static int timingfd = -1;           /* Timing file descriptor */
00169 
00170 static struct ast_netsock_list *netsock;
00171 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00172 static int defaultsockfd = -1;
00173 
00174 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00175 
00176 /* Ethernet, etc */
00177 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00178 /* T1, maybe ISDN */
00179 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00180                 ~AST_FORMAT_SLINEAR &        \
00181                 ~AST_FORMAT_ULAW &        \
00182                 ~AST_FORMAT_ALAW &        \
00183                 ~AST_FORMAT_G722) 
00184 /* A modem */
00185 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00186                 ~AST_FORMAT_G726 &        \
00187                 ~AST_FORMAT_G726_AAL2 &      \
00188                 ~AST_FORMAT_ADPCM)
00189 
00190 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00191                 ~AST_FORMAT_G723_1)
00192 
00193 
00194 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00195 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00196 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00197 
00198 static   struct io_context *io;
00199 static   struct sched_context *sched;
00200 
00201 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00202 
00203 static int iaxdebug = 0;
00204 
00205 static int iaxtrunkdebug = 0;
00206 
00207 static int test_losspct = 0;
00208 #ifdef IAXTESTS
00209 static int test_late = 0;
00210 static int test_resync = 0;
00211 static int test_jit = 0;
00212 static int test_jitpct = 0;
00213 #endif /* IAXTESTS */
00214 
00215 static char accountcode[AST_MAX_ACCOUNT_CODE];
00216 static char mohinterpret[MAX_MUSICCLASS];
00217 static char mohsuggest[MAX_MUSICCLASS];
00218 static int amaflags = 0;
00219 static int adsi = 0;
00220 static int delayreject = 0;
00221 static int iax2_encryption = 0;
00222 
00223 static struct ast_flags globalflags = { 0 };
00224 
00225 static pthread_t netthreadid = AST_PTHREADT_NULL;
00226 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00227 AST_MUTEX_DEFINE_STATIC(sched_lock);
00228 static ast_cond_t sched_cond;
00229 
00230 enum {
00231    IAX_STATE_STARTED =     (1 << 0),
00232    IAX_STATE_AUTHENTICATED =  (1 << 1),
00233    IAX_STATE_TBD =      (1 << 2),
00234    IAX_STATE_UNCHANGED =      (1 << 3),
00235 } iax2_state;
00236 
00237 struct iax2_context {
00238    char context[AST_MAX_CONTEXT];
00239    struct iax2_context *next;
00240 };
00241 
00242 enum {
00243    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00244    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00245    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00246    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00247    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00248    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00249    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00250    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00251         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00252    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00253    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00254    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00255    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00256    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00257    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00258    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00259    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00260    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00261    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00262    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00263    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00264    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00265    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00266    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00267    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00268    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00269                        response, so that we've achieved a three-way handshake with
00270                        them before sending voice or anything else*/
00271    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00272 } iax2_flags;
00273 
00274 static int global_rtautoclear = 120;
00275 
00276 static int reload_config(void);
00277 static int iax2_reload(int fd, int argc, char *argv[]);
00278 
00279 
00280 struct iax2_user {
00281    AST_DECLARE_STRING_FIELDS(
00282       AST_STRING_FIELD(name);
00283       AST_STRING_FIELD(secret);
00284       AST_STRING_FIELD(dbsecret);
00285       AST_STRING_FIELD(accountcode);
00286       AST_STRING_FIELD(mohinterpret);
00287       AST_STRING_FIELD(mohsuggest);
00288       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00289       AST_STRING_FIELD(language);
00290       AST_STRING_FIELD(cid_num);
00291       AST_STRING_FIELD(cid_name);
00292    );
00293    
00294    int authmethods;
00295    int encmethods;
00296    int amaflags;
00297    int adsi;
00298    unsigned int flags;
00299    int capability;
00300    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00301    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00302    struct ast_codec_pref prefs;
00303    struct ast_ha *ha;
00304    struct iax2_context *contexts;
00305    struct ast_variable *vars;
00306 };
00307 
00308 struct iax2_peer {
00309    AST_DECLARE_STRING_FIELDS(
00310       AST_STRING_FIELD(name);
00311       AST_STRING_FIELD(username);
00312       AST_STRING_FIELD(secret);
00313       AST_STRING_FIELD(dbsecret);
00314       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00315 
00316       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00317       AST_STRING_FIELD(context);      /*!< For transfers only */
00318       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00319       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00320       AST_STRING_FIELD(mohinterpret);
00321       AST_STRING_FIELD(mohsuggest);
00322       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00323       /* Suggested caller id if registering */
00324       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00325       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00326       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00327    );
00328    struct ast_codec_pref prefs;
00329    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00330    struct sockaddr_in addr;
00331    int formats;
00332    int sockfd;             /*!< Socket to use for transmission */
00333    struct in_addr mask;
00334    int adsi;
00335    unsigned int flags;
00336 
00337    /* Dynamic Registration fields */
00338    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00339    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00340    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00341 
00342    int expire;             /*!< Schedule entry for expiry */
00343    int expiry;             /*!< How soon to expire */
00344    int capability;               /*!< Capability */
00345 
00346    /* Qualification */
00347    int callno;             /*!< Call number of POKE request */
00348    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00349    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00350    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00351 
00352    int pokefreqok;               /*!< How often to check if the host is up */
00353    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00354    int historicms;               /*!< How long recent average responses took */
00355    int smoothing;             /*!< Sample over how many units to determine historic ms */
00356    
00357    struct ast_ha *ha;
00358 };
00359 
00360 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00361 
00362 static struct iax2_trunk_peer {
00363    ast_mutex_t lock;
00364    int sockfd;
00365    struct sockaddr_in addr;
00366    struct timeval txtrunktime;      /*!< Transmit trunktime */
00367    struct timeval rxtrunktime;      /*!< Receive trunktime */
00368    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00369    struct timeval trunkact;      /*!< Last trunk activity */
00370    unsigned int lastsent;        /*!< Last sent time */
00371    /* Trunk data and length */
00372    unsigned char *trunkdata;
00373    unsigned int trunkdatalen;
00374    unsigned int trunkdataalloc;
00375    struct iax2_trunk_peer *next;
00376    int trunkerror;
00377    int calls;
00378 } *tpeers = NULL;
00379 
00380 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00381 
00382 struct iax_firmware {
00383    struct iax_firmware *next;
00384    int fd;
00385    int mmaplen;
00386    int dead;
00387    struct ast_iax2_firmware_header *fwh;
00388    unsigned char *buf;
00389 };
00390 
00391 enum iax_reg_state {
00392    REG_STATE_UNREGISTERED = 0,
00393    REG_STATE_REGSENT,
00394    REG_STATE_AUTHSENT,
00395    REG_STATE_REGISTERED,
00396    REG_STATE_REJECTED,
00397    REG_STATE_TIMEOUT,
00398    REG_STATE_NOAUTH
00399 };
00400 
00401 enum iax_transfer_state {
00402    TRANSFER_NONE = 0,
00403    TRANSFER_BEGIN,
00404    TRANSFER_READY,
00405    TRANSFER_RELEASED,
00406    TRANSFER_PASSTHROUGH,
00407    TRANSFER_MBEGIN,
00408    TRANSFER_MREADY,
00409    TRANSFER_MRELEASED,
00410    TRANSFER_MPASSTHROUGH,
00411    TRANSFER_MEDIA,
00412    TRANSFER_MEDIAPASS
00413 };
00414 
00415 struct iax2_registry {
00416    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00417    char username[80];
00418    char secret[80];        /*!< Password or key name in []'s */
00419    char random[80];
00420    int expire;          /*!< Sched ID of expiration */
00421    int refresh;            /*!< How often to refresh */
00422    enum iax_reg_state regstate;
00423    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00424    int callno;          /*!< Associated call number if applicable */
00425    struct sockaddr_in us;        /*!< Who the server thinks we are */
00426    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00427    AST_LIST_ENTRY(iax2_registry) entry;
00428 };
00429 
00430 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00431 
00432 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00433 #define MIN_RETRY_TIME     100
00434 #define MAX_RETRY_TIME     10000
00435 
00436 #define MAX_JITTER_BUFFER  50
00437 #define MIN_JITTER_BUFFER  10
00438 
00439 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00440 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00441 
00442 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00443 
00444 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00445 #define TS_GAP_FOR_JB_RESYNC  5000
00446 
00447 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00448 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00449 static int iaxdynamicthreadcount = 0;
00450 static int iaxactivethreadcount = 0;
00451 
00452 struct iax_rr {
00453    int jitter;
00454    int losspct;
00455    int losscnt;
00456    int packets;
00457    int delay;
00458    int dropped;
00459    int ooo;
00460 };
00461 
00462 struct chan_iax2_pvt {
00463    /*! Socket to send/receive on for this call */
00464    int sockfd;
00465    /*! Last received voice format */
00466    int voiceformat;
00467    /*! Last received video format */
00468    int videoformat;
00469    /*! Last sent voice format */
00470    int svoiceformat;
00471    /*! Last sent video format */
00472    int svideoformat;
00473    /*! What we are capable of sending */
00474    int capability;
00475    /*! Last received timestamp */
00476    unsigned int last;
00477    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00478    unsigned int lastsent;
00479    /*! Timestamp of the last video frame sent */
00480    unsigned int lastvsent;
00481    /*! Next outgoing timestamp if everything is good */
00482    unsigned int nextpred;
00483    /*! True if the last voice we transmitted was not silence/CNG */
00484    int notsilenttx;
00485    /*! Ping time */
00486    unsigned int pingtime;
00487    /*! Max time for initial response */
00488    int maxtime;
00489    /*! Peer Address */
00490    struct sockaddr_in addr;
00491    /*! Actual used codec preferences */
00492    struct ast_codec_pref prefs;
00493    /*! Requested codec preferences */
00494    struct ast_codec_pref rprefs;
00495    /*! Our call number */
00496    unsigned short callno;
00497    /*! Peer callno */
00498    unsigned short peercallno;
00499    /*! Negotiated format, this is only used to remember what format was
00500        chosen for an unauthenticated call so that the channel can get
00501        created later using the right format */
00502    int chosenformat;
00503    /*! Peer selected format */
00504    int peerformat;
00505    /*! Peer capability */
00506    int peercapability;
00507    /*! timeval that we base our transmission on */
00508    struct timeval offset;
00509    /*! timeval that we base our delivery on */
00510    struct timeval rxcore;
00511    /*! The jitterbuffer */
00512         jitterbuf *jb;
00513    /*! active jb read scheduler id */
00514         int jbid;                       
00515    /*! LAG */
00516    int lag;
00517    /*! Error, as discovered by the manager */
00518    int error;
00519    /*! Owner if we have one */
00520    struct ast_channel *owner;
00521    /*! What's our state? */
00522    struct ast_flags state;
00523    /*! Expiry (optional) */
00524    int expiry;
00525    /*! Next outgoing sequence number */
00526    unsigned char oseqno;
00527    /*! Next sequence number they have not yet acknowledged */
00528    unsigned char rseqno;
00529    /*! Next incoming sequence number */
00530    unsigned char iseqno;
00531    /*! Last incoming sequence number we have acknowledged */
00532    unsigned char aseqno;
00533 
00534    AST_DECLARE_STRING_FIELDS(
00535       /*! Peer name */
00536       AST_STRING_FIELD(peer);
00537       /*! Default Context */
00538       AST_STRING_FIELD(context);
00539       /*! Caller ID if available */
00540       AST_STRING_FIELD(cid_num);
00541       AST_STRING_FIELD(cid_name);
00542       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00543       AST_STRING_FIELD(ani);
00544       /*! DNID */
00545       AST_STRING_FIELD(dnid);
00546       /*! RDNIS */
00547       AST_STRING_FIELD(rdnis);
00548       /*! Requested Extension */
00549       AST_STRING_FIELD(exten);
00550       /*! Expected Username */
00551       AST_STRING_FIELD(username);
00552       /*! Expected Secret */
00553       AST_STRING_FIELD(secret);
00554       /*! MD5 challenge */
00555       AST_STRING_FIELD(challenge);
00556       /*! Public keys permitted keys for incoming authentication */
00557       AST_STRING_FIELD(inkeys);
00558       /*! Private key for outgoing authentication */
00559       AST_STRING_FIELD(outkey);
00560       /*! Preferred language */
00561       AST_STRING_FIELD(language);
00562       /*! Hostname/peername for naming purposes */
00563       AST_STRING_FIELD(host);
00564 
00565       AST_STRING_FIELD(dproot);
00566       AST_STRING_FIELD(accountcode);
00567       AST_STRING_FIELD(mohinterpret);
00568       AST_STRING_FIELD(mohsuggest);
00569    );
00570    
00571    /*! permitted authentication methods */
00572    int authmethods;
00573    /*! permitted encryption methods */
00574    int encmethods;
00575    /*! Encryption AES-128 Key */
00576    aes_encrypt_ctx ecx;
00577    /*! Decryption AES-128 Key */
00578    aes_decrypt_ctx dcx;
00579    /*! 32 bytes of semi-random data */
00580    unsigned char semirand[32];
00581    /*! Associated registry */
00582    struct iax2_registry *reg;
00583    /*! Associated peer for poking */
00584    struct iax2_peer *peerpoke;
00585    /*! IAX_ flags */
00586    unsigned int flags;
00587    int adsi;
00588 
00589    /*! Transferring status */
00590    enum iax_transfer_state transferring;
00591    /*! Transfer identifier */
00592    int transferid;
00593    /*! Who we are IAX transfering to */
00594    struct sockaddr_in transfer;
00595    /*! What's the new call number for the transfer */
00596    unsigned short transfercallno;
00597    /*! Transfer decrypt AES-128 Key */
00598    aes_encrypt_ctx tdcx;
00599 
00600    /*! Status of knowledge of peer ADSI capability */
00601    int peeradsicpe;
00602 
00603    /*! Who we are bridged to */
00604    unsigned short bridgecallno;
00605    
00606    int pingid;       /*!< Transmit PING request */
00607    int lagid;        /*!< Retransmit lag request */
00608    int autoid;       /*!< Auto hangup for Dialplan requestor */
00609    int authid;       /*!< Authentication rejection ID */
00610    int authfail;        /*!< Reason to report failure */
00611    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00612    int calling_ton;
00613    int calling_tns;
00614    int calling_pres;
00615    int amaflags;
00616    struct iax2_dpcache *dpentries;
00617    struct ast_variable *vars;
00618    /*! last received remote rr */
00619    struct iax_rr remote_rr;
00620    /*! Current base time: (just for stats) */
00621    int min;
00622    /*! Dropped frame count: (just for stats) */
00623    int frames_dropped;
00624    /*! received frame count: (just for stats) */
00625    int frames_received;
00626 };
00627 
00628 static struct ast_iax2_queue {
00629    AST_LIST_HEAD(, iax_frame) queue;
00630    int count;
00631 } iaxq;
00632 
00633 /*!
00634  * This module will get much higher performance when doing a lot of
00635  * user and peer lookups if the number of buckets is increased from 1.
00636  * However, to maintain old behavior for Asterisk 1.4, these are set to
00637  * 1 by default.  When using multiple buckets, search order through these
00638  * containers is considered random, so you will not be able to depend on
00639  * the order the entires are specified in iax.conf for matching order. */
00640 #ifdef LOW_MEMORY
00641 #define MAX_PEER_BUCKETS 1
00642 /* #define MAX_PEER_BUCKETS 17 */
00643 #else
00644 #define MAX_PEER_BUCKETS 1
00645 /* #define MAX_PEER_BUCKETS 563 */
00646 #endif
00647 static struct ao2_container *peers;
00648 
00649 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00650 static struct ao2_container *users;
00651 
00652 static struct ast_firmware_list {
00653    struct iax_firmware *wares;
00654    ast_mutex_t lock;
00655 } waresl;
00656 
00657 /*! Extension exists */
00658 #define CACHE_FLAG_EXISTS     (1 << 0)
00659 /*! Extension is nonexistent */
00660 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00661 /*! Extension can exist */
00662 #define CACHE_FLAG_CANEXIST      (1 << 2)
00663 /*! Waiting to hear back response */
00664 #define CACHE_FLAG_PENDING    (1 << 3)
00665 /*! Timed out */
00666 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00667 /*! Request transmitted */
00668 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00669 /*! Timeout */
00670 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00671 /*! Matchmore */
00672 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00673 
00674 static struct iax2_dpcache {
00675    char peercontext[AST_MAX_CONTEXT];
00676    char exten[AST_MAX_EXTENSION];
00677    struct timeval orig;
00678    struct timeval expiry;
00679    int flags;
00680    unsigned short callno;
00681    int waiters[256];
00682    struct iax2_dpcache *next;
00683    struct iax2_dpcache *peer; /*!< For linking in peers */
00684 } *dpcache;
00685 
00686 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00687 
00688 static void reg_source_db(struct iax2_peer *p);
00689 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00690 
00691 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00692 
00693 #define IAX_IOSTATE_IDLE      0
00694 #define IAX_IOSTATE_READY     1
00695 #define IAX_IOSTATE_PROCESSING   2
00696 #define IAX_IOSTATE_SCHEDREADY   3
00697 
00698 #define IAX_TYPE_POOL    1
00699 #define IAX_TYPE_DYNAMIC 2
00700 
00701 struct iax2_pkt_buf {
00702    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00703    size_t len;
00704    unsigned char buf[1];
00705 };
00706 
00707 struct iax2_thread {
00708    AST_LIST_ENTRY(iax2_thread) list;
00709    int type;
00710    int iostate;
00711 #ifdef SCHED_MULTITHREADED
00712    void (*schedfunc)(const void *);
00713    const void *scheddata;
00714 #endif
00715 #ifdef DEBUG_SCHED_MULTITHREAD
00716    char curfunc[80];
00717 #endif   
00718    int actions;
00719    pthread_t threadid;
00720    int threadnum;
00721    struct sockaddr_in iosin;
00722    unsigned char readbuf[4096]; 
00723    unsigned char *buf;
00724    ssize_t buf_len;
00725    size_t buf_size;
00726    int iofd;
00727    time_t checktime;
00728    ast_mutex_t lock;
00729    ast_cond_t cond;
00730    unsigned int ready_for_signal:1;
00731    /*! if this thread is processing a full frame,
00732      some information about that frame will be stored
00733      here, so we can avoid dispatching any more full
00734      frames for that callno to other threads */
00735    struct {
00736       unsigned short callno;
00737       struct sockaddr_in sin;
00738       unsigned char type;
00739       unsigned char csub;
00740    } ffinfo;
00741    /*! Queued up full frames for processing.  If more full frames arrive for
00742     *  a call which this thread is already processing a full frame for, they
00743     *  are queued up here. */
00744    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00745 };
00746 
00747 /* Thread lists */
00748 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00749 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00750 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00751 
00752 static void *iax2_process_thread(void *data);
00753 
00754 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00755 {
00756    ast_mutex_lock(lock);
00757    ast_cond_signal(cond);
00758    ast_mutex_unlock(lock);
00759 }
00760 
00761 static void iax_debug_output(const char *data)
00762 {
00763    if (iaxdebug)
00764       ast_verbose("%s", data);
00765 }
00766 
00767 static void iax_error_output(const char *data)
00768 {
00769    ast_log(LOG_WARNING, "%s", data);
00770 }
00771 
00772 static void jb_error_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_ERROR, buf);
00782 }
00783 
00784 static void jb_warning_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_log(LOG_WARNING, buf);
00794 }
00795 
00796 static void jb_debug_output(const char *fmt, ...)
00797 {
00798    va_list args;
00799    char buf[1024];
00800 
00801    va_start(args, fmt);
00802    vsnprintf(buf, 1024, fmt, args);
00803    va_end(args);
00804 
00805    ast_verbose(buf);
00806 }
00807 
00808 /* XXX We probably should use a mutex when working with this XXX */
00809 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00810 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00811 static struct timeval lastused[ARRAY_LEN(iaxs)];
00812 
00813 /*!
00814  * \brief Another container of iax2_pvt structures
00815  *
00816  * Active IAX2 pvt structs are also stored in this container, if they are a part
00817  * of an active call where we know the remote side's call number.  The reason
00818  * for this is that incoming media frames do not contain our call number.  So,
00819  * instead of having to iterate the entire iaxs array, we use this container to
00820  * look up calls where the remote side is using a given call number.
00821  */
00822 static struct ao2_container *iax_peercallno_pvts;
00823 
00824 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00825    but keeps the division between trunked and non-trunked better. */
00826 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00827 
00828 static int maxtrunkcall = TRUNK_CALL_START;
00829 static int maxnontrunkcall = 1;
00830 
00831 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);
00832 static int expire_registry(const void *data);
00833 static int iax2_answer(struct ast_channel *c);
00834 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00835 static int iax2_devicestate(void *data);
00836 static int iax2_digit_begin(struct ast_channel *c, char digit);
00837 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00838 static int iax2_do_register(struct iax2_registry *reg);
00839 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00840 static int iax2_hangup(struct ast_channel *c);
00841 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00842 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00843 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00844 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00845 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00846 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00847 static int iax2_sendtext(struct ast_channel *c, const char *text);
00848 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00849 static int iax2_transfer(struct ast_channel *c, const char *dest);
00850 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00851 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00852 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00853 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00854 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00855 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00856 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00857 static struct ast_frame *iax2_read(struct ast_channel *c);
00858 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00859 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00860 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00861 static void prune_peers(void);
00862 
00863 static const struct ast_channel_tech iax2_tech = {
00864    .type = "IAX2",
00865    .description = tdesc,
00866    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00867    .properties = AST_CHAN_TP_WANTSJITTER,
00868    .requester = iax2_request,
00869    .devicestate = iax2_devicestate,
00870    .send_digit_begin = iax2_digit_begin,
00871    .send_digit_end = iax2_digit_end,
00872    .send_text = iax2_sendtext,
00873    .send_image = iax2_sendimage,
00874    .send_html = iax2_sendhtml,
00875    .call = iax2_call,
00876    .hangup = iax2_hangup,
00877    .answer = iax2_answer,
00878    .read = iax2_read,
00879    .write = iax2_write,
00880    .write_video = iax2_write,
00881    .indicate = iax2_indicate,
00882    .setoption = iax2_setoption,
00883    .bridge = iax2_bridge,
00884    .transfer = iax2_transfer,
00885    .fixup = iax2_fixup,
00886 };
00887 
00888 /* WARNING: insert_idle_thread should only ever be called within the
00889  * context of an iax2_process_thread() thread.
00890  */
00891 static void insert_idle_thread(struct iax2_thread *thread)
00892 {
00893    if (thread->type == IAX_TYPE_DYNAMIC) {
00894       AST_LIST_LOCK(&dynamic_list);
00895       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00896       AST_LIST_UNLOCK(&dynamic_list);
00897    } else {
00898       AST_LIST_LOCK(&idle_list);
00899       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00900       AST_LIST_UNLOCK(&idle_list);
00901    }
00902 
00903    return;
00904 }
00905 
00906 static struct iax2_thread *find_idle_thread(void)
00907 {
00908    pthread_attr_t attr;
00909    struct iax2_thread *thread = NULL;
00910 
00911    /* Pop the head of the list off */
00912    AST_LIST_LOCK(&idle_list);
00913    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00914    AST_LIST_UNLOCK(&idle_list);
00915 
00916    /* If no idle thread is available from the regular list, try dynamic */
00917    if (thread == NULL) {
00918       AST_LIST_LOCK(&dynamic_list);
00919       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00920       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00921       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00922          /* We need to MAKE a thread! */
00923          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00924             thread->threadnum = iaxdynamicthreadcount;
00925             thread->type = IAX_TYPE_DYNAMIC;
00926             ast_mutex_init(&thread->lock);
00927             ast_cond_init(&thread->cond, NULL);
00928             pthread_attr_init(&attr);
00929             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00930             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00931                free(thread);
00932                thread = NULL;
00933             } else {
00934                /* All went well and the thread is up, so increment our count */
00935                iaxdynamicthreadcount++;
00936                
00937                /* Wait for the thread to be ready before returning it to the caller */
00938                while (!thread->ready_for_signal)
00939                   usleep(1);
00940             }
00941          }
00942       }
00943       AST_LIST_UNLOCK(&dynamic_list);
00944    }
00945 
00946    /* this thread is not processing a full frame (since it is idle),
00947       so ensure that the field for the full frame call number is empty */
00948    if (thread)
00949       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00950 
00951    return thread;
00952 }
00953 
00954 #ifdef SCHED_MULTITHREADED
00955 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00956 {
00957    struct iax2_thread *thread = NULL;
00958    static time_t lasterror;
00959    static time_t t;
00960 
00961    thread = find_idle_thread();
00962 
00963    if (thread != NULL) {
00964       thread->schedfunc = func;
00965       thread->scheddata = data;
00966       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00967 #ifdef DEBUG_SCHED_MULTITHREAD
00968       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00969 #endif
00970       signal_condition(&thread->lock, &thread->cond);
00971       return 0;
00972    }
00973    time(&t);
00974    if (t != lasterror && option_debug) 
00975       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00976    lasterror = t;
00977 
00978    return -1;
00979 }
00980 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00981 #endif
00982 
00983 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00984 {
00985    int res;
00986 
00987    res = ast_sched_add(con, when, callback, data);
00988    signal_condition(&sched_lock, &sched_cond);
00989 
00990    return res;
00991 }
00992 
00993 static int send_ping(const void *data);
00994 
00995 static void __send_ping(const void *data)
00996 {
00997    int callno = (long) data;
00998 
00999    ast_mutex_lock(&iaxsl[callno]);
01000 
01001    while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01002       if (iaxs[callno]->peercallno) {
01003          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01004       }
01005       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01006       break;
01007    }
01008 
01009    ast_mutex_unlock(&iaxsl[callno]);
01010 }
01011 
01012 static int send_ping(const void *data)
01013 {
01014 #ifdef SCHED_MULTITHREADED
01015    if (schedule_action(__send_ping, data))
01016 #endif      
01017       __send_ping(data);
01018    return 0;
01019 }
01020 
01021 static int get_encrypt_methods(const char *s)
01022 {
01023    int e;
01024    if (!strcasecmp(s, "aes128"))
01025       e = IAX_ENCRYPT_AES128;
01026    else if (ast_true(s))
01027       e = IAX_ENCRYPT_AES128;
01028    else
01029       e = 0;
01030    return e;
01031 }
01032 
01033 static int send_lagrq(const void *data);
01034 
01035 static void __send_lagrq(const void *data)
01036 {
01037    int callno = (long) data;
01038 
01039    ast_mutex_lock(&iaxsl[callno]);
01040 
01041    while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01042       if (iaxs[callno]->peercallno) {
01043          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01044       }
01045       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01046       break;
01047    }
01048 
01049    ast_mutex_unlock(&iaxsl[callno]);
01050 }
01051 
01052 static int send_lagrq(const void *data)
01053 {
01054 #ifdef SCHED_MULTITHREADED
01055    if (schedule_action(__send_lagrq, data))
01056 #endif      
01057       __send_lagrq(data);
01058    return 0;
01059 }
01060 
01061 static unsigned char compress_subclass(int subclass)
01062 {
01063    int x;
01064    int power=-1;
01065    /* If it's 128 or smaller, just return it */
01066    if (subclass < IAX_FLAG_SC_LOG)
01067       return subclass;
01068    /* Otherwise find its power */
01069    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01070       if (subclass & (1 << x)) {
01071          if (power > -1) {
01072             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01073             return 0;
01074          } else
01075             power = x;
01076       }
01077    }
01078    return power | IAX_FLAG_SC_LOG;
01079 }
01080 
01081 static int uncompress_subclass(unsigned char csub)
01082 {
01083    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01084    if (csub & IAX_FLAG_SC_LOG) {
01085       /* special case for 'compressed' -1 */
01086       if (csub == 0xff)
01087          return -1;
01088       else
01089          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01090    }
01091    else
01092       return csub;
01093 }
01094 
01095 /*!
01096  * \note The only member of the peer passed here guaranteed to be set is the name field
01097  */
01098 static int peer_hash_cb(const void *obj, const int flags)
01099 {
01100    const struct iax2_peer *peer = obj;
01101 
01102    return ast_str_hash(peer->name);
01103 }
01104 
01105 /*!
01106  * \note The only member of the peer passed here guaranteed to be set is the name field
01107  */
01108 static int peer_cmp_cb(void *obj, void *arg, int flags)
01109 {
01110    struct iax2_peer *peer = obj, *peer2 = arg;
01111 
01112    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01113 }
01114 
01115 /*!
01116  * \note The only member of the user passed here guaranteed to be set is the name field
01117  */
01118 static int user_hash_cb(const void *obj, const int flags)
01119 {
01120    const struct iax2_user *user = obj;
01121 
01122    return ast_str_hash(user->name);
01123 }
01124 
01125 /*!
01126  * \note The only member of the user passed here guaranteed to be set is the name field
01127  */
01128 static int user_cmp_cb(void *obj, void *arg, int flags)
01129 {
01130    struct iax2_user *user = obj, *user2 = arg;
01131 
01132    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01133 }
01134 
01135 /*!
01136  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01137  *       so do not call it with a pvt lock held.
01138  */
01139 static struct iax2_peer *find_peer(const char *name, int realtime) 
01140 {
01141    struct iax2_peer *peer = NULL;
01142    struct iax2_peer tmp_peer = {
01143       .name = name,
01144    };
01145 
01146    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01147 
01148    /* Now go for realtime if applicable */
01149    if(!peer && realtime)
01150       peer = realtime_peer(name, NULL);
01151 
01152    return peer;
01153 }
01154 
01155 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01156 {
01157    ao2_ref(peer, +1);
01158    return peer;
01159 }
01160 
01161 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01162 {
01163    ao2_ref(peer, -1);
01164    return NULL;
01165 }
01166 
01167 static inline struct iax2_user *user_ref(struct iax2_user *user)
01168 {
01169    ao2_ref(user, +1);
01170    return user;
01171 }
01172 
01173 static inline struct iax2_user *user_unref(struct iax2_user *user)
01174 {
01175    ao2_ref(user, -1);
01176    return NULL;
01177 }
01178 
01179 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01180 {
01181    struct iax2_peer *peer = NULL;
01182    int res = 0;
01183    struct ao2_iterator i;
01184 
01185    i = ao2_iterator_init(peers, 0);
01186    while ((peer = ao2_iterator_next(&i))) {
01187       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01188           (peer->addr.sin_port == sin.sin_port)) {
01189          ast_copy_string(host, peer->name, len);
01190          peer_unref(peer);
01191          res = 1;
01192          break;
01193       }
01194       peer_unref(peer);
01195    }
01196 
01197    if (!peer) {
01198       peer = realtime_peer(NULL, &sin);
01199       if (peer) {
01200          ast_copy_string(host, peer->name, len);
01201          peer_unref(peer);
01202          res = 1;
01203       }
01204    }
01205 
01206    return res;
01207 }
01208 
01209 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01210 {
01211    /* Decrement AUTHREQ count if needed */
01212    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01213       struct iax2_user *user;
01214       struct iax2_user tmp_user = {
01215          .name = pvt->username,
01216       };
01217 
01218       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01219       if (user) {
01220          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01221          user = user_unref(user);       
01222       }
01223 
01224       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01225    }
01226 
01227    /* No more pings or lagrq's */
01228    AST_SCHED_DEL(sched, pvt->pingid);
01229    AST_SCHED_DEL(sched, pvt->lagid);
01230    AST_SCHED_DEL(sched, pvt->autoid);
01231    AST_SCHED_DEL(sched, pvt->authid);
01232    AST_SCHED_DEL(sched, pvt->initid);
01233    AST_SCHED_DEL(sched, pvt->jbid);
01234 }
01235 
01236 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01237 {
01238    if (!pvt->peercallno) {
01239       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01240       return;
01241    }
01242 
01243    ao2_link(iax_peercallno_pvts, pvt);
01244 }
01245 
01246 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01247 {
01248    if (!pvt->peercallno) {
01249       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01250       return;
01251    }
01252 
01253    ao2_unlink(iax_peercallno_pvts, pvt);
01254 }
01255 
01256 static void update_max_trunk(void)
01257 {
01258    int max = TRUNK_CALL_START;
01259    int x;
01260 
01261    /* XXX Prolly don't need locks here XXX */
01262    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01263       if (iaxs[x]) {
01264          max = x + 1;
01265       }
01266    }
01267 
01268    maxtrunkcall = max;
01269    if (option_debug && iaxdebug)
01270       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01271 }
01272 
01273 static void iax2_frame_free(struct iax_frame *fr)
01274 {
01275    AST_SCHED_DEL(sched, fr->retrans);
01276    iax_frame_free(fr);
01277 }
01278 
01279 static void iax2_destroy(int callno)
01280 {
01281    struct chan_iax2_pvt *pvt;
01282    struct ast_channel *owner;
01283 
01284 retry:
01285    pvt = iaxs[callno];
01286    gettimeofday(&lastused[callno], NULL);
01287    
01288    owner = pvt ? pvt->owner : NULL;
01289 
01290    if (owner) {
01291       if (ast_mutex_trylock(&owner->lock)) {
01292          if (option_debug > 2)
01293             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01294          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01295          goto retry;
01296       }
01297    }
01298    if (!owner) {
01299       iaxs[callno] = NULL;
01300    }
01301 
01302    if (pvt) {
01303       if (!owner) {
01304          pvt->owner = NULL;
01305       } else {
01306          /* If there's an owner, prod it to give up */
01307          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01308           * because we already hold the owner channel lock. */
01309          ast_queue_hangup(owner);
01310       }
01311 
01312       if (pvt->peercallno) {
01313          remove_by_peercallno(pvt);
01314       }
01315 
01316       if (!owner) {
01317          ao2_ref(pvt, -1);
01318          pvt = NULL;
01319       }
01320    }
01321 
01322    if (owner) {
01323       ast_mutex_unlock(&owner->lock);
01324    }
01325 
01326    if (callno & 0x4000) {
01327       update_max_trunk();
01328    }
01329 }
01330 
01331 static void pvt_destructor(void *obj)
01332 {
01333    struct chan_iax2_pvt *pvt = obj;
01334    struct iax_frame *cur = NULL;
01335 
01336    iax2_destroy_helper(pvt);
01337 
01338    /* Already gone */
01339    ast_set_flag(pvt, IAX_ALREADYGONE); 
01340 
01341    AST_LIST_LOCK(&iaxq.queue);
01342    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01343       /* Cancel any pending transmissions */
01344       if (cur->callno == pvt->callno) { 
01345          cur->retries = -1;
01346       }
01347    }
01348    AST_LIST_UNLOCK(&iaxq.queue);
01349 
01350    if (pvt->reg) {
01351       pvt->reg->callno = 0;
01352    }
01353 
01354    if (!pvt->owner) {
01355       jb_frame frame;
01356       if (pvt->vars) {
01357           ast_variables_destroy(pvt->vars);
01358           pvt->vars = NULL;
01359       }
01360 
01361       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01362          iax2_frame_free(frame.data);
01363       }
01364 
01365       jb_destroy(pvt->jb);
01366       ast_string_field_free_memory(pvt);
01367    }
01368 }
01369 
01370 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01371 {
01372    struct chan_iax2_pvt *tmp;
01373    jb_conf jbconf;
01374 
01375    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01376       return NULL;
01377    }
01378 
01379    if (ast_string_field_init(tmp, 32)) {
01380       ao2_ref(tmp, -1);
01381       tmp = NULL;
01382       return NULL;
01383    }
01384       
01385    tmp->prefs = prefs;
01386    tmp->callno = 0;
01387    tmp->peercallno = 0;
01388    tmp->transfercallno = 0;
01389    tmp->bridgecallno = 0;
01390    tmp->pingid = -1;
01391    tmp->lagid = -1;
01392    tmp->autoid = -1;
01393    tmp->authid = -1;
01394    tmp->initid = -1;
01395 
01396    ast_string_field_set(tmp,exten, "s");
01397    ast_string_field_set(tmp,host, host);
01398 
01399    tmp->jb = jb_new();
01400    tmp->jbid = -1;
01401    jbconf.max_jitterbuf = maxjitterbuffer;
01402    jbconf.resync_threshold = resyncthreshold;
01403    jbconf.max_contig_interp = maxjitterinterps;
01404    jb_setconf(tmp->jb,&jbconf);
01405 
01406    return tmp;
01407 }
01408 
01409 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01410 {
01411    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01412    if (new) {
01413       size_t afdatalen = new->afdatalen;
01414       memcpy(new, fr, sizeof(*new));
01415       iax_frame_wrap(new, &fr->af);
01416       new->afdatalen = afdatalen;
01417       new->data = NULL;
01418       new->datalen = 0;
01419       new->direction = DIRECTION_INGRESS;
01420       new->retrans = -1;
01421    }
01422    return new;
01423 }
01424 
01425 #define NEW_PREVENT  0
01426 #define NEW_ALLOW    1
01427 #define NEW_FORCE    2
01428 
01429 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01430 {
01431    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01432       (cur->addr.sin_port == sin->sin_port)) {
01433       /* This is the main host */
01434       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01435           (check_dcallno ? dcallno == cur->callno : 1) ) {
01436          /* That's us.  Be sure we keep track of the peer call number */
01437          return 1;
01438       }
01439    }
01440    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01441        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01442       /* We're transferring */
01443       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01444          return 1;
01445    }
01446    return 0;
01447 }
01448 
01449 static void update_max_nontrunk(void)
01450 {
01451    int max = 1;
01452    int x;
01453    /* XXX Prolly don't need locks here XXX */
01454    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01455       if (iaxs[x])
01456          max = x + 1;
01457    }
01458    maxnontrunkcall = max;
01459    if (option_debug && iaxdebug)
01460       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01461 }
01462 
01463 static int make_trunk(unsigned short callno, int locked)
01464 {
01465    int x;
01466    int res= 0;
01467    struct timeval now;
01468    if (iaxs[callno]->oseqno) {
01469       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01470       return -1;
01471    }
01472    if (callno & TRUNK_CALL_START) {
01473       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01474       return -1;
01475    }
01476    gettimeofday(&now, NULL);
01477    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01478       ast_mutex_lock(&iaxsl[x]);
01479       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01480          iaxs[x] = iaxs[callno];
01481          iaxs[x]->callno = x;
01482          iaxs[callno] = NULL;
01483          /* Update the two timers that should have been started */
01484          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01485          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01486          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01487          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01488          if (locked)
01489             ast_mutex_unlock(&iaxsl[callno]);
01490          res = x;
01491          if (!locked)
01492             ast_mutex_unlock(&iaxsl[x]);
01493          break;
01494       }
01495       ast_mutex_unlock(&iaxsl[x]);
01496    }
01497    if (x >= ARRAY_LEN(iaxs) - 1) {
01498       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01499       return -1;
01500    }
01501    if (option_debug)
01502       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01503    /* We move this call from a non-trunked to a trunked call */
01504    update_max_trunk();
01505    update_max_nontrunk();
01506    return res;
01507 }
01508 
01509 /*!
01510  * \note Calling this function while holding another pvt lock can cause a deadlock.
01511  */
01512 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01513 {
01514    int res = 0;
01515    int x;
01516    struct timeval now;
01517    char host[80];
01518 
01519    if (new <= NEW_ALLOW) {
01520       if (callno) {
01521          struct chan_iax2_pvt *pvt;
01522          struct chan_iax2_pvt tmp_pvt = {
01523             .callno = dcallno,
01524             .peercallno = callno,
01525             /* hack!! */
01526             .frames_received = check_dcallno,
01527          };
01528  
01529          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01530  
01531          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01532             if (return_locked) {
01533                ast_mutex_lock(&iaxsl[pvt->callno]);
01534             }
01535             res = pvt->callno;
01536             ao2_ref(pvt, -1);
01537             pvt = NULL;
01538             return res;
01539          }
01540       }
01541 
01542       /* Look for an existing connection first */
01543       for (x = 1; !res && x < maxnontrunkcall; x++) {
01544          ast_mutex_lock(&iaxsl[x]);
01545          if (iaxs[x]) {
01546             /* Look for an exact match */
01547             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01548                res = x;
01549             }
01550          }
01551          if (!res || !return_locked)
01552             ast_mutex_unlock(&iaxsl[x]);
01553       }
01554       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01555          ast_mutex_lock(&iaxsl[x]);
01556          if (iaxs[x]) {
01557             /* Look for an exact match */
01558             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01559                res = x;
01560             }
01561          }
01562          if (!res || !return_locked)
01563             ast_mutex_unlock(&iaxsl[x]);
01564       }
01565    }
01566    if (!res && (new >= NEW_ALLOW)) {
01567       int start, found = 0;
01568 
01569       /* It may seem odd that we look through the peer list for a name for
01570        * this *incoming* call.  Well, it is weird.  However, users don't
01571        * have an IP address/port number that we can match against.  So,
01572        * this is just checking for a peer that has that IP/port and
01573        * assuming that we have a user of the same name.  This isn't always
01574        * correct, but it will be changed if needed after authentication. */
01575       if (!iax2_getpeername(*sin, host, sizeof(host)))
01576          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01577 
01578       now = ast_tvnow();
01579       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01580       for (x = start; 1; x++) {
01581          if (x == TRUNK_CALL_START) {
01582             x = 1;
01583             continue;
01584          }
01585 
01586          /* Find first unused call number that hasn't been used in a while */
01587          ast_mutex_lock(&iaxsl[x]);
01588          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01589             found = 1;
01590             break;
01591          }
01592          ast_mutex_unlock(&iaxsl[x]);
01593          
01594          if (x == start - 1) {
01595             break;
01596          }
01597       }
01598       /* We've still got lock held if we found a spot */
01599       if (x == start - 1 && !found) {
01600          ast_log(LOG_WARNING, "No more space\n");
01601          return 0;
01602       }
01603       iaxs[x] = new_iax(sin, host);
01604       update_max_nontrunk();
01605       if (iaxs[x]) {
01606          if (option_debug && iaxdebug)
01607             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01608          iaxs[x]->sockfd = sockfd;
01609          iaxs[x]->addr.sin_port = sin->sin_port;
01610          iaxs[x]->addr.sin_family = sin->sin_family;
01611          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01612          iaxs[x]->peercallno = callno;
01613          iaxs[x]->callno = x;
01614          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01615          iaxs[x]->expiry = min_reg_expire;
01616          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01617          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01618          iaxs[x]->amaflags = amaflags;
01619          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01620          
01621          ast_string_field_set(iaxs[x], accountcode, accountcode);
01622          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01623          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01624 
01625          if (iaxs[x]->peercallno) {
01626             store_by_peercallno(iaxs[x]);
01627          }
01628       } else {
01629          ast_log(LOG_WARNING, "Out of resources\n");
01630          ast_mutex_unlock(&iaxsl[x]);
01631          return 0;
01632       }
01633       if (!return_locked)
01634          ast_mutex_unlock(&iaxsl[x]);
01635       res = x;
01636    }
01637    return res;
01638 }
01639 
01640 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01641 
01642    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01643 }
01644 
01645 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01646 
01647    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01648 }
01649 
01650 /*!
01651  * \brief Queue a frame to a call's owning asterisk channel
01652  *
01653  * \pre This function assumes that iaxsl[callno] is locked when called.
01654  *
01655  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01656  * was valid before calling it, it may no longer be valid after calling it.
01657  * This function may unlock and lock the mutex associated with this callno,
01658  * meaning that another thread may grab it and destroy the call.
01659  */
01660 static int iax2_queue_frame(int callno, struct ast_frame *f)
01661 {
01662    for (;;) {
01663       if (iaxs[callno] && iaxs[callno]->owner) {
01664          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01665             /* Avoid deadlock by pausing and trying again */
01666             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01667          } else {
01668             ast_queue_frame(iaxs[callno]->owner, f);
01669             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01670             break;
01671          }
01672       } else
01673          break;
01674    }
01675    return 0;
01676 }
01677 
01678 /*!
01679  * \brief Queue a hangup frame on the ast_channel owner
01680  *
01681  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01682  * is active for the given call number.
01683  *
01684  * \pre Assumes lock for callno is already held.
01685  *
01686  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01687  * was valid before calling it, it may no longer be valid after calling it.
01688  * This function may unlock and lock the mutex associated with this callno,
01689  * meaning that another thread may grab it and destroy the call.
01690  */
01691 static int iax2_queue_hangup(int callno)
01692 {
01693    for (;;) {
01694       if (iaxs[callno] && iaxs[callno]->owner) {
01695          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01696             /* Avoid deadlock by pausing and trying again */
01697             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01698          } else {
01699             ast_queue_hangup(iaxs[callno]->owner);
01700             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01701             break;
01702          }
01703       } else
01704          break;
01705    }
01706    return 0;
01707 }
01708 
01709 /*!
01710  * \brief Queue a control frame on the ast_channel owner
01711  *
01712  * This function queues a control frame on the owner of the IAX2 pvt struct that
01713  * is active for the given call number.
01714  *
01715  * \pre Assumes lock for callno is already held.
01716  *
01717  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01718  * was valid before calling it, it may no longer be valid after calling it.
01719  * This function may unlock and lock the mutex associated with this callno,
01720  * meaning that another thread may grab it and destroy the call.
01721  */
01722 static int iax2_queue_control_data(int callno, 
01723    enum ast_control_frame_type control, const void *data, size_t datalen)
01724 {
01725    for (;;) {
01726       if (iaxs[callno] && iaxs[callno]->owner) {
01727          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01728             /* Avoid deadlock by pausing and trying again */
01729             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01730          } else {
01731             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01732             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01733             break;
01734          }
01735       } else
01736          break;
01737    }
01738    return 0;
01739 }
01740 static void destroy_firmware(struct iax_firmware *cur)
01741 {
01742    /* Close firmware */
01743    if (cur->fwh) {
01744       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01745    }
01746    close(cur->fd);
01747    free(cur);
01748 }
01749 
01750 static int try_firmware(char *s)
01751 {
01752    struct stat stbuf;
01753    struct iax_firmware *cur;
01754    int ifd;
01755    int fd;
01756    int res;
01757    
01758    struct ast_iax2_firmware_header *fwh, fwh2;
01759    struct MD5Context md5;
01760    unsigned char sum[16];
01761    unsigned char buf[1024];
01762    int len, chunk;
01763    char *s2;
01764    char *last;
01765    s2 = alloca(strlen(s) + 100);
01766    if (!s2) {
01767       ast_log(LOG_WARNING, "Alloca failed!\n");
01768       return -1;
01769    }
01770    last = strrchr(s, '/');
01771    if (last)
01772       last++;
01773    else
01774       last = s;
01775    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01776    res = stat(s, &stbuf);
01777    if (res < 0) {
01778       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01779       return -1;
01780    }
01781    /* Make sure it's not a directory */
01782    if (S_ISDIR(stbuf.st_mode))
01783       return -1;
01784    ifd = open(s, O_RDONLY);
01785    if (ifd < 0) {
01786       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01787       return -1;
01788    }
01789    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01790    if (fd < 0) {
01791       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01792       close(ifd);
01793       return -1;
01794    }
01795    /* Unlink our newly created file */
01796    unlink(s2);
01797    
01798    /* Now copy the firmware into it */
01799    len = stbuf.st_size;
01800    while(len) {
01801       chunk = len;
01802       if (chunk > sizeof(buf))
01803          chunk = sizeof(buf);
01804       res = read(ifd, buf, chunk);
01805       if (res != chunk) {
01806          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01807          close(ifd);
01808          close(fd);
01809          return -1;
01810       }
01811       res = write(fd, buf, chunk);
01812       if (res != chunk) {
01813          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01814          close(ifd);
01815          close(fd);
01816          return -1;
01817       }
01818       len -= chunk;
01819    }
01820    close(ifd);
01821    /* Return to the beginning */
01822    lseek(fd, 0, SEEK_SET);
01823    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01824       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01825       close(fd);
01826       return -1;
01827    }
01828    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01829       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01830       close(fd);
01831       return -1;
01832    }
01833    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01834       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01835       close(fd);
01836       return -1;
01837    }
01838    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01839       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01840       close(fd);
01841       return -1;
01842    }
01843    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01844    if (fwh == (void *) -1) {
01845       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01846       close(fd);
01847       return -1;
01848    }
01849    MD5Init(&md5);
01850    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01851    MD5Final(sum, &md5);
01852    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01853       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01854       munmap((void*)fwh, stbuf.st_size);
01855       close(fd);
01856       return -1;
01857    }
01858    cur = waresl.wares;
01859    while(cur) {
01860       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01861          /* Found a candidate */
01862          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01863             /* The version we have on loaded is older, load this one instead */
01864             break;
01865          /* This version is no newer than what we have.  Don't worry about it.
01866             We'll consider it a proper load anyhow though */
01867          munmap((void*)fwh, stbuf.st_size);
01868          close(fd);
01869          return 0;
01870       }
01871       cur = cur->next;
01872    }
01873    if (!cur) {
01874       /* Allocate a new one and link it */
01875       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01876          cur->fd = -1;
01877          cur->next = waresl.wares;
01878          waresl.wares = cur;
01879       }
01880    }
01881    if (cur) {
01882       if (cur->fwh) {
01883          munmap((void*)cur->fwh, cur->mmaplen);
01884       }
01885       if (cur->fd > -1)
01886          close(cur->fd);
01887       cur->fwh = fwh;
01888       cur->fd = fd;
01889       cur->mmaplen = stbuf.st_size;
01890       cur->dead = 0;
01891    }
01892    return 0;
01893 }
01894 
01895 static int iax_check_version(char *dev)
01896 {
01897    int res = 0;
01898    struct iax_firmware *cur;
01899    if (!ast_strlen_zero(dev)) {
01900       ast_mutex_lock(&waresl.lock);
01901       cur = waresl.wares;
01902       while(cur) {
01903          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01904             res = ntohs(cur->fwh->version);
01905             break;
01906          }
01907          cur = cur->next;
01908       }
01909       ast_mutex_unlock(&waresl.lock);
01910    }
01911    return res;
01912 }
01913 
01914 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01915 {
01916    int res = -1;
01917    unsigned int bs = desc & 0xff;
01918    unsigned int start = (desc >> 8) & 0xffffff;
01919    unsigned int bytes;
01920    struct iax_firmware *cur;
01921    if (!ast_strlen_zero((char *)dev) && bs) {
01922       start *= bs;
01923       ast_mutex_lock(&waresl.lock);
01924       cur = waresl.wares;
01925       while(cur) {
01926          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01927             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01928             if (start < ntohl(cur->fwh->datalen)) {
01929                bytes = ntohl(cur->fwh->datalen) - start;
01930                if (bytes > bs)
01931                   bytes = bs;
01932                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01933             } else {
01934                bytes = 0;
01935                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01936             }
01937             if (bytes == bs)
01938                res = 0;
01939             else
01940                res = 1;
01941             break;
01942          }
01943          cur = cur->next;
01944       }
01945       ast_mutex_unlock(&waresl.lock);
01946    }
01947    return res;
01948 }
01949 
01950 
01951 static void reload_firmware(int unload)
01952 {
01953    struct iax_firmware *cur, *curl, *curp;
01954    DIR *fwd;
01955    struct dirent *de;
01956    char dir[256];
01957    char fn[256];
01958    /* Mark all as dead */
01959    ast_mutex_lock(&waresl.lock);
01960    cur = waresl.wares;
01961    while(cur) {
01962       cur->dead = 1;
01963       cur = cur->next;
01964    }
01965 
01966    /* Now that we've freed them, load the new ones */
01967    if (!unload) {
01968       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01969       fwd = opendir(dir);
01970       if (fwd) {
01971          while((de = readdir(fwd))) {
01972             if (de->d_name[0] != '.') {
01973                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01974                if (!try_firmware(fn)) {
01975                   if (option_verbose > 1)
01976                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01977                }
01978             }
01979          }
01980          closedir(fwd);
01981       } else 
01982          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01983    }
01984 
01985    /* Clean up leftovers */
01986    cur = waresl.wares;
01987    curp = NULL;
01988    while(cur) {
01989       curl = cur;
01990       cur = cur->next;
01991       if (curl->dead) {
01992          if (curp) {
01993             curp->next = cur;
01994          } else {
01995             waresl.wares = cur;
01996          }
01997          destroy_firmware(curl);
01998       } else {
01999          curp = cur;
02000       }
02001    }
02002    ast_mutex_unlock(&waresl.lock);
02003 }
02004 
02005 /*!
02006  * \note This function assumes that iaxsl[callno] is locked when called.
02007  *
02008  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02009  * was valid before calling it, it may no longer be valid after calling it.
02010  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02011  * associated with this callno, meaning that another thread may grab it and destroy the call.
02012  */
02013 static int __do_deliver(void *data)
02014 {
02015    /* Just deliver the packet by using queueing.  This is called by
02016      the IAX thread with the iaxsl lock held. */
02017    struct iax_frame *fr = data;
02018    fr->retrans = -1;
02019    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02020    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02021       iax2_queue_frame(fr->callno, &fr->af);
02022    /* Free our iax frame */
02023    iax2_frame_free(fr);
02024    /* And don't run again */
02025    return 0;
02026 }
02027 
02028 static int handle_error(void)
02029 {
02030    /* XXX Ideally we should figure out why an error occured and then abort those
02031       rather than continuing to try.  Unfortunately, the published interface does
02032       not seem to work XXX */
02033 #if 0
02034    struct sockaddr_in *sin;
02035    int res;
02036    struct msghdr m;
02037    struct sock_extended_err e;
02038    m.msg_name = NULL;
02039    m.msg_namelen = 0;
02040    m.msg_iov = NULL;
02041    m.msg_control = &e;
02042    m.msg_controllen = sizeof(e);
02043    m.msg_flags = 0;
02044    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02045    if (res < 0)
02046       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02047    else {
02048       if (m.msg_controllen) {
02049          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02050          if (sin) 
02051             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02052          else
02053             ast_log(LOG_WARNING, "No address detected??\n");
02054       } else {
02055          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02056       }
02057    }
02058 #endif
02059    return 0;
02060 }
02061 
02062 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02063 {
02064    int res;
02065    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02066                sizeof(*sin));
02067    if (res < 0) {
02068       if (option_debug)
02069          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02070       handle_error();
02071    } else
02072       res = 0;
02073    return res;
02074 }
02075 
02076 static int send_packet(struct iax_frame *f)
02077 {
02078    int res;
02079    int callno = f->callno;
02080 
02081    /* Don't send if there was an error, but return error instead */
02082    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02083        return -1;
02084    
02085    /* Called with iaxsl held */
02086    if (option_debug > 2 && iaxdebug)
02087       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));
02088    if (f->transfer) {
02089       if (iaxdebug)
02090          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02091       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02092                sizeof(iaxs[callno]->transfer));
02093    } else {
02094       if (iaxdebug)
02095          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02096       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02097                sizeof(iaxs[callno]->addr));
02098    }
02099    if (res < 0) {
02100       if (option_debug && iaxdebug)
02101          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02102       handle_error();
02103    } else
02104       res = 0;
02105    return res;
02106 }
02107 
02108 /*!
02109  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02110  *       for the given call number may disappear during its execution.
02111  */
02112 static int iax2_predestroy(int callno)
02113 {
02114    struct ast_channel *c;
02115    struct chan_iax2_pvt *pvt = iaxs[callno];
02116 
02117    if (!pvt)
02118       return -1;
02119    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02120       iax2_destroy_helper(pvt);
02121       ast_set_flag(pvt, IAX_ALREADYGONE); 
02122    }
02123    c = pvt->owner;
02124    if (c) {
02125       c->tech_pvt = NULL;
02126       iax2_queue_hangup(callno);
02127       pvt->owner = NULL;
02128       ast_module_unref(ast_module_info->self);
02129    }
02130    return 0;
02131 }
02132 
02133 static int update_packet(struct iax_frame *f)
02134 {
02135    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02136    struct ast_iax2_full_hdr *fh = f->data;
02137    /* Mark this as a retransmission */
02138    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02139    /* Update iseqno */
02140    f->iseqno = iaxs[f->callno]->iseqno;
02141    fh->iseqno = f->iseqno;
02142    return 0;
02143 }
02144 
02145 static int attempt_transmit(const void *data);
02146 static void __attempt_transmit(const void *data)
02147 {
02148    /* Attempt to transmit the frame to the remote peer...
02149       Called without iaxsl held. */
02150    struct iax_frame *f = (struct iax_frame *)data;
02151    int freeme=0;
02152    int callno = f->callno;
02153    /* Make sure this call is still active */
02154    if (callno) 
02155       ast_mutex_lock(&iaxsl[callno]);
02156    if (callno && iaxs[callno]) {
02157       if ((f->retries < 0) /* Already ACK'd */ ||
02158           (f->retries >= max_retries) /* Too many attempts */) {
02159             /* Record an error if we've transmitted too many times */
02160             if (f->retries >= max_retries) {
02161                if (f->transfer) {
02162                   /* Transfer timeout */
02163                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02164                } else if (f->final) {
02165                   if (f->final) 
02166                      iax2_destroy(callno);
02167                } else {
02168                   if (iaxs[callno]->owner)
02169                      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);
02170                   iaxs[callno]->error = ETIMEDOUT;
02171                   if (iaxs[callno]->owner) {
02172                      struct ast_frame fr = { 0, };
02173                      /* Hangup the fd */
02174                      fr.frametype = AST_FRAME_CONTROL;
02175                      fr.subclass = AST_CONTROL_HANGUP;
02176                      iax2_queue_frame(callno, &fr); // XXX
02177                      /* Remember, owner could disappear */
02178                      if (iaxs[callno] && iaxs[callno]->owner)
02179                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02180                   } else {
02181                      if (iaxs[callno]->reg) {
02182                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02183                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02184                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02185                      }
02186                      iax2_destroy(callno);
02187                   }
02188                }
02189 
02190             }
02191             freeme++;
02192       } else {
02193          /* Update it if it needs it */
02194          update_packet(f);
02195          /* Attempt transmission */
02196          send_packet(f);
02197          f->retries++;
02198          /* Try again later after 10 times as long */
02199          f->retrytime *= 10;
02200          if (f->retrytime > MAX_RETRY_TIME)
02201             f->retrytime = MAX_RETRY_TIME;
02202          /* Transfer messages max out at one second */
02203          if (f->transfer && (f->retrytime > 1000))
02204             f->retrytime = 1000;
02205          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02206       }
02207    } else {
02208       /* Make sure it gets freed */
02209       f->retries = -1;
02210       freeme++;
02211    }
02212    if (callno)
02213       ast_mutex_unlock(&iaxsl[callno]);
02214    /* Do not try again */
02215    if (freeme) {
02216       /* Don't attempt delivery, just remove it from the queue */
02217       AST_LIST_LOCK(&iaxq.queue);
02218       AST_LIST_REMOVE(&iaxq.queue, f, list);
02219       iaxq.count--;
02220       AST_LIST_UNLOCK(&iaxq.queue);
02221       f->retrans = -1;
02222       /* Free the IAX frame */
02223       iax2_frame_free(f);
02224    }
02225 }
02226 
02227 static int attempt_transmit(const void *data)
02228 {
02229 #ifdef SCHED_MULTITHREADED
02230    if (schedule_action(__attempt_transmit, data))
02231 #endif      
02232       __attempt_transmit(data);
02233    return 0;
02234 }
02235 
02236 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02237 {
02238    struct iax2_peer *peer;
02239 
02240    if (argc != 4)
02241         return RESULT_SHOWUSAGE;
02242    if (!strcmp(argv[3],"all")) {
02243       reload_config();
02244       ast_cli(fd, "OK cache is flushed.\n");
02245    } else if ((peer = find_peer(argv[3], 0))) {
02246       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02247          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02248          expire_registry(peer_ref(peer));
02249          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02250       } else {
02251          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02252       }
02253       peer_unref(peer);
02254    } else {
02255       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02256    }
02257    
02258    return RESULT_SUCCESS;
02259 }
02260 
02261 static int iax2_test_losspct(int fd, int argc, char *argv[])
02262 {
02263        if (argc != 4)
02264                return RESULT_SHOWUSAGE;
02265 
02266        test_losspct = atoi(argv[3]);
02267 
02268        return RESULT_SUCCESS;
02269 }
02270 
02271 #ifdef IAXTESTS
02272 static int iax2_test_late(int fd, int argc, char *argv[])
02273 {
02274    if (argc != 4)
02275       return RESULT_SHOWUSAGE;
02276 
02277    test_late = atoi(argv[3]);
02278 
02279    return RESULT_SUCCESS;
02280 }
02281 
02282 static int iax2_test_resync(int fd, int argc, char *argv[])
02283 {
02284    if (argc != 4)
02285       return RESULT_SHOWUSAGE;
02286 
02287    test_resync = atoi(argv[3]);
02288 
02289    return RESULT_SUCCESS;
02290 }
02291 
02292 static int iax2_test_jitter(int fd, int argc, char *argv[])
02293 {
02294    if (argc < 4 || argc > 5)
02295       return RESULT_SHOWUSAGE;
02296 
02297    test_jit = atoi(argv[3]);
02298    if (argc == 5) 
02299       test_jitpct = atoi(argv[4]);
02300 
02301    return RESULT_SUCCESS;
02302 }
02303 #endif /* IAXTESTS */
02304 
02305 /*! \brief  peer_status: Report Peer status in character string */
02306 /*    returns 1 if peer is online, -1 if unmonitored */
02307 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02308 {
02309    int res = 0;
02310    if (peer->maxms) {
02311       if (peer->lastms < 0) {
02312          ast_copy_string(status, "UNREACHABLE", statuslen);
02313       } else if (peer->lastms > peer->maxms) {
02314          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02315          res = 1;
02316       } else if (peer->lastms) {
02317          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02318          res = 1;
02319       } else {
02320          ast_copy_string(status, "UNKNOWN", statuslen);
02321       }
02322    } else { 
02323       ast_copy_string(status, "Unmonitored", statuslen);
02324       res = -1;
02325    }
02326    return res;
02327 }
02328 
02329 /*! \brief Show one peer in detail */
02330 static int iax2_show_peer(int fd, int argc, char *argv[])
02331 {
02332    char status[30];
02333    char cbuf[256];
02334    struct iax2_peer *peer;
02335    char codec_buf[512];
02336    int x = 0, codec = 0, load_realtime = 0;
02337 
02338    if (argc < 4)
02339       return RESULT_SHOWUSAGE;
02340 
02341    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02342 
02343    peer = find_peer(argv[3], load_realtime);
02344    if (peer) {
02345       ast_cli(fd,"\n\n");
02346       ast_cli(fd, "  * Name       : %s\n", peer->name);
02347       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02348       ast_cli(fd, "  Context      : %s\n", peer->context);
02349       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02350       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02351       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02352       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02353       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02354       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));
02355       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02356       ast_cli(fd, "  Username     : %s\n", peer->username);
02357       ast_cli(fd, "  Codecs       : ");
02358       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02359       ast_cli(fd, "%s\n", codec_buf);
02360 
02361       ast_cli(fd, "  Codec Order  : (");
02362       for(x = 0; x < 32 ; x++) {
02363          codec = ast_codec_pref_index(&peer->prefs,x);
02364          if(!codec)
02365             break;
02366          ast_cli(fd, "%s", ast_getformatname(codec));
02367          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02368             ast_cli(fd, "|");
02369       }
02370 
02371       if (!x)
02372          ast_cli(fd, "none");
02373       ast_cli(fd, ")\n");
02374 
02375       ast_cli(fd, "  Status       : ");
02376       peer_status(peer, status, sizeof(status));   
02377       ast_cli(fd, "%s\n",status);
02378       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02379       ast_cli(fd,"\n");
02380       peer_unref(peer);
02381    } else {
02382       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02383       ast_cli(fd,"\n");
02384    }
02385 
02386    return RESULT_SUCCESS;
02387 }
02388 
02389 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02390 {
02391    int which = 0;
02392    struct iax2_peer *peer;
02393    char *res = NULL;
02394    int wordlen = strlen(word);
02395    struct ao2_iterator i;
02396 
02397    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02398    if (pos != 3)
02399       return NULL;
02400 
02401    i = ao2_iterator_init(peers, 0);
02402    while ((peer = ao2_iterator_next(&i))) {
02403       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02404          res = ast_strdup(peer->name);
02405          peer_unref(peer);
02406          break;
02407       }
02408       peer_unref(peer);
02409    }
02410 
02411    return res;
02412 }
02413 
02414 static int iax2_show_stats(int fd, int argc, char *argv[])
02415 {
02416    struct iax_frame *cur;
02417    int cnt = 0, dead=0, final=0;
02418 
02419    if (argc != 3)
02420       return RESULT_SHOWUSAGE;
02421 
02422    AST_LIST_LOCK(&iaxq.queue);
02423    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02424       if (cur->retries < 0)
02425          dead++;
02426       if (cur->final)
02427          final++;
02428       cnt++;
02429    }
02430    AST_LIST_UNLOCK(&iaxq.queue);
02431 
02432    ast_cli(fd, "    IAX Statistics\n");
02433    ast_cli(fd, "---------------------\n");
02434    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02435    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02436    
02437    return RESULT_SUCCESS;
02438 }
02439 
02440 static int iax2_show_cache(int fd, int argc, char *argv[])
02441 {
02442    struct iax2_dpcache *dp;
02443    char tmp[1024], *pc;
02444    int s;
02445    int x,y;
02446    struct timeval tv;
02447    gettimeofday(&tv, NULL);
02448    ast_mutex_lock(&dpcache_lock);
02449    dp = dpcache;
02450    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02451    while(dp) {
02452       s = dp->expiry.tv_sec - tv.tv_sec;
02453       tmp[0] = '\0';
02454       if (dp->flags & CACHE_FLAG_EXISTS)
02455          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02456       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02457          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02458       if (dp->flags & CACHE_FLAG_CANEXIST)
02459          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02460       if (dp->flags & CACHE_FLAG_PENDING)
02461          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02462       if (dp->flags & CACHE_FLAG_TIMEOUT)
02463          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02464       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02465          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02466       if (dp->flags & CACHE_FLAG_MATCHMORE)
02467          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02468       if (dp->flags & CACHE_FLAG_UNKNOWN)
02469          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02470       /* Trim trailing pipe */
02471       if (!ast_strlen_zero(tmp))
02472          tmp[strlen(tmp) - 1] = '\0';
02473       else
02474          ast_copy_string(tmp, "(none)", sizeof(tmp));
02475       y=0;
02476       pc = strchr(dp->peercontext, '@');
02477       if (!pc)
02478          pc = dp->peercontext;
02479       else
02480          pc++;
02481       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02482          if (dp->waiters[x] > -1)
02483             y++;
02484       if (s > 0)
02485          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02486       else
02487          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02488       dp = dp->next;
02489    }
02490    ast_mutex_unlock(&dpcache_lock);
02491    return RESULT_SUCCESS;
02492 }
02493 
02494 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02495 
02496 static void unwrap_timestamp(struct iax_frame *fr)
02497 {
02498    int x;
02499 
02500    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02501       x = fr->ts - iaxs[fr->callno]->last;
02502       if (x < -50000) {
02503          /* Sudden big jump backwards in timestamp:
02504             What likely happened here is that miniframe timestamp has circled but we haven't
02505             gotten the update from the main packet.  We'll just pretend that we did, and
02506             update the timestamp appropriately. */
02507          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02508          if (option_debug && iaxdebug)
02509             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02510       }
02511       if (x > 50000) {
02512          /* Sudden apparent big jump forwards in timestamp:
02513             What's likely happened is this is an old miniframe belonging to the previous
02514             top-16-bit timestamp that has turned up out of order.
02515             Adjust the timestamp appropriately. */
02516          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02517          if (option_debug && iaxdebug)
02518             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02519       }
02520    }
02521 }
02522 
02523 static int get_from_jb(const void *p);
02524 
02525 static void update_jbsched(struct chan_iax2_pvt *pvt)
02526 {
02527    int when;
02528    
02529    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02530    
02531    when = jb_next(pvt->jb) - when;
02532 
02533    AST_SCHED_DEL(sched, pvt->jbid);
02534 
02535    if(when <= 0) {
02536       /* XXX should really just empty until when > 0.. */
02537       when = 1;
02538    }
02539    
02540    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02541 }
02542 
02543 static void __get_from_jb(const void *p) 
02544 {
02545    int callno = PTR_TO_CALLNO(p);
02546    struct chan_iax2_pvt *pvt = NULL;
02547    struct iax_frame *fr;
02548    jb_frame frame;
02549    int ret;
02550    long now;
02551    long next;
02552    struct timeval tv;
02553    
02554    /* Make sure we have a valid private structure before going on */
02555    ast_mutex_lock(&iaxsl[callno]);
02556    pvt = iaxs[callno];
02557    if (!pvt) {
02558       /* No go! */
02559       ast_mutex_unlock(&iaxsl[callno]);
02560       return;
02561    }
02562 
02563    pvt->jbid = -1;
02564    
02565    gettimeofday(&tv,NULL);
02566    /* round up a millisecond since ast_sched_runq does; */
02567    /* prevents us from spinning while waiting for our now */
02568    /* to catch up with runq's now */
02569    tv.tv_usec += 1000;
02570    
02571    now = ast_tvdiff_ms(tv, pvt->rxcore);
02572    
02573    if(now >= (next = jb_next(pvt->jb))) {
02574       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02575       switch(ret) {
02576       case JB_OK:
02577          fr = frame.data;
02578          __do_deliver(fr);
02579          /* __do_deliver() can cause the call to disappear */
02580          pvt = iaxs[callno];
02581          break;
02582       case JB_INTERP:
02583       {
02584          struct ast_frame af = { 0, };
02585          
02586          /* create an interpolation frame */
02587          af.frametype = AST_FRAME_VOICE;
02588          af.subclass = pvt->voiceformat;
02589          af.samples  = frame.ms * 8;
02590          af.src  = "IAX2 JB interpolation";
02591          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02592          af.offset = AST_FRIENDLY_OFFSET;
02593          
02594          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02595           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02596          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02597             iax2_queue_frame(callno, &af);
02598             /* iax2_queue_frame() could cause the call to disappear */
02599             pvt = iaxs[callno];
02600          }
02601       }
02602          break;
02603       case JB_DROP:
02604          iax2_frame_free(frame.data);
02605          break;
02606       case JB_NOFRAME:
02607       case JB_EMPTY:
02608          /* do nothing */
02609          break;
02610       default:
02611          /* shouldn't happen */
02612          break;
02613       }
02614    }
02615    if (pvt)
02616       update_jbsched(pvt);
02617    ast_mutex_unlock(&iaxsl[callno]);
02618 }
02619 
02620 static int get_from_jb(const void *data)
02621 {
02622 #ifdef SCHED_MULTITHREADED
02623    if (schedule_action(__get_from_jb, data))
02624 #endif      
02625       __get_from_jb(data);
02626    return 0;
02627 }
02628 
02629 /*!
02630  * \note This function assumes fr->callno is locked
02631  *
02632  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02633  * was valid before calling it, it may no longer be valid after calling it.
02634  */
02635 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02636 {
02637    int type, len;
02638    int ret;
02639    int needfree = 0;
02640    struct ast_channel *owner = NULL;
02641    struct ast_channel *bridge = NULL;
02642    
02643    /* Attempt to recover wrapped timestamps */
02644    unwrap_timestamp(fr);
02645 
02646    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02647    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02648       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02649    else {
02650 #if 0
02651       if (option_debug)
02652          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02653 #endif
02654       fr->af.delivery = ast_tv(0,0);
02655    }
02656 
02657    type = JB_TYPE_CONTROL;
02658    len = 0;
02659 
02660    if(fr->af.frametype == AST_FRAME_VOICE) {
02661       type = JB_TYPE_VOICE;
02662       len = ast_codec_get_samples(&fr->af) / 8;
02663    } else if(fr->af.frametype == AST_FRAME_CNG) {
02664       type = JB_TYPE_SILENCE;
02665    }
02666 
02667    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02668       if (tsout)
02669          *tsout = fr->ts;
02670       __do_deliver(fr);
02671       return -1;
02672    }
02673 
02674    if ((owner = iaxs[fr->callno]->owner))
02675       bridge = ast_bridged_channel(owner);
02676 
02677    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02678     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02679    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02680       jb_frame frame;
02681 
02682       /* deliver any frames in the jb */
02683       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02684          __do_deliver(frame.data);
02685          /* __do_deliver() can make the call disappear */
02686          if (!iaxs[fr->callno])
02687             return -1;
02688       }
02689 
02690       jb_reset(iaxs[fr->callno]->jb);
02691 
02692       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02693 
02694       /* deliver this frame now */
02695       if (tsout)
02696          *tsout = fr->ts;
02697       __do_deliver(fr);
02698       return -1;
02699    }
02700 
02701    /* insert into jitterbuffer */
02702    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02703    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02704          calc_rxstamp(iaxs[fr->callno],fr->ts));
02705    if (ret == JB_DROP) {
02706       needfree++;
02707    } else if (ret == JB_SCHED) {
02708       update_jbsched(iaxs[fr->callno]);
02709    }
02710    if (tsout)
02711       *tsout = fr->ts;
02712    if (needfree) {
02713       /* Free our iax frame */
02714       iax2_frame_free(fr);
02715       return -1;
02716    }
02717    return 0;
02718 }
02719 
02720 static int iax2_transmit(struct iax_frame *fr)
02721 {
02722    /* Lock the queue and place this packet at the end */
02723    /* By setting this to 0, the network thread will send it for us, and
02724       queue retransmission if necessary */
02725    fr->sentyet = 0;
02726    AST_LIST_LOCK(&iaxq.queue);
02727    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02728    iaxq.count++;
02729    AST_LIST_UNLOCK(&iaxq.queue);
02730    /* Wake up the network and scheduler thread */
02731    if (netthreadid != AST_PTHREADT_NULL)
02732       pthread_kill(netthreadid, SIGURG);
02733    signal_condition(&sched_lock, &sched_cond);
02734    return 0;
02735 }
02736 
02737 
02738 
02739 static int iax2_digit_begin(struct ast_channel *c, char digit)
02740 {
02741    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02742 }
02743 
02744 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02745 {
02746    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02747 }
02748 
02749 static int iax2_sendtext(struct ast_channel *c, const char *text)
02750 {
02751    
02752    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02753       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02754 }
02755 
02756 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02757 {
02758    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02759 }
02760 
02761 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02762 {
02763    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02764 }
02765 
02766 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02767 {
02768    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02769    ast_mutex_lock(&iaxsl[callno]);
02770    if (iaxs[callno])
02771       iaxs[callno]->owner = newchan;
02772    else
02773       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02774    ast_mutex_unlock(&iaxsl[callno]);
02775    return 0;
02776 }
02777 
02778 /*!
02779  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02780  *       so do not call this with a pvt lock held.
02781  */
02782 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02783 {
02784    struct ast_variable *var = NULL;
02785    struct ast_variable *tmp;
02786    struct iax2_peer *peer=NULL;
02787    time_t regseconds = 0, nowtime;
02788    int dynamic=0;
02789 
02790    if (peername) {
02791       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02792       if (!var && sin)
02793          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02794    } else if (sin) {
02795       char porta[25];
02796       sprintf(porta, "%d", ntohs(sin->sin_port));
02797       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02798       if (var) {
02799          /* We'll need the peer name in order to build the structure! */
02800          for (tmp = var; tmp; tmp = tmp->next) {
02801             if (!strcasecmp(tmp->name, "name"))
02802                peername = tmp->value;
02803          }
02804       }
02805    }
02806    if (!var && peername) { /* Last ditch effort */
02807       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02808       /*!\note
02809        * If this one loaded something, then we need to ensure that the host
02810        * field matched.  The only reason why we can't have this as a criteria
02811        * is because we only have the IP address and the host field might be
02812        * set as a name (and the reverse PTR might not match).
02813        */
02814       if (var && sin) {
02815          for (tmp = var; tmp; tmp = tmp->next) {
02816             if (!strcasecmp(tmp->name, "host")) {
02817                struct ast_hostent ahp;
02818                struct hostent *hp;
02819                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02820                   /* No match */
02821                   ast_variables_destroy(var);
02822                   var = NULL;
02823                }
02824                break;
02825             }
02826          }
02827       }
02828    }
02829    if (!var)
02830       return NULL;
02831 
02832    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02833    
02834    if (!peer) {
02835       ast_variables_destroy(var);
02836       return NULL;
02837    }
02838 
02839    for (tmp = var; tmp; tmp = tmp->next) {
02840       /* Make sure it's not a user only... */
02841       if (!strcasecmp(tmp->name, "type")) {
02842          if (strcasecmp(tmp->value, "friend") &&
02843              strcasecmp(tmp->value, "peer")) {
02844             /* Whoops, we weren't supposed to exist! */
02845             peer = peer_unref(peer);
02846             break;
02847          } 
02848       } else if (!strcasecmp(tmp->name, "regseconds")) {
02849          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02850       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02851          inet_aton(tmp->value, &(peer->addr.sin_addr));
02852       } else if (!strcasecmp(tmp->name, "port")) {
02853          peer->addr.sin_port = htons(atoi(tmp->value));
02854       } else if (!strcasecmp(tmp->name, "host")) {
02855          if (!strcasecmp(tmp->value, "dynamic"))
02856             dynamic = 1;
02857       }
02858    }
02859 
02860    ast_variables_destroy(var);
02861 
02862    if (!peer)
02863       return NULL;
02864 
02865    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02866       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02867       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02868          if (peer->expire > -1) {
02869             if (!ast_sched_del(sched, peer->expire)) {
02870                peer->expire = -1;
02871                peer_unref(peer);
02872             }
02873          }
02874          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02875          if (peer->expire == -1)
02876             peer_unref(peer);
02877       }
02878       ao2_link(peers, peer);
02879       if (ast_test_flag(peer, IAX_DYNAMIC))
02880          reg_source_db(peer);
02881    } else {
02882       ast_set_flag(peer, IAX_TEMPONLY);   
02883    }
02884 
02885    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02886       time(&nowtime);
02887       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02888          memset(&peer->addr, 0, sizeof(peer->addr));
02889          realtime_update_peer(peer->name, &peer->addr, 0);
02890          if (option_debug)
02891             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02892                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02893       }
02894       else {
02895          if (option_debug)
02896             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02897                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02898       }
02899    }
02900 
02901    return peer;
02902 }
02903 
02904 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02905 {
02906    struct ast_variable *var;
02907    struct ast_variable *tmp;
02908    struct iax2_user *user=NULL;
02909 
02910    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02911    if (!var)
02912       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02913    if (!var && sin) {
02914       char porta[6];
02915       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02916       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02917       if (!var)
02918          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02919    }
02920    if (!var) { /* Last ditch effort */
02921       var = ast_load_realtime("iaxusers", "name", username, NULL);
02922       /*!\note
02923        * If this one loaded something, then we need to ensure that the host
02924        * field matched.  The only reason why we can't have this as a criteria
02925        * is because we only have the IP address and the host field might be
02926        * set as a name (and the reverse PTR might not match).
02927        */
02928       if (var) {
02929          for (tmp = var; tmp; tmp = tmp->next) {
02930             if (!strcasecmp(tmp->name, "host")) {
02931                struct ast_hostent ahp;
02932                struct hostent *hp;
02933                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02934                   /* No match */
02935                   ast_variables_destroy(var);
02936                   var = NULL;
02937                }
02938                break;
02939             }
02940          }
02941       }
02942    }
02943    if (!var)
02944       return NULL;
02945 
02946    tmp = var;
02947    while(tmp) {
02948       /* Make sure it's not a peer only... */
02949       if (!strcasecmp(tmp->name, "type")) {
02950          if (strcasecmp(tmp->value, "friend") &&
02951              strcasecmp(tmp->value, "user")) {
02952             return NULL;
02953          } 
02954       }
02955       tmp = tmp->next;
02956    }
02957 
02958    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02959 
02960    ast_variables_destroy(var);
02961 
02962    if (!user)
02963       return NULL;
02964 
02965    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02966       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02967       ao2_link(users, user);
02968    } else {
02969       ast_set_flag(user, IAX_TEMPONLY);   
02970    }
02971 
02972    return user;
02973 }
02974 
02975 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02976 {
02977    char port[10];
02978    char regseconds[20];
02979    
02980    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02981    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02982    ast_update_realtime("iaxpeers", "name", peername, 
02983       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02984       "regseconds", regseconds, NULL);
02985 }
02986 
02987 struct create_addr_info {
02988    int capability;
02989    unsigned int flags;
02990    int maxtime;
02991    int encmethods;
02992    int found;
02993    int sockfd;
02994    int adsi;
02995    char username[80];
02996    char secret[80];
02997    char outkey[80];
02998    char timezone[80];
02999    char prefs[32];
03000    char context[AST_MAX_CONTEXT];
03001    char peercontext[AST_MAX_CONTEXT];
03002    char mohinterpret[MAX_MUSICCLASS];
03003    char mohsuggest[MAX_MUSICCLASS];
03004 };
03005 
03006 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03007 {
03008    struct ast_hostent ahp;
03009    struct hostent *hp;
03010    struct iax2_peer *peer;
03011    int res = -1;
03012    struct ast_codec_pref ourprefs;
03013 
03014    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03015    cai->sockfd = defaultsockfd;
03016    cai->maxtime = 0;
03017    sin->sin_family = AF_INET;
03018 
03019    if (!(peer = find_peer(peername, 1))) {
03020       cai->found = 0;
03021 
03022       hp = ast_gethostbyname(peername, &ahp);
03023       if (hp) {
03024          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03025          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03026          /* use global iax prefs for unknown peer/user */
03027          /* But move the calling channel's native codec to the top of the preference list */
03028          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03029          if (c)
03030             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03031          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03032          return 0;
03033       } else {
03034          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03035          return -1;
03036       }
03037    }
03038 
03039    cai->found = 1;
03040    
03041    /* if the peer has no address (current or default), return failure */
03042    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03043       goto return_unref;
03044 
03045    /* if the peer is being monitored and is currently unreachable, return failure */
03046    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03047       goto return_unref;
03048 
03049    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03050    cai->maxtime = peer->maxms;
03051    cai->capability = peer->capability;
03052    cai->encmethods = peer->encmethods;
03053    cai->sockfd = peer->sockfd;
03054    cai->adsi = peer->adsi;
03055    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03056    /* Move the calling channel's native codec to the top of the preference list */
03057    if (c) {
03058       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03059       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03060    }
03061    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03062    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03063    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03064    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03065    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03066    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03067    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03068    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03069    if (ast_strlen_zero(peer->dbsecret)) {
03070       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03071    } else {
03072       char *family;
03073       char *key = NULL;
03074 
03075       family = ast_strdupa(peer->dbsecret);
03076       key = strchr(family, '/');
03077       if (key)
03078          *key++ = '\0';
03079       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03080          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03081          goto return_unref;
03082       }
03083    }
03084 
03085    if (peer->addr.sin_addr.s_addr) {
03086       sin->sin_addr = peer->addr.sin_addr;
03087       sin->sin_port = peer->addr.sin_port;
03088    } else {
03089       sin->sin_addr = peer->defaddr.sin_addr;
03090       sin->sin_port = peer->defaddr.sin_port;
03091    }
03092 
03093    res = 0;
03094 
03095 return_unref:
03096    peer_unref(peer);
03097 
03098    return res;
03099 }
03100 
03101 static void __auto_congest(const void *nothing)
03102 {
03103    int callno = PTR_TO_CALLNO(nothing);
03104    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03105    ast_mutex_lock(&iaxsl[callno]);
03106    if (iaxs[callno]) {
03107       iaxs[callno]->initid = -1;
03108       iax2_queue_frame(callno, &f);
03109       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03110    }
03111    ast_mutex_unlock(&iaxsl[callno]);
03112 }
03113 
03114 static int auto_congest(const void *data)
03115 {
03116 #ifdef SCHED_MULTITHREADED
03117    if (schedule_action(__auto_congest, data))
03118 #endif      
03119       __auto_congest(data);
03120    return 0;
03121 }
03122 
03123 static unsigned int iax2_datetime(const char *tz)
03124 {
03125    time_t t;
03126    struct tm tm;
03127    unsigned int tmp;
03128    time(&t);
03129    if (!ast_strlen_zero(tz))
03130       ast_localtime(&t, &tm, tz);
03131    else
03132       ast_localtime(&t, &tm, NULL);
03133    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03134    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03135    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03136    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03137    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03138    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03139    return tmp;
03140 }
03141 
03142 struct parsed_dial_string {
03143    char *username;
03144    char *password;
03145    char *key;
03146    char *peer;
03147    char *port;
03148    char *exten;
03149    char *context;
03150    char *options;
03151 };
03152 
03153 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03154 {
03155    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03156       .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03157       .csub = compress_subclass(command) };
03158 
03159    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03160 }
03161 
03162 /*!
03163  * \brief Parses an IAX dial string into its component parts.
03164  * \param data the string to be parsed
03165  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03166  * \return nothing
03167  *
03168  * This function parses the string and fills the structure
03169  * with pointers to its component parts. The input string
03170  * will be modified.
03171  *
03172  * \note This function supports both plaintext passwords and RSA
03173  * key names; if the password string is formatted as '[keyname]',
03174  * then the keyname will be placed into the key field, and the
03175  * password field will be set to NULL.
03176  *
03177  * \note The dial string format is:
03178  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03179  */
03180 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03181 {
03182    if (ast_strlen_zero(data))
03183       return;
03184 
03185    pds->peer = strsep(&data, "/");
03186    pds->exten = strsep(&data, "/");
03187    pds->options = data;
03188 
03189    if (pds->exten) {
03190       data = pds->exten;
03191       pds->exten = strsep(&data, "@");
03192       pds->context = data;
03193    }
03194 
03195    if (strchr(pds->peer, '@')) {
03196       data = pds->peer;
03197       pds->username = strsep(&data, "@");
03198       pds->peer = data;
03199    }
03200 
03201    if (pds->username) {
03202       data = pds->username;
03203       pds->username = strsep(&data, ":");
03204       pds->password = data;
03205    }
03206 
03207    data = pds->peer;
03208    pds->peer = strsep(&data, ":");
03209    pds->port = data;
03210 
03211    /* check for a key name wrapped in [] in the secret position, if found,
03212       move it to the key field instead
03213    */
03214    if (pds->password && (pds->password[0] == '[')) {
03215       pds->key = ast_strip_quoted(pds->password, "[", "]");
03216       pds->password = NULL;
03217    }
03218 }
03219 
03220 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03221 {
03222    struct sockaddr_in sin;
03223    char *l=NULL, *n=NULL, *tmpstr;
03224    struct iax_ie_data ied;
03225    char *defaultrdest = "s";
03226    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03227    struct parsed_dial_string pds;
03228    struct create_addr_info cai;
03229 
03230    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03231       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03232       return -1;
03233    }
03234 
03235    memset(&cai, 0, sizeof(cai));
03236    cai.encmethods = iax2_encryption;
03237 
03238    memset(&pds, 0, sizeof(pds));
03239    tmpstr = ast_strdupa(dest);
03240    parse_dial_string(tmpstr, &pds);
03241 
03242    if (ast_strlen_zero(pds.peer)) {
03243       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03244       return -1;
03245    }
03246 
03247    if (!pds.exten) {
03248       pds.exten = defaultrdest;
03249    }
03250 
03251    if (create_addr(pds.peer, c, &sin, &cai)) {
03252       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03253       return -1;
03254    }
03255 
03256    if (!pds.username && !ast_strlen_zero(cai.username))
03257       pds.username = cai.username;
03258    if (!pds.password && !ast_strlen_zero(cai.secret))
03259       pds.password = cai.secret;
03260    if (!pds.key && !ast_strlen_zero(cai.outkey))
03261       pds.key = cai.outkey;
03262    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03263       pds.context = cai.peercontext;
03264 
03265    /* Keep track of the context for outgoing calls too */
03266    ast_copy_string(c->context, cai.context, sizeof(c->context));
03267 
03268    if (pds.port)
03269       sin.sin_port = htons(atoi(pds.port));
03270 
03271    l = c->cid.cid_num;
03272    n = c->cid.cid_name;
03273 
03274    /* Now build request */ 
03275    memset(&ied, 0, sizeof(ied));
03276 
03277    /* On new call, first IE MUST be IAX version of caller */
03278    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03279    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03280    if (pds.options && strchr(pds.options, 'a')) {
03281       /* Request auto answer */
03282       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03283    }
03284 
03285    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03286 
03287    if (l) {
03288       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03289       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03290    } else {
03291       if (n)
03292          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03293       else
03294          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03295    }
03296 
03297    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03298    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03299 
03300    if (n)
03301       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03302    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03303       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03304 
03305    if (!ast_strlen_zero(c->language))
03306       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03307    if (!ast_strlen_zero(c->cid.cid_dnid))
03308       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03309    if (!ast_strlen_zero(c->cid.cid_rdnis))
03310       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03311 
03312    if (pds.context)
03313       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03314 
03315    if (pds.username)
03316       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03317 
03318    if (cai.encmethods)
03319       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03320 
03321    ast_mutex_lock(&iaxsl[callno]);
03322 
03323    if (!ast_strlen_zero(c->context))
03324       ast_string_field_set(iaxs[callno], context, c->context);
03325 
03326    if (pds.username)
03327       ast_string_field_set(iaxs[callno], username, pds.username);
03328 
03329    iaxs[callno]->encmethods = cai.encmethods;
03330 
03331    iaxs[callno]->adsi = cai.adsi;
03332    
03333    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03334    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03335 
03336    if (pds.key)
03337       ast_string_field_set(iaxs[callno], outkey, pds.key);
03338    if (pds.password)
03339       ast_string_field_set(iaxs[callno], secret, pds.password);
03340 
03341    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03342    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03343    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03344    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03345 
03346    if (iaxs[callno]->maxtime) {
03347       /* Initialize pingtime and auto-congest time */
03348       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03349       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03350    } else if (autokill) {
03351       iaxs[callno]->pingtime = autokill / 2;
03352       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03353    }
03354 
03355    /* send the command using the appropriate socket for this peer */
03356    iaxs[callno]->sockfd = cai.sockfd;
03357 
03358    /* Transmit the string in a "NEW" request */
03359    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03360 
03361    ast_mutex_unlock(&iaxsl[callno]);
03362    ast_setstate(c, AST_STATE_RINGING);
03363    
03364    return 0;
03365 }
03366 
03367 static int iax2_hangup(struct ast_channel *c) 
03368 {
03369    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03370    int alreadygone;
03371    struct iax_ie_data ied;
03372    memset(&ied, 0, sizeof(ied));
03373    ast_mutex_lock(&iaxsl[callno]);
03374    if (callno && iaxs[callno]) {
03375       if (option_debug)
03376          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03377       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03378       /* Send the hangup unless we have had a transmission error or are already gone */
03379       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03380       if (!iaxs[callno]->error && !alreadygone) {
03381          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03382          if (!iaxs[callno]) {
03383             ast_mutex_unlock(&iaxsl[callno]);
03384             return 0;
03385          }
03386       }
03387       /* Explicitly predestroy it */
03388       iax2_predestroy(callno);
03389       /* If we were already gone to begin with, destroy us now */
03390       if (alreadygone && iaxs[callno]) {
03391          if (option_debug)
03392             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03393          iax2_destroy(callno);
03394       }
03395    }
03396    ast_mutex_unlock(&iaxsl[callno]);
03397    if (option_verbose > 2) 
03398       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03399    return 0;
03400 }
03401 
03402 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03403 {
03404    struct ast_option_header *h;
03405    int res;
03406 
03407    switch (option) {
03408    case AST_OPTION_TXGAIN:
03409    case AST_OPTION_RXGAIN:
03410       /* these two cannot be sent, because they require a result */
03411       errno = ENOSYS;
03412       return -1;
03413    default:
03414       if (!(h = ast_malloc(datalen + sizeof(*h))))
03415          return -1;
03416 
03417       h->flag = AST_OPTION_FLAG_REQUEST;
03418       h->option = htons(option);
03419       memcpy(h->data, data, datalen);
03420       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03421                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03422                  datalen + sizeof(*h), -1);
03423       free(h);
03424       return res;
03425    }
03426 }
03427 
03428 static struct ast_frame *iax2_read(struct ast_channel *c) 
03429 {
03430    ast_log(LOG_NOTICE, "I should never be called!\n");
03431    return &ast_null_frame;
03432 }
03433 
03434 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03435 {
03436    int res;
03437    struct iax_ie_data ied0;
03438    struct iax_ie_data ied1;
03439    unsigned int transferid = (unsigned int)ast_random();
03440    memset(&ied0, 0, sizeof(ied0));
03441    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03442    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03443    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03444 
03445    memset(&ied1, 0, sizeof(ied1));
03446    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03447    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03448    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03449    
03450    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03451    if (res)
03452       return -1;
03453    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03454    if (res)
03455       return -1;
03456    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03457    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03458    return 0;
03459 }
03460 
03461 static void lock_both(unsigned short callno0, unsigned short callno1)
03462 {
03463    ast_mutex_lock(&iaxsl[callno0]);
03464    while (ast_mutex_trylock(&iaxsl[callno1])) {
03465       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03466    }
03467 }
03468 
03469 static void unlock_both(unsigned short callno0, unsigned short callno1)
03470 {
03471    ast_mutex_unlock(&iaxsl[callno1]);
03472    ast_mutex_unlock(&iaxsl[callno0]);
03473 }
03474 
03475 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)
03476 {
03477    struct ast_channel *cs[3];
03478    struct ast_channel *who, *other;
03479    int to = -1;
03480    int res = -1;
03481    int transferstarted=0;
03482    struct ast_frame *f;
03483    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03484    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03485    struct timeval waittimer = {0, 0}, tv;
03486 
03487    lock_both(callno0, callno1);
03488    if (!iaxs[callno0] || !iaxs[callno1]) {
03489       unlock_both(callno0, callno1);
03490       return AST_BRIDGE_FAILED;
03491    }
03492    /* Put them in native bridge mode */
03493    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03494       iaxs[callno0]->bridgecallno = callno1;
03495       iaxs[callno1]->bridgecallno = callno0;
03496    }
03497    unlock_both(callno0, callno1);
03498 
03499    /* If not, try to bridge until we can execute a transfer, if we can */
03500    cs[0] = c0;
03501    cs[1] = c1;
03502    for (/* ever */;;) {
03503       /* Check in case we got masqueraded into */
03504       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03505          if (option_verbose > 2)
03506             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03507          /* Remove from native mode */
03508          if (c0->tech == &iax2_tech) {
03509             ast_mutex_lock(&iaxsl[callno0]);
03510             iaxs[callno0]->bridgecallno = 0;
03511             ast_mutex_unlock(&iaxsl[callno0]);
03512          }
03513          if (c1->tech == &iax2_tech) {
03514             ast_mutex_lock(&iaxsl[callno1]);
03515             iaxs[callno1]->bridgecallno = 0;
03516             ast_mutex_unlock(&iaxsl[callno1]);
03517          }
03518          return AST_BRIDGE_FAILED_NOWARN;
03519       }
03520       if (c0->nativeformats != c1->nativeformats) {
03521          if (option_verbose > 2) {
03522             char buf0[255];
03523             char buf1[255];
03524             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03525             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03526             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03527          }
03528          /* Remove from native mode */
03529          lock_both(callno0, callno1);
03530          if (iaxs[callno0])
03531             iaxs[callno0]->bridgecallno = 0;
03532          if (iaxs[callno1])
03533             iaxs[callno1]->bridgecallno = 0;
03534          unlock_both(callno0, callno1);
03535          return AST_BRIDGE_FAILED_NOWARN;
03536       }
03537       /* check if transfered and if we really want native bridging */
03538       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03539          /* Try the transfer */
03540          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03541                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03542             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03543          transferstarted = 1;
03544       }
03545       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03546          /* Call has been transferred.  We're no longer involved */
03547          gettimeofday(&tv, NULL);
03548          if (ast_tvzero(waittimer)) {
03549             waittimer = tv;
03550          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03551             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03552             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03553             *fo = NULL;
03554             *rc = c0;
03555             res = AST_BRIDGE_COMPLETE;
03556             break;
03557          }
03558       }
03559       to = 1000;
03560       who = ast_waitfor_n(cs, 2, &to);
03561       if (timeoutms > -1) {
03562          timeoutms -= (1000 - to);
03563          if (timeoutms < 0)
03564             timeoutms = 0;
03565       }
03566       if (!who) {
03567          if (!timeoutms) {
03568             res = AST_BRIDGE_RETRY;
03569             break;
03570          }
03571          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03572             res = AST_BRIDGE_FAILED;
03573             break;
03574          }
03575          continue;
03576       }
03577       f = ast_read(who);
03578       if (!f) {
03579          *fo = NULL;
03580          *rc = who;
03581          res = AST_BRIDGE_COMPLETE;
03582          break;
03583       }
03584       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03585          *fo = f;
03586          *rc = who;
03587          res =  AST_BRIDGE_COMPLETE;
03588          break;
03589       }
03590       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03591       if ((f->frametype == AST_FRAME_VOICE) ||
03592           (f->frametype == AST_FRAME_TEXT) ||
03593           (f->frametype == AST_FRAME_VIDEO) || 
03594           (f->frametype == AST_FRAME_IMAGE) ||
03595           (f->frametype == AST_FRAME_DTMF)) {
03596          /* monitored dtmf take out of the bridge.
03597           * check if we monitor the specific source.
03598           */
03599          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03600          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03601             *rc = who;
03602             *fo = f;
03603             res = AST_BRIDGE_COMPLETE;
03604             /* Remove from native mode */
03605             break;
03606          }
03607          /* everything else goes to the other side */
03608          ast_write(other, f);
03609       }
03610       ast_frfree(f);
03611       /* Swap who gets priority */
03612       cs[2] = cs[0];
03613       cs[0] = cs[1];
03614       cs[1] = cs[2];
03615    }
03616    lock_both(callno0, callno1);
03617    if(iaxs[callno0])
03618       iaxs[callno0]->bridgecallno = 0;
03619    if(iaxs[callno1])
03620       iaxs[callno1]->bridgecallno = 0;
03621    unlock_both(callno0, callno1);
03622    return res;
03623 }
03624 
03625 static int iax2_answer(struct ast_channel *c)
03626 {
03627    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03628    if (option_debug)
03629       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03630    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03631 }
03632 
03633 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03634 {
03635    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03636    struct chan_iax2_pvt *pvt;
03637    int res = 0;
03638 
03639    if (option_debug && iaxdebug)
03640       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03641 
03642    ast_mutex_lock(&iaxsl[callno]);
03643    pvt = iaxs[callno];
03644 
03645    if (!pvt->peercallno) {
03646       /* We don't know the remote side's call number, yet.  :( */
03647       int count = 10;
03648       while (count-- && pvt && !pvt->peercallno) {
03649          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03650          pvt = iaxs[callno];
03651       }
03652       if (!pvt->peercallno) {
03653          res = -1;
03654          goto done;
03655       }
03656    }
03657 
03658    switch (condition) {
03659    case AST_CONTROL_HOLD:
03660       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03661          ast_moh_start(c, data, pvt->mohinterpret);
03662          goto done;
03663       }
03664       break;
03665    case AST_CONTROL_UNHOLD:
03666       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03667          ast_moh_stop(c);
03668          goto done;
03669       }
03670    }
03671 
03672    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03673 
03674 done:
03675    ast_mutex_unlock(&iaxsl[callno]);
03676 
03677    return res;
03678 }
03679    
03680 static int iax2_transfer(struct ast_channel *c, const char *dest)
03681 {
03682    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03683    struct iax_ie_data ied;
03684    char tmp[256], *context;
03685    ast_copy_string(tmp, dest, sizeof(tmp));
03686    context = strchr(tmp, '@');
03687    if (context) {
03688       *context = '\0';
03689       context++;
03690    }
03691    memset(&ied, 0, sizeof(ied));
03692    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03693    if (context)
03694       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03695    if (option_debug)
03696       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03697    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03698 }
03699    
03700 static int iax2_getpeertrunk(struct sockaddr_in sin)
03701 {
03702    struct iax2_peer *peer;
03703    int res = 0;
03704    struct ao2_iterator i;
03705 
03706    i = ao2_iterator_init(peers, 0);
03707    while ((peer = ao2_iterator_next(&i))) {
03708       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03709           (peer->addr.sin_port == sin.sin_port)) {
03710          res = ast_test_flag(peer, IAX_TRUNK);
03711          peer_unref(peer);
03712          break;
03713       }
03714       peer_unref(peer);
03715    }
03716 
03717    return res;
03718 }
03719 
03720 /*! \brief  Create new call, interface with the PBX core */
03721 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03722 {
03723    struct ast_channel *tmp;
03724    struct chan_iax2_pvt *i;
03725    struct ast_variable *v = NULL;
03726 
03727    if (!(i = iaxs[callno])) {
03728       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03729       return NULL;
03730    }
03731 
03732    /* Don't hold call lock */
03733    ast_mutex_unlock(&iaxsl[callno]);
03734    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);
03735    ast_mutex_lock(&iaxsl[callno]);
03736    if (!iaxs[callno]) {
03737       if (tmp) {
03738          ast_channel_free(tmp);
03739       }
03740       ast_mutex_unlock(&iaxsl[callno]);
03741       return NULL;
03742    }
03743 
03744    if (!tmp)
03745       return NULL;
03746    tmp->tech = &iax2_tech;
03747    /* We can support any format by default, until we get restricted */
03748    tmp->nativeformats = capability;
03749    tmp->readformat = ast_best_codec(capability);
03750    tmp->writeformat = ast_best_codec(capability);
03751    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03752 
03753    /* Don't use ast_set_callerid() here because it will
03754     * generate a NewCallerID event before the NewChannel event */
03755    if (!ast_strlen_zero(i->ani))
03756       tmp->cid.cid_ani = ast_strdup(i->ani);
03757    else
03758       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03759    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03760    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03761    tmp->cid.cid_pres = i->calling_pres;
03762    tmp->cid.cid_ton = i->calling_ton;
03763    tmp->cid.cid_tns = i->calling_tns;
03764    if (!ast_strlen_zero(i->language))
03765       ast_string_field_set(tmp, language, i->language);
03766    if (!ast_strlen_zero(i->accountcode))
03767       ast_string_field_set(tmp, accountcode, i->accountcode);
03768    if (i->amaflags)
03769       tmp->amaflags = i->amaflags;
03770    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03771    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03772    if (i->adsi)
03773       tmp->adsicpe = i->peeradsicpe;
03774    else
03775       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03776    i->owner = tmp;
03777    i->capability = capability;
03778 
03779    for (v = i->vars ; v ; v = v->next)
03780       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03781 
03782    if (state != AST_STATE_DOWN) {
03783       if (ast_pbx_start(tmp)) {
03784          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03785          ast_hangup(tmp);
03786          i->owner = NULL;
03787          return NULL;
03788       }
03789    }
03790 
03791    ast_module_ref(ast_module_info->self);
03792    
03793    return tmp;
03794 }
03795 
03796 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03797 {
03798    unsigned long int mssincetx; /* unsigned to handle overflows */
03799    long int ms, pred;
03800 
03801    tpeer->trunkact = *tv;
03802    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03803    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03804       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03805       tpeer->txtrunktime = *tv;
03806       tpeer->lastsent = 999999;
03807    }
03808    /* Update last transmit time now */
03809    tpeer->lasttxtime = *tv;
03810    
03811    /* Calculate ms offset */
03812    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03813    /* Predict from last value */
03814    pred = tpeer->lastsent + sampms;
03815    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03816       ms = pred;
03817    
03818    /* We never send the same timestamp twice, so fudge a little if we must */
03819    if (ms == tpeer->lastsent)
03820       ms = tpeer->lastsent + 1;
03821    tpeer->lastsent = ms;
03822    return ms;
03823 }
03824 
03825 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03826 {
03827    long ms; /* NOT unsigned */
03828    if (ast_tvzero(iaxs[callno]->rxcore)) {
03829       /* Initialize rxcore time if appropriate */
03830       gettimeofday(&iaxs[callno]->rxcore, NULL);
03831       /* Round to nearest 20ms so traces look pretty */
03832       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03833    }
03834    /* Calculate difference between trunk and channel */
03835    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03836    /* Return as the sum of trunk time and the difference between trunk and real time */
03837    return ms + ts;
03838 }
03839 
03840 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03841 {
03842    int ms;
03843    int voice = 0;
03844    int genuine = 0;
03845    int adjust;
03846    struct timeval *delivery = NULL;
03847 
03848 
03849    /* What sort of frame do we have?: voice is self-explanatory
03850       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03851       non-genuine frames are CONTROL frames [ringing etc], DTMF
03852       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03853       the others need a timestamp slaved to the voice frames so that they go in sequence
03854    */
03855    if (f) {
03856       if (f->frametype == AST_FRAME_VOICE) {
03857          voice = 1;
03858          delivery = &f->delivery;
03859       } else if (f->frametype == AST_FRAME_IAX) {
03860          genuine = 1;
03861       } else if (f->frametype == AST_FRAME_CNG) {
03862          p->notsilenttx = 0;  
03863       }
03864    }
03865    if (ast_tvzero(p->offset)) {
03866       gettimeofday(&p->offset, NULL);
03867       /* Round to nearest 20ms for nice looking traces */
03868       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03869    }
03870    /* If the timestamp is specified, just send it as is */
03871    if (ts)
03872       return ts;
03873    /* If we have a time that the frame arrived, always use it to make our timestamp */
03874    if (delivery && !ast_tvzero(*delivery)) {
03875       ms = ast_tvdiff_ms(*delivery, p->offset);
03876       if (option_debug > 2 && iaxdebug)
03877          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03878    } else {
03879       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03880       if (ms < 0)
03881          ms = 0;
03882       if (voice) {
03883          /* On a voice frame, use predicted values if appropriate */
03884          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03885             /* Adjust our txcore, keeping voice and non-voice synchronized */
03886             /* AN EXPLANATION:
03887                When we send voice, we usually send "calculated" timestamps worked out
03888                on the basis of the number of samples sent. When we send other frames,
03889                we usually send timestamps worked out from the real clock.
03890                The problem is that they can tend to drift out of step because the 
03891                   source channel's clock and our clock may not be exactly at the same rate.
03892                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03893                for this call.  Moving it adjusts timestamps for non-voice frames.
03894                We make the adjustment in the style of a moving average.  Each time we
03895                adjust p->offset by 10% of the difference between our clock-derived
03896                timestamp and the predicted timestamp.  That's why you see "10000"
03897                below even though IAX2 timestamps are in milliseconds.
03898                The use of a moving average avoids offset moving too radically.
03899                Generally, "adjust" roams back and forth around 0, with offset hardly
03900                changing at all.  But if a consistent different starts to develop it
03901                will be eliminated over the course of 10 frames (200-300msecs) 
03902             */
03903             adjust = (ms - p->nextpred);
03904             if (adjust < 0)
03905                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03906             else if (adjust > 0)
03907                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03908 
03909             if (!p->nextpred) {
03910                p->nextpred = ms; /*f->samples / 8;*/
03911                if (p->nextpred <= p->lastsent)
03912                   p->nextpred = p->lastsent + 3;
03913             }
03914             ms = p->nextpred;
03915          } else {
03916                 /* in this case, just use the actual
03917             * time, since we're either way off
03918             * (shouldn't happen), or we're  ending a
03919             * silent period -- and seed the next
03920             * predicted time.  Also, round ms to the
03921             * next multiple of frame size (so our
03922             * silent periods are multiples of
03923             * frame size too) */
03924 
03925             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03926                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03927                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03928 
03929             if (f->samples >= 8) /* check to make sure we dont core dump */
03930             {
03931                int diff = ms % (f->samples / 8);
03932                if (diff)
03933                    ms += f->samples/8 - diff;
03934             }
03935 
03936             p->nextpred = ms;
03937             p->notsilenttx = 1;
03938          }
03939       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03940          /*
03941          * IAX2 draft 03 says that timestamps MUST be in order.
03942          * It does not say anything about several frames having the same timestamp
03943          * When transporting video, we can have a frame that spans multiple iax packets
03944          * (so called slices), so it would make sense to use the same timestamp for all of
03945          * them
03946          * We do want to make sure that frames don't go backwards though
03947          */
03948          if ( (unsigned int)ms < p->lastsent )
03949             ms = p->lastsent;
03950       } else {
03951          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03952             it's a genuine frame */
03953          if (genuine) {
03954             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03955             if (ms <= p->lastsent)
03956                ms = p->lastsent + 3;
03957          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03958             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03959             ms = p->lastsent + 3;
03960          }
03961       }
03962    }
03963    p->lastsent = ms;
03964    if (voice)
03965       p->nextpred = p->nextpred + f->samples / 8;
03966    return ms;
03967 }
03968 
03969 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03970 {
03971    /* Returns where in "receive time" we are.  That is, how many ms
03972       since we received (or would have received) the frame with timestamp 0 */
03973    int ms;
03974 #ifdef IAXTESTS
03975    int jit;
03976 #endif /* IAXTESTS */
03977    /* Setup rxcore if necessary */
03978    if (ast_tvzero(p->rxcore)) {
03979       p->rxcore = ast_tvnow();
03980       if (option_debug && iaxdebug)
03981          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03982                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03983       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03984 #if 1
03985       if (option_debug && iaxdebug)
03986          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03987                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03988 #endif
03989    }
03990 
03991    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03992 #ifdef IAXTESTS
03993    if (test_jit) {
03994       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03995          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03996          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03997             jit = -jit;
03998          ms += jit;
03999       }
04000    }
04001    if (test_late) {
04002       ms += test_late;
04003       test_late = 0;
04004    }
04005 #endif /* IAXTESTS */
04006    return ms;
04007 }
04008 
04009 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04010 {
04011    struct iax2_trunk_peer *tpeer;
04012    
04013    /* Finds and locks trunk peer */
04014    ast_mutex_lock(&tpeerlock);
04015    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04016       /* We don't lock here because tpeer->addr *never* changes */
04017       if (!inaddrcmp(&tpeer->addr, sin)) {
04018          ast_mutex_lock(&tpeer->lock);
04019          break;
04020       }
04021    }
04022    if (!tpeer) {
04023       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04024          ast_mutex_init(&tpeer->lock);
04025          tpeer->lastsent = 9999;
04026          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04027          tpeer->trunkact = ast_tvnow();
04028          ast_mutex_lock(&tpeer->lock);
04029          tpeer->next = tpeers;
04030          tpeer->sockfd = fd;
04031          tpeers = tpeer;
04032 #ifdef SO_NO_CHECK
04033          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04034 #endif
04035          if (option_debug)
04036             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04037       }
04038    }
04039    ast_mutex_unlock(&tpeerlock);
04040    return tpeer;
04041 }
04042 
04043 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04044 {
04045    struct ast_frame *f;
04046    struct iax2_trunk_peer *tpeer;
04047    void *tmp, *ptr;
04048    struct ast_iax2_meta_trunk_entry *met;
04049    struct ast_iax2_meta_trunk_mini *mtm;
04050 
04051    f = &fr->af;
04052    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04053    if (tpeer) {
04054       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04055          /* Need to reallocate space */
04056          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04057             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04058                ast_mutex_unlock(&tpeer->lock);
04059                return -1;
04060             }
04061             
04062             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04063             tpeer->trunkdata = tmp;
04064             if (option_debug)
04065                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);
04066          } else {
04067             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));
04068             ast_mutex_unlock(&tpeer->lock);
04069             return -1;
04070          }
04071       }
04072 
04073       /* Append to meta frame */
04074       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04075       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04076          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04077          mtm->len = htons(f->datalen);
04078          mtm->mini.callno = htons(pvt->callno);
04079          mtm->mini.ts = htons(0xffff & fr->ts);
04080          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04081          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04082       } else {
04083          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04084          /* Store call number and length in meta header */
04085          met->callno = htons(pvt->callno);
04086          met->len = htons(f->datalen);
04087          /* Advance pointers/decrease length past trunk entry header */
04088          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04089          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04090       }
04091       /* Copy actual trunk data */
04092       memcpy(ptr, f->data, f->datalen);
04093       tpeer->trunkdatalen += f->datalen;
04094 
04095       tpeer->calls++;
04096       ast_mutex_unlock(&tpeer->lock);
04097    }
04098    return 0;
04099 }
04100 
04101 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04102 {
04103    aes_encrypt_key128(digest, ecx);
04104    aes_decrypt_key128(digest, dcx);
04105 }
04106 
04107 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04108 {
04109 #if 0
04110    /* Debug with "fake encryption" */
04111    int x;
04112    if (len % 16)
04113       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04114    for (x=0;x<len;x++)
04115       dst[x] = src[x] ^ 0xff;
04116 #else 
04117    unsigned char lastblock[16] = { 0 };
04118    int x;
04119    while(len > 0) {
04120       aes_decrypt(src, dst, dcx);
04121       for (x=0;x<16;x++)
04122          dst[x] ^= lastblock[x];
04123       memcpy(lastblock, src, sizeof(lastblock));
04124       dst += 16;
04125       src += 16;
04126       len -= 16;
04127    }
04128 #endif
04129 }
04130 
04131 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04132 {
04133 #if 0
04134    /* Debug with "fake encryption" */
04135    int x;
04136    if (len % 16)
04137       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04138    for (x=0;x<len;x++)
04139       dst[x] = src[x] ^ 0xff;
04140 #else
04141    unsigned char curblock[16] = { 0 };
04142    int x;
04143    while(len > 0) {
04144       for (x=0;x<16;x++)
04145          curblock[x] ^= src[x];
04146       aes_encrypt(curblock, dst, ecx);
04147       memcpy(curblock, dst, sizeof(curblock)); 
04148       dst += 16;
04149       src += 16;
04150       len -= 16;
04151    }
04152 #endif
04153 }
04154 
04155 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04156 {
04157    int padding;
04158    unsigned char *workspace;
04159 
04160    workspace = alloca(*datalen);
04161    memset(f, 0, sizeof(*f));
04162    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04163       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04164       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04165          return -1;
04166       /* Decrypt */
04167       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04168 
04169       padding = 16 + (workspace[15] & 0xf);
04170       if (option_debug && iaxdebug)
04171          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04172       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04173          return -1;
04174 
04175       *datalen -= padding;
04176       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04177       f->frametype = fh->type;
04178       if (f->frametype == AST_FRAME_VIDEO) {
04179          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04180       } else {
04181          f->subclass = uncompress_subclass(fh->csub);
04182       }
04183    } else {
04184       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04185       if (option_debug && iaxdebug)
04186          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04187       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04188          return -1;
04189       /* Decrypt */
04190       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04191       padding = 16 + (workspace[15] & 0x0f);
04192       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04193          return -1;
04194       *datalen -= padding;
04195       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04196    }
04197    return 0;
04198 }
04199 
04200 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04201 {
04202    int padding;
04203    unsigned char *workspace;
04204    workspace = alloca(*datalen + 32);
04205    if (!workspace)
04206       return -1;
04207    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04208       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04209       if (option_debug && iaxdebug)
04210          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04211       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04212       padding = 16 + (padding & 0xf);
04213       memcpy(workspace, poo, padding);
04214       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04215       workspace[15] &= 0xf0;
04216       workspace[15] |= (padding & 0xf);
04217       if (option_debug && iaxdebug)
04218          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]);
04219       *datalen += padding;
04220       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04221       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04222          memcpy(poo, workspace + *datalen - 32, 32);
04223    } else {
04224       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04225       if (option_debug && iaxdebug)
04226          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04227       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04228       padding = 16 + (padding & 0xf);
04229       memcpy(workspace, poo, padding);
04230       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04231       workspace[15] &= 0xf0;
04232       workspace[15] |= (padding & 0x0f);
04233       *datalen += padding;
04234       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04235       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04236          memcpy(poo, workspace + *datalen - 32, 32);
04237    }
04238    return 0;
04239 }
04240 
04241 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04242 {
04243    int res=-1;
04244    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04245       /* Search for possible keys, given secrets */
04246       struct MD5Context md5;
04247       unsigned char digest[16];
04248       char *tmppw, *stringp;
04249       
04250       tmppw = ast_strdupa(iaxs[callno]->secret);
04251       stringp = tmppw;
04252       while ((tmppw = strsep(&stringp, ";"))) {
04253          MD5Init(&md5);
04254          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04255          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04256          MD5Final(digest, &md5);
04257          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04258          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04259          if (!res) {
04260             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04261             break;
04262          }
04263       }
04264    } else 
04265       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04266    return res;
04267 }
04268 
04269 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04270 {
04271    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04272       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04273       or delayed, with retransmission */
04274    struct ast_iax2_full_hdr *fh;
04275    struct ast_iax2_mini_hdr *mh;
04276    struct ast_iax2_video_hdr *vh;
04277    struct {
04278       struct iax_frame fr2;
04279       unsigned char buffer[4096];
04280    } frb;
04281    struct iax_frame *fr;
04282    int res;
04283    int sendmini=0;
04284    unsigned int lastsent;
04285    unsigned int fts;
04286 
04287    frb.fr2.afdatalen = sizeof(frb.buffer);
04288 
04289    if (!pvt) {
04290       ast_log(LOG_WARNING, "No private structure for packet?\n");
04291       return -1;
04292    }
04293    
04294    lastsent = pvt->lastsent;
04295 
04296    /* Calculate actual timestamp */
04297    fts = calc_timestamp(pvt, ts, f);
04298 
04299    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04300     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04301     * increment the "predicted timestamps" for voice, if we're predecting */
04302    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04303        return 0;
04304 
04305 
04306    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04307          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04308          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04309       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04310        (f->frametype == AST_FRAME_VOICE) 
04311       /* is a voice frame */ &&
04312       (f->subclass == pvt->svoiceformat) 
04313       /* is the same type */ ) {
04314          /* Force immediate rather than delayed transmission */
04315          now = 1;
04316          /* Mark that mini-style frame is appropriate */
04317          sendmini = 1;
04318    }
04319    if ( f->frametype == AST_FRAME_VIDEO ) {
04320       /*
04321        * If the lower 15 bits of the timestamp roll over, or if
04322        * the video format changed then send a full frame.
04323        * Otherwise send a mini video frame
04324        */
04325       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04326           ((f->subclass & ~0x1) == pvt->svideoformat)
04327          ) {
04328          now = 1;
04329          sendmini = 1;
04330       } else {
04331          now = 0;
04332          sendmini = 0;
04333       }
04334       pvt->lastvsent = fts;
04335    }
04336    /* Allocate an iax_frame */
04337    if (now) {
04338       fr = &frb.fr2;
04339    } else
04340       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));
04341    if (!fr) {
04342       ast_log(LOG_WARNING, "Out of memory\n");
04343       return -1;
04344    }
04345    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04346    iax_frame_wrap(fr, f);
04347 
04348    fr->ts = fts;
04349    fr->callno = pvt->callno;
04350    fr->transfer = transfer;
04351    fr->final = final;
04352    if (!sendmini) {
04353       /* We need a full frame */
04354       if (seqno > -1)
04355          fr->oseqno = seqno;
04356       else
04357          fr->oseqno = pvt->oseqno++;
04358       fr->iseqno = pvt->iseqno;
04359       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04360       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04361       fh->ts = htonl(fr->ts);
04362       fh->oseqno = fr->oseqno;
04363       if (transfer) {
04364          fh->iseqno = 0;
04365       } else
04366          fh->iseqno = fr->iseqno;
04367       /* Keep track of the last thing we've acknowledged */
04368       if (!transfer)
04369          pvt->aseqno = fr->iseqno;
04370       fh->type = fr->af.frametype & 0xFF;
04371       if (fr->af.frametype == AST_FRAME_VIDEO)
04372          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04373       else
04374          fh->csub = compress_subclass(fr->af.subclass);
04375       if (transfer) {
04376          fr->dcallno = pvt->transfercallno;
04377       } else
04378          fr->dcallno = pvt->peercallno;
04379       fh->dcallno = htons(fr->dcallno);
04380       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04381       fr->data = fh;
04382       fr->retries = 0;
04383       /* Retry after 2x the ping time has passed */
04384       fr->retrytime = pvt->pingtime * 2;
04385       if (fr->retrytime < MIN_RETRY_TIME)
04386          fr->retrytime = MIN_RETRY_TIME;
04387       if (fr->retrytime > MAX_RETRY_TIME)
04388          fr->retrytime = MAX_RETRY_TIME;
04389       /* Acks' don't get retried */
04390       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04391          fr->retries = -1;
04392       else if (f->frametype == AST_FRAME_VOICE)
04393          pvt->svoiceformat = f->subclass;
04394       else if (f->frametype == AST_FRAME_VIDEO)
04395          pvt->svideoformat = f->subclass & ~0x1;
04396       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04397          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04398             if (iaxdebug) {
04399                if (fr->transfer)
04400                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04401                else
04402                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04403             }
04404             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04405          } else
04406             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04407       }
04408    
04409       if (now) {
04410          res = send_packet(fr);
04411       } else
04412          res = iax2_transmit(fr);
04413    } else {
04414       if (ast_test_flag(pvt, IAX_TRUNK)) {
04415          iax2_trunk_queue(pvt, fr);
04416          res = 0;
04417       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04418          /* Video frame have no sequence number */
04419          fr->oseqno = -1;
04420          fr->iseqno = -1;
04421          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04422          vh->zeros = 0;
04423          vh->callno = htons(0x8000 | fr->callno);
04424          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04425          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04426          fr->data = vh;
04427          fr->retries = -1;
04428          res = send_packet(fr);        
04429       } else {
04430          /* Mini-frames have no sequence number */
04431          fr->oseqno = -1;
04432          fr->iseqno = -1;
04433          /* Mini frame will do */
04434          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04435          mh->callno = htons(fr->callno);
04436          mh->ts = htons(fr->ts & 0xFFFF);
04437          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04438          fr->data = mh;
04439          fr->retries = -1;
04440          if (pvt->transferring == TRANSFER_MEDIAPASS)
04441             fr->transfer = 1;
04442          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04443             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04444                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04445             } else
04446                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04447          }
04448          res = send_packet(fr);
04449       }
04450    }
04451    return res;
04452 }
04453 
04454 static int iax2_show_users(int fd, int argc, char *argv[])
04455 {
04456    regex_t regexbuf;
04457    int havepattern = 0;
04458 
04459 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04460 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04461 
04462    struct iax2_user *user = NULL;
04463    char auth[90];
04464    char *pstr = "";
04465    struct ao2_iterator i;
04466 
04467    switch (argc) {
04468    case 5:
04469       if (!strcasecmp(argv[3], "like")) {
04470          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04471             return RESULT_SHOWUSAGE;
04472          havepattern = 1;
04473       } else
04474          return RESULT_SHOWUSAGE;
04475    case 3:
04476       break;
04477    default:
04478       return RESULT_SHOWUSAGE;
04479    }
04480 
04481    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04482    i = ao2_iterator_init(users, 0);
04483    for (user = ao2_iterator_next(&i); user; 
04484       user_unref(user), user = ao2_iterator_next(&i)) {
04485       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04486          continue;
04487       
04488       if (!ast_strlen_zero(user->secret)) {
04489          ast_copy_string(auth,user->secret,sizeof(auth));
04490       } else if (!ast_strlen_zero(user->inkeys)) {
04491          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04492       } else
04493          ast_copy_string(auth, "-no secret-", sizeof(auth));
04494       
04495       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04496          pstr = "REQ Only";
04497       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04498          pstr = "Disabled";
04499       else
04500          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04501       
04502       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04503          user->contexts ? user->contexts->context : context,
04504          user->ha ? "Yes" : "No", pstr);
04505    }
04506 
04507    if (havepattern)
04508       regfree(&regexbuf);
04509 
04510    return RESULT_SUCCESS;
04511 #undef FORMAT
04512 #undef FORMAT2
04513 }
04514 
04515 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04516 {
04517    regex_t regexbuf;
04518    int havepattern = 0;
04519    int total_peers = 0;
04520    int online_peers = 0;
04521    int offline_peers = 0;
04522    int unmonitored_peers = 0;
04523    struct ao2_iterator i;
04524 
04525 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04526 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04527 
04528    struct iax2_peer *peer = NULL;
04529    char name[256];
04530    int registeredonly=0;
04531    char *term = manager ? "\r\n" : "\n";
04532 
04533    switch (argc) {
04534    case 6:
04535       if (!strcasecmp(argv[3], "registered"))
04536          registeredonly = 1;
04537       else
04538          return RESULT_SHOWUSAGE;
04539       if (!strcasecmp(argv[4], "like")) {
04540          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04541             return RESULT_SHOWUSAGE;
04542          havepattern = 1;
04543       } else
04544          return RESULT_SHOWUSAGE;
04545       break;
04546    case 5:
04547       if (!strcasecmp(argv[3], "like")) {
04548          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04549             return RESULT_SHOWUSAGE;
04550          havepattern = 1;
04551       } else
04552          return RESULT_SHOWUSAGE;
04553       break;
04554    case 4:
04555       if (!strcasecmp(argv[3], "registered"))
04556          registeredonly = 1;
04557       else
04558          return RESULT_SHOWUSAGE;
04559       break;
04560    case 3:
04561       break;
04562    default:
04563       return RESULT_SHOWUSAGE;
04564    }
04565 
04566 
04567    if (s)
04568       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04569    else
04570       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04571 
04572    i = ao2_iterator_init(peers, 0);
04573    for (peer = ao2_iterator_next(&i); peer; 
04574       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04575       char nm[20];
04576       char status[20];
04577       char srch[2000];
04578       int retstatus;
04579 
04580       if (registeredonly && !peer->addr.sin_addr.s_addr)
04581          continue;
04582       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04583          continue;
04584 
04585       if (!ast_strlen_zero(peer->username))
04586          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04587       else
04588          ast_copy_string(name, peer->name, sizeof(name));
04589       
04590       retstatus = peer_status(peer, status, sizeof(status));
04591       if (retstatus > 0)
04592          online_peers++;
04593       else if (!retstatus)
04594          offline_peers++;
04595       else
04596          unmonitored_peers++;
04597       
04598       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04599       
04600       snprintf(srch, sizeof(srch), FORMAT, name, 
04601           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04602           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04603           nm,
04604           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04605           peer->encmethods ? "(E)" : "   ", status, term);
04606       
04607       if (s)
04608          astman_append(s, FORMAT, name, 
04609                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04610                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04611                   nm,
04612                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04613                   peer->encmethods ? "(E)" : "   ", status, term);
04614       else
04615          ast_cli(fd, FORMAT, name, 
04616             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04617             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04618             nm,
04619             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04620             peer->encmethods ? "(E)" : "   ", status, term);
04621       total_peers++;
04622    }
04623 
04624    if (s)
04625       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04626    else
04627       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04628 
04629    if (havepattern)
04630       regfree(&regexbuf);
04631 
04632    return RESULT_SUCCESS;
04633 #undef FORMAT
04634 #undef FORMAT2
04635 }
04636 
04637 static int iax2_show_threads(int fd, int argc, char *argv[])
04638 {
04639    struct iax2_thread *thread = NULL;
04640    time_t t;
04641    int threadcount = 0, dynamiccount = 0;
04642    char type;
04643 
04644    if (argc != 3)
04645       return RESULT_SHOWUSAGE;
04646       
04647    ast_cli(fd, "IAX2 Thread Information\n");
04648    time(&t);
04649    ast_cli(fd, "Idle Threads:\n");
04650    AST_LIST_LOCK(&idle_list);
04651    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04652 #ifdef DEBUG_SCHED_MULTITHREAD
04653       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04654          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04655 #else
04656       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04657          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04658 #endif
04659       threadcount++;
04660    }
04661    AST_LIST_UNLOCK(&idle_list);
04662    ast_cli(fd, "Active Threads:\n");
04663    AST_LIST_LOCK(&active_list);
04664    AST_LIST_TRAVERSE(&active_list, thread, list) {
04665       if (thread->type == IAX_TYPE_DYNAMIC)
04666          type = 'D';
04667       else
04668          type = 'P';
04669 #ifdef DEBUG_SCHED_MULTITHREAD
04670       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04671          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04672 #else
04673       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04674          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04675 #endif
04676       threadcount++;
04677    }
04678    AST_LIST_UNLOCK(&active_list);
04679    ast_cli(fd, "Dynamic Threads:\n");
04680         AST_LIST_LOCK(&dynamic_list);
04681         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04682 #ifdef DEBUG_SCHED_MULTITHREAD
04683                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04684                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04685 #else
04686                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04687                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04688 #endif
04689       dynamiccount++;
04690         }
04691         AST_LIST_UNLOCK(&dynamic_list);
04692    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04693    return RESULT_SUCCESS;
04694 }
04695 
04696 static int iax2_show_peers(int fd, int argc, char *argv[])
04697 {
04698    return __iax2_show_peers(0, fd, NULL, argc, argv);
04699 }
04700 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04701 {
04702    ast_cli_netstats(s, -1, 0);
04703    astman_append(s, "\r\n");
04704    return RESULT_SUCCESS;
04705 }
04706 
04707 static int iax2_show_firmware(int fd, int argc, char *argv[])
04708 {
04709 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04710 #if !defined(__FreeBSD__)
04711 #define FORMAT "%-15.15s  %-15d %-15d\n"
04712 #else /* __FreeBSD__ */
04713 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04714 #endif /* __FreeBSD__ */
04715    struct iax_firmware *cur;
04716    if ((argc != 3) && (argc != 4))
04717       return RESULT_SHOWUSAGE;
04718    ast_mutex_lock(&waresl.lock);
04719    
04720    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04721    for (cur = waresl.wares;cur;cur = cur->next) {
04722       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04723          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04724             (int)ntohl(cur->fwh->datalen));
04725    }
04726    ast_mutex_unlock(&waresl.lock);
04727    return RESULT_SUCCESS;
04728 #undef FORMAT
04729 #undef FORMAT2
04730 }
04731 
04732 /* JDG: callback to display iax peers in manager */
04733 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04734 {
04735    char *a[] = { "iax2", "show", "users" };
04736    int ret;
04737    const char *id = astman_get_header(m,"ActionID");
04738 
04739    if (!ast_strlen_zero(id))
04740       astman_append(s, "ActionID: %s\r\n",id);
04741    ret = __iax2_show_peers(1, -1, s, 3, a );
04742    astman_append(s, "\r\n\r\n" );
04743    return ret;
04744 } /* /JDG */
04745 
04746 static char *regstate2str(int regstate)
04747 {
04748    switch(regstate) {
04749    case REG_STATE_UNREGISTERED:
04750       return "Unregistered";
04751    case REG_STATE_REGSENT:
04752       return "Request Sent";
04753    case REG_STATE_AUTHSENT:
04754       return "Auth. Sent";
04755    case REG_STATE_REGISTERED:
04756       return "Registered";
04757    case REG_STATE_REJECTED:
04758       return "Rejected";
04759    case REG_STATE_TIMEOUT:
04760       return "Timeout";
04761    case REG_STATE_NOAUTH:
04762       return "No Authentication";
04763    default:
04764       return "Unknown";
04765    }
04766 }
04767 
04768 static int iax2_show_registry(int fd, int argc, char *argv[])
04769 {
04770 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04771 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04772    struct iax2_registry *reg = NULL;
04773 
04774    char host[80];
04775    char perceived[80];
04776    if (argc != 3)
04777       return RESULT_SHOWUSAGE;
04778    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04779    AST_LIST_LOCK(&registrations);
04780    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04781       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04782       if (reg->us.sin_addr.s_addr) 
04783          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04784       else
04785          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04786       ast_cli(fd, FORMAT, host, 
04787                (reg->dnsmgr) ? "Y" : "N", 
04788                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04789    }
04790    AST_LIST_UNLOCK(&registrations);
04791    return RESULT_SUCCESS;
04792 #undef FORMAT
04793 #undef FORMAT2
04794 }
04795 
04796 static int iax2_show_channels(int fd, int argc, char *argv[])
04797 {
04798 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04799 #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"
04800 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04801    int x;
04802    int numchans = 0;
04803 
04804    if (argc != 3)
04805       return RESULT_SHOWUSAGE;
04806    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04807    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04808       ast_mutex_lock(&iaxsl[x]);
04809       if (iaxs[x]) {
04810          int lag, jitter, localdelay;
04811          jb_info jbinfo;
04812          
04813          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04814             jb_getinfo(iaxs[x]->jb, &jbinfo);
04815             jitter = jbinfo.jitter;
04816             localdelay = jbinfo.current - jbinfo.min;
04817          } else {
04818             jitter = -1;
04819             localdelay = 0;
04820          }
04821          lag = iaxs[x]->remote_rr.delay;
04822          ast_cli(fd, FORMAT,
04823             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04824             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04825             S_OR(iaxs[x]->username, "(None)"),
04826             iaxs[x]->callno, iaxs[x]->peercallno,
04827             iaxs[x]->oseqno, iaxs[x]->iseqno,
04828             lag,
04829             jitter,
04830             localdelay,
04831             ast_getformatname(iaxs[x]->voiceformat) );
04832          numchans++;
04833       }
04834       ast_mutex_unlock(&iaxsl[x]);
04835    }
04836    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04837    return RESULT_SUCCESS;
04838 #undef FORMAT
04839 #undef FORMAT2
04840 #undef FORMATB
04841 }
04842 
04843 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04844 {
04845    int x;
04846    int numchans = 0;
04847    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04848       ast_mutex_lock(&iaxsl[x]);
04849       if (iaxs[x]) {
04850          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04851          char *fmt;
04852          jb_info jbinfo;
04853          
04854          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04855             jb_getinfo(iaxs[x]->jb, &jbinfo);
04856             localjitter = jbinfo.jitter;
04857             localdelay = jbinfo.current - jbinfo.min;
04858             locallost = jbinfo.frames_lost;
04859             locallosspct = jbinfo.losspct/1000;
04860             localdropped = jbinfo.frames_dropped;
04861             localooo = jbinfo.frames_ooo;
04862          } else {
04863             localjitter = -1;
04864             localdelay = 0;
04865             locallost = -1;
04866             locallosspct = -1;
04867             localdropped = 0;
04868             localooo = -1;
04869          }
04870          if (limit_fmt)
04871             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04872          else
04873             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04874          if (s)
04875             
04876             astman_append(s, fmt,
04877                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04878                      iaxs[x]->pingtime,
04879                      localjitter, 
04880                      localdelay,
04881                      locallost,
04882                      locallosspct,
04883                      localdropped,
04884                      localooo,
04885                      iaxs[x]->frames_received/1000,
04886                      iaxs[x]->remote_rr.jitter,
04887                      iaxs[x]->remote_rr.delay,
04888                      iaxs[x]->remote_rr.losscnt,
04889                      iaxs[x]->remote_rr.losspct,
04890                      iaxs[x]->remote_rr.dropped,
04891                      iaxs[x]->remote_rr.ooo,
04892                      iaxs[x]->remote_rr.packets/1000);
04893          else
04894             ast_cli(fd, fmt,
04895                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04896                iaxs[x]->pingtime,
04897                localjitter, 
04898                localdelay,
04899                locallost,
04900                locallosspct,
04901                localdropped,
04902                localooo,
04903                iaxs[x]->frames_received/1000,
04904                iaxs[x]->remote_rr.jitter,
04905                iaxs[x]->remote_rr.delay,
04906                iaxs[x]->remote_rr.losscnt,
04907                iaxs[x]->remote_rr.losspct,
04908                iaxs[x]->remote_rr.dropped,
04909                iaxs[x]->remote_rr.ooo,
04910                iaxs[x]->remote_rr.packets/1000
04911                );
04912          numchans++;
04913       }
04914       ast_mutex_unlock(&iaxsl[x]);
04915    }
04916    return numchans;
04917 }
04918 
04919 static int iax2_show_netstats(int fd, int argc, char *argv[])
04920 {
04921    int numchans = 0;
04922    if (argc != 3)
04923       return RESULT_SHOWUSAGE;
04924    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04925    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04926    numchans = ast_cli_netstats(NULL, fd, 1);
04927    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04928    return RESULT_SUCCESS;
04929 }
04930 
04931 static int iax2_do_debug(int fd, int argc, char *argv[])
04932 {
04933    if (argc < 2 || argc > 3)
04934       return RESULT_SHOWUSAGE;
04935    iaxdebug = 1;
04936    ast_cli(fd, "IAX2 Debugging Enabled\n");
04937    return RESULT_SUCCESS;
04938 }
04939 
04940 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04941 {
04942    if (argc < 3 || argc > 4)
04943       return RESULT_SHOWUSAGE;
04944    iaxtrunkdebug = 1;
04945    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04946    return RESULT_SUCCESS;
04947 }
04948 
04949 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04950 {
04951    if (argc < 3 || argc > 4)
04952       return RESULT_SHOWUSAGE;
04953    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04954    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04955    return RESULT_SUCCESS;
04956 }
04957 
04958 static int iax2_no_debug(int fd, int argc, char *argv[])
04959 {
04960    if (argc < 3 || argc > 4)
04961       return RESULT_SHOWUSAGE;
04962    iaxdebug = 0;
04963    ast_cli(fd, "IAX2 Debugging Disabled\n");
04964    return RESULT_SUCCESS;
04965 }
04966 
04967 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04968 {
04969    if (argc < 4 || argc > 5)
04970       return RESULT_SHOWUSAGE;
04971    iaxtrunkdebug = 0;
04972    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04973    return RESULT_SUCCESS;
04974 }
04975 
04976 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04977 {
04978    if (argc < 4 || argc > 5)
04979       return RESULT_SHOWUSAGE;
04980    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04981    jb_debug_output("\n");
04982    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04983    return RESULT_SUCCESS;
04984 }
04985 
04986 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04987 {
04988    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04989    int res = -1;
04990    ast_mutex_lock(&iaxsl[callno]);
04991    if (iaxs[callno]) {
04992    /* If there's an outstanding error, return failure now */
04993       if (!iaxs[callno]->error) {
04994          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04995             res = 0;
04996             /* Don't waste bandwidth sending null frames */
04997          else if (f->frametype == AST_FRAME_NULL)
04998             res = 0;
04999          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05000             res = 0;
05001          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05002             res = 0;
05003          else
05004          /* Simple, just queue for transmission */
05005             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05006       } else {
05007          if (option_debug)
05008             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05009       }
05010    }
05011    /* If it's already gone, just return */
05012    ast_mutex_unlock(&iaxsl[callno]);
05013    return res;
05014 }
05015 
05016 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05017       int now, int transfer, int final)
05018 {
05019    struct ast_frame f = { 0, };
05020 
05021    f.frametype = type;
05022    f.subclass = command;
05023    f.datalen = datalen;
05024    f.src = __FUNCTION__;
05025    f.data = (void *) data;
05026 
05027    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05028 }
05029 
05030 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05031 {
05032    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05033 }
05034 
05035 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05036 {
05037    int res;
05038    ast_mutex_lock(&iaxsl[callno]);
05039    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05040    ast_mutex_unlock(&iaxsl[callno]);
05041    return res;
05042 }
05043 
05044 /*!
05045  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05046  *       the pvt struct for the given call number may disappear during its 
05047  *       execution.
05048  */
05049 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)
05050 {
05051    int call_num = i->callno;
05052    /* It is assumed that the callno has already been locked */
05053    iax2_predestroy(i->callno);
05054    if (!iaxs[call_num])
05055       return -1;
05056    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05057 }
05058 
05059 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)
05060 {
05061    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05062 }
05063 
05064 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05065 {
05066    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05067 }
05068 
05069 static int apply_context(struct iax2_context *con, const char *context)
05070 {
05071    while(con) {
05072       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05073          return -1;
05074       con = con->next;
05075    }
05076    return 0;
05077 }
05078 
05079 
05080 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05081 {
05082    /* Start pessimistic */
05083    int res = -1;
05084    int version = 2;
05085    struct iax2_user *user = NULL, *best = NULL;
05086    int bestscore = 0;
05087    int gotcapability = 0;
05088    struct ast_variable *v = NULL, *tmpvar = NULL;
05089    struct ao2_iterator i;
05090 
05091    if (!iaxs[callno])
05092       return res;
05093    if (ies->called_number)
05094       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05095    if (ies->calling_number) {
05096       ast_shrink_phone_number(ies->calling_number);
05097       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05098    }
05099    if (ies->calling_name)
05100       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05101    if (ies->calling_ani)
05102       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05103    if (ies->dnid)
05104       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05105    if (ies->rdnis)
05106       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05107    if (ies->called_context)
05108       ast_string_field_set(iaxs[callno], context, ies->called_context);
05109    if (ies->language)
05110       ast_string_field_set(iaxs[callno], language, ies->language);
05111    if (ies->username)
05112       ast_string_field_set(iaxs[callno], username, ies->username);
05113    if (ies->calling_ton > -1)
05114       iaxs[callno]->calling_ton = ies->calling_ton;
05115    if (ies->calling_tns > -1)
05116       iaxs[callno]->calling_tns = ies->calling_tns;
05117    if (ies->calling_pres > -1)
05118       iaxs[callno]->calling_pres = ies->calling_pres;
05119    if (ies->format)
05120       iaxs[callno]->peerformat = ies->format;
05121    if (ies->adsicpe)
05122       iaxs[callno]->peeradsicpe = ies->adsicpe;
05123    if (ies->capability) {
05124       gotcapability = 1;
05125       iaxs[callno]->peercapability = ies->capability;
05126    } 
05127    if (ies->version)
05128       version = ies->version;
05129 
05130    /* Use provided preferences until told otherwise for actual preferences */
05131    if(ies->codec_prefs) {
05132       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05133       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05134    }
05135 
05136    if (!gotcapability) 
05137       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05138    if (version > IAX_PROTO_VERSION) {
05139       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05140          ast_inet_ntoa(sin->sin_addr), version);
05141       return res;
05142    }
05143    /* Search the userlist for a compatible entry, and fill in the rest */
05144    i = ao2_iterator_init(users, 0);
05145    while ((user = ao2_iterator_next(&i))) {
05146       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05147          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05148          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05149          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05150               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05151          if (!ast_strlen_zero(iaxs[callno]->username)) {
05152             /* Exact match, stop right now. */
05153             if (best)
05154                user_unref(best);
05155             best = user;
05156             break;
05157          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05158             /* No required authentication */
05159             if (user->ha) {
05160                /* There was host authentication and we passed, bonus! */
05161                if (bestscore < 4) {
05162                   bestscore = 4;
05163                   if (best)
05164                      user_unref(best);
05165                   best = user;
05166                   continue;
05167                }
05168             } else {
05169                /* No host access, but no secret, either, not bad */
05170                if (bestscore < 3) {
05171                   bestscore = 3;
05172                   if (best)
05173                      user_unref(best);
05174                   best = user;
05175                   continue;
05176                }
05177             }
05178          } else {
05179             if (user->ha) {
05180                /* Authentication, but host access too, eh, it's something.. */
05181                if (bestscore < 2) {
05182                   bestscore = 2;
05183                   if (best)
05184                      user_unref(best);
05185                   best = user;
05186                   continue;
05187                }
05188             } else {
05189                /* Authentication and no host access...  This is our baseline */
05190                if (bestscore < 1) {
05191                   bestscore = 1;
05192                   if (best)
05193                      user_unref(best);
05194                   best = user;
05195                   continue;
05196                }
05197             }
05198          }
05199       }
05200       user_unref(user);
05201    }
05202    user = best;
05203    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05204       user = realtime_user(iaxs[callno]->username, sin);
05205       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05206           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05207          user = user_unref(user);
05208       }
05209    }
05210    if (user) {
05211       /* We found our match (use the first) */
05212       /* copy vars */
05213       for (v = user->vars ; v ; v = v->next) {
05214          if((tmpvar = ast_variable_new(v->name, v->value))) {
05215             tmpvar->next = iaxs[callno]->vars; 
05216             iaxs[callno]->vars = tmpvar;
05217          }
05218       }
05219       /* If a max AUTHREQ restriction is in place, activate it */
05220       if (user->maxauthreq > 0)
05221          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05222       iaxs[callno]->prefs = user->prefs;
05223       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05224       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05225       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05226       iaxs[callno]->encmethods = user->encmethods;
05227       /* Store the requested username if not specified */
05228       if (ast_strlen_zero(iaxs[callno]->username))
05229          ast_string_field_set(iaxs[callno], username, user->name);
05230       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05231       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05232       iaxs[callno]->capability = user->capability;
05233       /* And use the default context */
05234       if (ast_strlen_zero(iaxs[callno]->context)) {
05235          if (user->contexts)
05236             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05237          else
05238             ast_string_field_set(iaxs[callno], context, context);
05239       }
05240       /* And any input keys */
05241       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05242       /* And the permitted authentication methods */
05243       iaxs[callno]->authmethods = user->authmethods;
05244       iaxs[callno]->adsi = user->adsi;
05245       /* If they have callerid, override the given caller id.  Always store the ANI */
05246       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05247          if (ast_test_flag(user, IAX_HASCALLERID)) {
05248             iaxs[callno]->calling_tns = 0;
05249             iaxs[callno]->calling_ton = 0;
05250             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05251             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05252             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05253          }
05254          if (ast_strlen_zero(iaxs[callno]->ani))
05255             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05256       } else {
05257          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05258       }
05259       if (!ast_strlen_zero(user->accountcode))
05260          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05261       if (!ast_strlen_zero(user->mohinterpret))
05262          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05263       if (!ast_strlen_zero(user->mohsuggest))
05264          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05265       if (user->amaflags)
05266          iaxs[callno]->amaflags = user->amaflags;
05267       if (!ast_strlen_zero(user->language))
05268          ast_string_field_set(iaxs[callno], language, user->language);
05269       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05270       /* Keep this check last */
05271       if (!ast_strlen_zero(user->dbsecret)) {
05272          char *family, *key=NULL;
05273          char buf[80];
05274          family = ast_strdupa(user->dbsecret);
05275          key = strchr(family, '/');
05276          if (key) {
05277             *key = '\0';
05278             key++;
05279          }
05280          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05281             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05282          else
05283             ast_string_field_set(iaxs[callno], secret, buf);
05284       } else
05285          ast_string_field_set(iaxs[callno], secret, user->secret);
05286       res = 0;
05287       user = user_unref(user);
05288    }
05289    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05290    return res;
05291 }
05292 
05293 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05294 {
05295    struct ast_iax2_full_hdr fh;
05296    fh.scallno = htons(src | IAX_FLAG_FULL);
05297    fh.dcallno = htons(dst);
05298    fh.ts = 0;
05299    fh.oseqno = 0;
05300    fh.iseqno = 0;
05301    fh.type = AST_FRAME_IAX;
05302    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05303    if (iaxdebug)
05304        iax_showframe(NULL, &fh, 0, sin, 0);
05305    if (option_debug)
05306       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05307          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05308    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05309 }
05310 
05311 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05312 {
05313    /* Select exactly one common encryption if there are any */
05314    p->encmethods &= enc;
05315    if (p->encmethods) {
05316       if (p->encmethods & IAX_ENCRYPT_AES128)
05317          p->encmethods = IAX_ENCRYPT_AES128;
05318       else
05319          p->encmethods = 0;
05320    }
05321 }
05322 
05323 /*!
05324  * \pre iaxsl[call_num] is locked
05325  *
05326  * \note Since this function calls send_command_final(), the pvt struct for the given
05327  *       call number may disappear while executing this function.
05328  */
05329 static int authenticate_request(int call_num)
05330 {
05331    struct iax_ie_data ied;
05332    int res = -1, authreq_restrict = 0;
05333    char challenge[10];
05334    struct chan_iax2_pvt *p = iaxs[call_num];
05335 
05336    memset(&ied, 0, sizeof(ied));
05337 
05338    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05339    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05340       struct iax2_user *user, tmp_user = {
05341          .name = p->username, 
05342       };
05343 
05344       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05345       if (user) {
05346          if (user->curauthreq == user->maxauthreq)
05347             authreq_restrict = 1;
05348          else
05349             user->curauthreq++;
05350          user = user_unref(user);
05351       }
05352    }
05353 
05354    /* If the AUTHREQ limit test failed, send back an error */
05355    if (authreq_restrict) {
05356       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05357       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05358       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05359       return 0;
05360    }
05361 
05362    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05363    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05364       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05365       ast_string_field_set(p, challenge, challenge);
05366       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05367       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05368    }
05369    if (p->encmethods)
05370       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05371 
05372    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05373 
05374    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05375 
05376    if (p->encmethods)
05377       ast_set_flag(p, IAX_ENCRYPTED);
05378 
05379    return res;
05380 }
05381 
05382 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05383 {
05384    char requeststr[256];
05385    char md5secret[256] = "";
05386    char secret[256] = "";
05387    char rsasecret[256] = "";
05388    int res = -1; 
05389    int x;
05390    struct iax2_user *user, tmp_user = {
05391       .name = p->username, 
05392    };
05393 
05394    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05395    if (user) {
05396       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05397          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05398          ast_clear_flag(p, IAX_MAXAUTHREQ);
05399       }
05400       ast_string_field_set(p, host, user->name);
05401       user = user_unref(user);
05402    }
05403 
05404    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05405       return res;
05406    if (ies->password)
05407       ast_copy_string(secret, ies->password, sizeof(secret));
05408    if (ies->md5_result)
05409       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05410    if (ies->rsa_result)
05411       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05412    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05413       struct ast_key *key;
05414       char *keyn;
05415       char tmpkey[256];
05416       char *stringp=NULL;
05417       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05418       stringp=tmpkey;
05419       keyn = strsep(&stringp, ":");
05420       while(keyn) {
05421          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05422          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05423             res = 0;
05424             break;
05425          } else if (!key)
05426             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05427          keyn = strsep(&stringp, ":");
05428       }
05429    } else if (p->authmethods & IAX_AUTH_MD5) {
05430       struct MD5Context md5;
05431       unsigned char digest[16];
05432       char *tmppw, *stringp;
05433       
05434       tmppw = ast_strdupa(p->secret);
05435       stringp = tmppw;
05436       while((tmppw = strsep(&stringp, ";"))) {
05437          MD5Init(&md5);
05438          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05439          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05440          MD5Final(digest, &md5);
05441          /* If they support md5, authenticate with it.  */
05442          for (x=0;x<16;x++)
05443             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05444          if (!strcasecmp(requeststr, md5secret)) {
05445             res = 0;
05446             break;
05447          }
05448       }
05449    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05450       if (!strcmp(secret, p->secret))
05451          res = 0;
05452    }
05453    return res;
05454 }
05455 
05456 /*! \brief Verify inbound registration */
05457 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05458 {
05459    char requeststr[256] = "";
05460    char peer[256] = "";
05461    char md5secret[256] = "";
05462    char rsasecret[256] = "";
05463    char secret[256] = "";
05464    struct iax2_peer *p = NULL;
05465    struct ast_key *key;
05466    char *keyn;
05467    int x;
05468    int expire = 0;
05469    int res = -1;
05470 
05471    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05472    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05473    if (ies->username)
05474       ast_copy_string(peer, ies->username, sizeof(peer));
05475    if (ies->password)
05476       ast_copy_string(secret, ies->password, sizeof(secret));
05477    if (ies->md5_result)
05478       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05479    if (ies->rsa_result)
05480       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05481    if (ies->refresh)
05482       expire = ies->refresh;
05483 
05484    if (ast_strlen_zero(peer)) {
05485       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05486       return -1;
05487    }
05488 
05489    /* SLD: first call to lookup peer during registration */
05490    ast_mutex_unlock(&iaxsl[callno]);
05491    p = find_peer(peer, 1);
05492    ast_mutex_lock(&iaxsl[callno]);
05493    if (!p || !iaxs[callno]) {
05494       if (authdebug && !p)
05495          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05496       goto return_unref;
05497    }
05498 
05499    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05500       if (authdebug)
05501          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05502       goto return_unref;
05503    }
05504 
05505    if (!ast_apply_ha(p->ha, sin)) {
05506       if (authdebug)
05507          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05508       goto return_unref;
05509    }
05510    if (!inaddrcmp(&p->addr, sin))
05511       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05512    ast_string_field_set(iaxs[callno], secret, p->secret);
05513    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05514    /* Check secret against what we have on file */
05515    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05516       if (!ast_strlen_zero(p->inkeys)) {
05517          char tmpkeys[256];
05518          char *stringp=NULL;
05519          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05520          stringp=tmpkeys;
05521          keyn = strsep(&stringp, ":");
05522          while(keyn) {
05523             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05524             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05525                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05526                break;
05527             } else if (!key) 
05528                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05529             keyn = strsep(&stringp, ":");
05530          }
05531          if (!keyn) {
05532             if (authdebug)
05533                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05534             goto return_unref;
05535          }
05536       } else {
05537          if (authdebug)
05538             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05539          goto return_unref;
05540       }
05541    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05542       struct MD5Context md5;
05543       unsigned char digest[16];
05544       char *tmppw, *stringp;
05545       
05546       tmppw = ast_strdupa(p->secret);
05547       stringp = tmppw;
05548       while((tmppw = strsep(&stringp, ";"))) {
05549          MD5Init(&md5);
05550          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05551          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05552          MD5Final(digest, &md5);
05553          for (x=0;x<16;x++)
05554             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05555          if (!strcasecmp(requeststr, md5secret)) 
05556             break;
05557       }
05558       if (tmppw) {
05559          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05560       } else {
05561          if (authdebug)
05562             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05563          goto return_unref;
05564       }
05565    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05566       /* They've provided a plain text password and we support that */
05567       if (strcmp(secret, p->secret)) {
05568          if (authdebug)
05569             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05570          goto return_unref;
05571       } else
05572          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05573    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05574       if (authdebug)
05575          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05576       goto return_unref;
05577    }
05578    ast_string_field_set(iaxs[callno], peer, peer);
05579    /* Choose lowest expiry number */
05580    if (expire && (expire < iaxs[callno]->expiry)) 
05581       iaxs[callno]->expiry = expire;
05582 
05583    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05584 
05585    res = 0;
05586 
05587 return_unref:
05588    if (p)
05589       peer_unref(p);
05590 
05591    return res;
05592 }
05593 
05594 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)
05595 {
05596    int res = -1;
05597    int x;
05598    if (!ast_strlen_zero(keyn)) {
05599       if (!(authmethods & IAX_AUTH_RSA)) {
05600          if (ast_strlen_zero(secret)) 
05601             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));
05602       } else if (ast_strlen_zero(challenge)) {
05603          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05604       } else {
05605          char sig[256];
05606          struct ast_key *key;
05607          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05608          if (!key) {
05609             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05610          } else {
05611             if (ast_sign(key, (char*)challenge, sig)) {
05612                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05613                res = -1;
05614             } else {
05615                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05616                res = 0;
05617             }
05618          }
05619       }
05620    } 
05621    /* Fall back */
05622    if (res && !ast_strlen_zero(secret)) {
05623       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05624          struct MD5Context md5;
05625          unsigned char digest[16];
05626          char digres[128];
05627          MD5Init(&md5);
05628          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05629          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05630          MD5Final(digest, &md5);
05631          /* If they support md5, authenticate with it.  */
05632          for (x=0;x<16;x++)
05633             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05634          if (ecx && dcx)
05635             build_enc_keys(digest, ecx, dcx);
05636          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05637          res = 0;
05638       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05639          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05640          res = 0;
05641       } else
05642          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05643    }
05644    return res;
05645 }
05646 
05647 /*!
05648  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05649  *       so do not call this function with a pvt lock held.
05650  */
05651 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05652 {
05653    struct iax2_peer *peer = NULL;
05654    /* Start pessimistic */
05655    int res = -1;
05656    int authmethods = 0;
05657    struct iax_ie_data ied;
05658    uint16_t callno = p->callno;
05659 
05660    memset(&ied, 0, sizeof(ied));
05661    
05662    if (ies->username)
05663       ast_string_field_set(p, username, ies->username);
05664    if (ies->challenge)
05665       ast_string_field_set(p, challenge, ies->challenge);
05666    if (ies->authmethods)
05667       authmethods = ies->authmethods;
05668    if (authmethods & IAX_AUTH_MD5)
05669       merge_encryption(p, ies->encmethods);
05670    else
05671       p->encmethods = 0;
05672 
05673    /* Check for override RSA authentication first */
05674    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05675       /* Normal password authentication */
05676       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05677    } else {
05678       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05679       while ((peer = ao2_iterator_next(&i))) {
05680          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05681              /* No peer specified at our end, or this is the peer */
05682              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05683              /* No username specified in peer rule, or this is the right username */
05684              && (!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)))
05685              /* No specified host, or this is our host */
05686             ) {
05687             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05688             if (!res) {
05689                peer_unref(peer);
05690                break;
05691             }
05692          }
05693          peer_unref(peer);
05694       }
05695       if (!peer) {
05696          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05697             that we're trying to authenticate *to* a realtime peer */
05698          const char *peer_name = ast_strdupa(p->peer);
05699          ast_mutex_unlock(&iaxsl[callno]);
05700          if ((peer = realtime_peer(peer_name, NULL))) {
05701             ast_mutex_lock(&iaxsl[callno]);
05702             if (!(p = iaxs[callno])) {
05703                peer_unref(peer);
05704                return -1;
05705             }
05706             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05707             peer_unref(peer);
05708          }
05709          if (!peer) {
05710             ast_mutex_lock(&iaxsl[callno]);
05711             if (!(p = iaxs[callno]))
05712                return -1;
05713          }
05714       }
05715    }
05716    if (ies->encmethods)
05717       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05718    if (!res)
05719       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05720    return res;
05721 }
05722 
05723 static int iax2_do_register(struct iax2_registry *reg);
05724 
05725 static void __iax2_do_register_s(const void *data)
05726 {
05727    struct iax2_registry *reg = (struct iax2_registry *)data;
05728    reg->expire = -1;
05729    iax2_do_register(reg);
05730 }
05731 
05732 static int iax2_do_register_s(const void *data)
05733 {
05734 #ifdef SCHED_MULTITHREADED
05735    if (schedule_action(__iax2_do_register_s, data))
05736 #endif      
05737       __iax2_do_register_s(data);
05738    return 0;
05739 }
05740 
05741 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05742 {
05743    int newcall = 0;
05744    char newip[256];
05745    struct iax_ie_data ied;
05746    struct sockaddr_in new;
05747    
05748    
05749    memset(&ied, 0, sizeof(ied));
05750    if (ies->apparent_addr)
05751       bcopy(ies->apparent_addr, &new, sizeof(new));
05752    if (ies->callno)
05753       newcall = ies->callno;
05754    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05755       ast_log(LOG_WARNING, "Invalid transfer request\n");
05756       return -1;
05757    }
05758    pvt->transfercallno = newcall;
05759    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05760    inet_aton(newip, &pvt->transfer.sin_addr);
05761    pvt->transfer.sin_family = AF_INET;
05762    pvt->transferring = TRANSFER_BEGIN;
05763    pvt->transferid = ies->transferid;
05764    if (ies->transferid)
05765       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05766    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05767    return 0; 
05768 }
05769 
05770 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05771 {
05772    char exten[256] = "";
05773    int status = CACHE_FLAG_UNKNOWN;
05774    int expiry = iaxdefaultdpcache;
05775    int x;
05776    int matchmore = 0;
05777    struct iax2_dpcache *dp, *prev;
05778    
05779    if (ies->called_number)
05780       ast_copy_string(exten, ies->called_number, sizeof(exten));
05781 
05782    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05783       status = CACHE_FLAG_EXISTS;
05784    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05785       status = CACHE_FLAG_CANEXIST;
05786    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05787       status = CACHE_FLAG_NONEXISTENT;
05788 
05789    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05790       /* Don't really do anything with this */
05791    }
05792    if (ies->refresh)
05793       expiry = ies->refresh;
05794    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05795       matchmore = CACHE_FLAG_MATCHMORE;
05796    ast_mutex_lock(&dpcache_lock);
05797    prev = NULL;
05798    dp = pvt->dpentries;
05799    while(dp) {
05800       if (!strcmp(dp->exten, exten)) {
05801          /* Let them go */
05802          if (prev)
05803             prev->peer = dp->peer;
05804          else
05805             pvt->dpentries = dp->peer;
05806          dp->peer = NULL;
05807          dp->callno = 0;
05808          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05809          if (dp->flags & CACHE_FLAG_PENDING) {
05810             dp->flags &= ~CACHE_FLAG_PENDING;
05811             dp->flags |= status;
05812             dp->flags |= matchmore;
05813          }
05814          /* Wake up waiters */
05815          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05816             if (dp->waiters[x] > -1)
05817                write(dp->waiters[x], "asdf", 4);
05818       }
05819       prev = dp;
05820       dp = dp->peer;
05821    }
05822    ast_mutex_unlock(&dpcache_lock);
05823    return 0;
05824 }
05825 
05826 static int complete_transfer(int callno, struct iax_ies *ies)
05827 {
05828    int peercallno = 0;
05829    struct chan_iax2_pvt *pvt = iaxs[callno];
05830    struct iax_frame *cur;
05831    jb_frame frame;
05832 
05833    if (ies->callno)
05834       peercallno = ies->callno;
05835 
05836    if (peercallno < 1) {
05837       ast_log(LOG_WARNING, "Invalid transfer request\n");
05838       return -1;
05839    }
05840    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05841    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05842    /* Reset sequence numbers */
05843    pvt->oseqno = 0;
05844    pvt->rseqno = 0;
05845    pvt->iseqno = 0;
05846    pvt->aseqno = 0;
05847 
05848    if (pvt->peercallno) {
05849       remove_by_peercallno(pvt);
05850    }
05851    pvt->peercallno = peercallno;
05852    store_by_peercallno(pvt);
05853 
05854    pvt->transferring = TRANSFER_NONE;
05855    pvt->svoiceformat = -1;
05856    pvt->voiceformat = 0;
05857    pvt->svideoformat = -1;
05858    pvt->videoformat = 0;
05859    pvt->transfercallno = -1;
05860    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05861    memset(&pvt->offset, 0, sizeof(pvt->offset));
05862    /* reset jitterbuffer */
05863    while(jb_getall(pvt->jb,&frame) == JB_OK)
05864       iax2_frame_free(frame.data);
05865    jb_reset(pvt->jb);
05866    pvt->lag = 0;
05867    pvt->last = 0;
05868    pvt->lastsent = 0;
05869    pvt->nextpred = 0;
05870    pvt->pingtime = DEFAULT_RETRY_TIME;
05871    AST_LIST_LOCK(&iaxq.queue);
05872    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05873       /* We must cancel any packets that would have been transmitted
05874          because now we're talking to someone new.  It's okay, they
05875          were transmitted to someone that didn't care anyway. */
05876       if (callno == cur->callno) 
05877          cur->retries = -1;
05878    }
05879    AST_LIST_UNLOCK(&iaxq.queue);
05880    return 0; 
05881 }
05882 
05883 /*! \brief Acknowledgment received for OUR registration */
05884 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05885 {
05886    struct iax2_registry *reg;
05887    /* Start pessimistic */
05888    char peer[256] = "";
05889    char msgstatus[60];
05890    int refresh = 60;
05891    char ourip[256] = "<Unspecified>";
05892    struct sockaddr_in oldus;
05893    struct sockaddr_in us;
05894    int oldmsgs;
05895 
05896    memset(&us, 0, sizeof(us));
05897    if (ies->apparent_addr)
05898       bcopy(ies->apparent_addr, &us, sizeof(us));
05899    if (ies->username)
05900       ast_copy_string(peer, ies->username, sizeof(peer));
05901    if (ies->refresh)
05902       refresh = ies->refresh;
05903    if (ies->calling_number) {
05904       /* We don't do anything with it really, but maybe we should */
05905    }
05906    reg = iaxs[callno]->reg;
05907    if (!reg) {
05908       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05909       return -1;
05910    }
05911    memcpy(&oldus, &reg->us, sizeof(oldus));
05912    oldmsgs = reg->messages;
05913    if (inaddrcmp(&reg->addr, sin)) {
05914       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05915       return -1;
05916    }
05917    memcpy(&reg->us, &us, sizeof(reg->us));
05918    if (ies->msgcount >= 0)
05919       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05920    /* always refresh the registration at the interval requested by the server
05921       we are registering to
05922    */
05923    reg->refresh = refresh;
05924    AST_SCHED_DEL(sched, reg->expire);
05925    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05926    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05927       if (option_verbose > 2) {
05928          if (reg->messages > 255)
05929             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05930          else if (reg->messages > 1)
05931             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05932          else if (reg->messages > 0)
05933             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05934          else
05935             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05936          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05937          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05938       }
05939       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05940    }
05941    reg->regstate = REG_STATE_REGISTERED;
05942    return 0;
05943 }
05944 
05945 static int iax2_register(char *value, int lineno)
05946 {
05947    struct iax2_registry *reg;
05948    char copy[256];
05949    char *username, *hostname, *secret;
05950    char *porta;
05951    char *stringp=NULL;
05952    
05953    if (!value)
05954       return -1;
05955    ast_copy_string(copy, value, sizeof(copy));
05956    stringp=copy;
05957    username = strsep(&stringp, "@");
05958    hostname = strsep(&stringp, "@");
05959    if (!hostname) {
05960       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05961       return -1;
05962    }
05963    stringp=username;
05964    username = strsep(&stringp, ":");
05965    secret = strsep(&stringp, ":");
05966    stringp=hostname;
05967    hostname = strsep(&stringp, ":");
05968    porta = strsep(&stringp, ":");
05969    
05970    if (porta && !atoi(porta)) {
05971       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05972       return -1;
05973    }
05974    if (!(reg = ast_calloc(1, sizeof(*reg))))
05975       return -1;
05976    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05977       free(reg);
05978       return -1;
05979    }
05980    ast_copy_string(reg->username, username, sizeof(reg->username));
05981    if (secret)
05982       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05983    reg->expire = -1;
05984    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05985    reg->addr.sin_family = AF_INET;
05986    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05987    AST_LIST_LOCK(&registrations);
05988    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05989    AST_LIST_UNLOCK(&registrations);
05990    
05991    return 0;
05992 }
05993 
05994 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05995 {
05996    char multi[256];
05997    char *stringp, *ext;
05998    if (!ast_strlen_zero(regcontext)) {
05999       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06000       stringp = multi;
06001       while((ext = strsep(&stringp, "&"))) {
06002          if (onoff) {
06003             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06004                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06005                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06006          } else
06007             ast_context_remove_extension(regcontext, ext, 1, NULL);
06008       }
06009    }
06010 }
06011 static void prune_peers(void);
06012 
06013 static void unlink_peer(struct iax2_peer *peer)
06014 {
06015    if (peer->expire > -1) {
06016       if (!ast_sched_del(sched, peer->expire)) {
06017          peer->expire = -1;
06018          peer_unref(peer);
06019       }
06020    }
06021 
06022    if (peer->pokeexpire > -1) {
06023       if (!ast_sched_del(sched, peer->pokeexpire)) {
06024          peer->pokeexpire = -1;
06025          peer_unref(peer);
06026       }
06027    }
06028 
06029    ao2_unlink(peers, peer);
06030 }
06031 
06032 static void __expire_registry(const void *data)
06033 {
06034    struct iax2_peer *peer = (struct iax2_peer *) data;
06035 
06036    if (!peer)
06037       return;
06038 
06039    peer->expire = -1;
06040 
06041    if (option_debug)
06042       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06043    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06044       realtime_update_peer(peer->name, &peer->addr, 0);
06045    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06046    /* Reset the address */
06047    memset(&peer->addr, 0, sizeof(peer->addr));
06048    /* Reset expiry value */
06049    peer->expiry = min_reg_expire;
06050    if (!ast_test_flag(peer, IAX_TEMPONLY))
06051       ast_db_del("IAX/Registry", peer->name);
06052    register_peer_exten(peer, 0);
06053    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06054    if (iax2_regfunk)
06055       iax2_regfunk(peer->name, 0);
06056 
06057    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06058       unlink_peer(peer);
06059 
06060    peer_unref(peer);
06061 }
06062 
06063 static int expire_registry(const void *data)
06064 {
06065 #ifdef SCHED_MULTITHREADED
06066    if (schedule_action(__expire_registry, data))
06067 #endif      
06068       __expire_registry(data);
06069    return 0;
06070 }
06071 
06072 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06073 
06074 static void reg_source_db(struct iax2_peer *p)
06075 {
06076    char data[80];
06077    struct in_addr in;
06078    char *c, *d;
06079    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06080       c = strchr(data, ':');
06081       if (c) {
06082          *c = '\0';
06083          c++;
06084          if (inet_aton(data, &in)) {
06085             d = strchr(c, ':');
06086             if (d) {
06087                *d = '\0';
06088                d++;
06089                if (option_verbose > 2)
06090                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06091                   ast_inet_ntoa(in), atoi(c), atoi(d));
06092                iax2_poke_peer(p, 0);
06093                p->expiry = atoi(d);
06094                memset(&p->addr, 0, sizeof(p->addr));
06095                p->addr.sin_family = AF_INET;
06096                p->addr.sin_addr = in;
06097                p->addr.sin_port = htons(atoi(c));
06098                if (p->expire > -1) {
06099                   if (!ast_sched_del(sched, p->expire)) {
06100                      p->expire = -1;
06101                      peer_unref(p);
06102                   }
06103                }
06104                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06105                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06106                if (p->expire == -1)
06107                   peer_unref(p);
06108                if (iax2_regfunk)
06109                   iax2_regfunk(p->name, 1);
06110                register_peer_exten(p, 1);
06111             }              
06112                
06113          }
06114       }
06115    }
06116 }
06117 
06118 /*!
06119  * \pre iaxsl[callno] is locked
06120  *
06121  * \note Since this function calls send_command_final(), the pvt struct for
06122  *       the given call number may disappear while executing this function.
06123  */
06124 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06125 {
06126    /* Called from IAX thread only, with proper iaxsl lock */
06127    struct iax_ie_data ied;
06128    struct iax2_peer *p;
06129    int msgcount;
06130    char data[80];
06131    int version;
06132    const char *peer_name;
06133    int res = -1;
06134 
06135    memset(&ied, 0, sizeof(ied));
06136 
06137    peer_name = ast_strdupa(iaxs[callno]->peer);
06138 
06139    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06140    ast_mutex_unlock(&iaxsl[callno]);
06141    if (!(p = find_peer(peer_name, 1))) {
06142       ast_mutex_lock(&iaxsl[callno]);
06143       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06144       return -1;
06145    }
06146    ast_mutex_lock(&iaxsl[callno]);
06147    if (!iaxs[callno])
06148       goto return_unref;
06149 
06150    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06151       if (sin->sin_addr.s_addr) {
06152          time_t nowtime;
06153          time(&nowtime);
06154          realtime_update_peer(peer_name, sin, nowtime);
06155       } else {
06156          realtime_update_peer(peer_name, sin, 0);
06157       }
06158    }
06159    if (inaddrcmp(&p->addr, sin)) {
06160       if (iax2_regfunk)
06161          iax2_regfunk(p->name, 1);
06162       /* Stash the IP address from which they registered */
06163       memcpy(&p->addr, sin, sizeof(p->addr));
06164       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06165       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06166          ast_db_put("IAX/Registry", p->name, data);
06167          if  (option_verbose > 2)
06168             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06169                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06170          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06171          register_peer_exten(p, 1);
06172          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06173       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06174          if  (option_verbose > 2)
06175             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06176                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06177          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06178          register_peer_exten(p, 0);
06179          ast_db_del("IAX/Registry", p->name);
06180          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06181       }
06182       /* Update the host */
06183       /* Verify that the host is really there */
06184       iax2_poke_peer(p, callno);
06185    }     
06186 
06187    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06188    if (!iaxs[callno]) {
06189       res = 0;
06190       goto return_unref;
06191    }
06192 
06193    /* Store socket fd */
06194    p->sockfd = fd;
06195    /* Setup the expiry */
06196    if (p->expire > -1) {
06197       if (!ast_sched_del(sched, p->expire)) {
06198          p->expire = -1;
06199          peer_unref(p);
06200       }
06201    }
06202    /* treat an unspecified refresh interval as the minimum */
06203    if (!refresh)
06204       refresh = min_reg_expire;
06205    if (refresh > max_reg_expire) {
06206       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06207          p->name, max_reg_expire, refresh);
06208       p->expiry = max_reg_expire;
06209    } else if (refresh < min_reg_expire) {
06210       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06211          p->name, min_reg_expire, refresh);
06212       p->expiry = min_reg_expire;
06213    } else {
06214       p->expiry = refresh;
06215    }
06216    if (p->expiry && sin->sin_addr.s_addr) {
06217       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06218       if (p->expire == -1)
06219          peer_unref(p);
06220    }
06221    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06222    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06223    if (sin->sin_addr.s_addr) {
06224       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06225       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06226       if (!ast_strlen_zero(p->mailbox)) {
06227          int new, old;
06228          ast_app_inboxcount(p->mailbox, &new, &old);
06229          if (new > 255)
06230             new = 255;
06231          if (old > 255)
06232             old = 255;
06233          msgcount = (old << 8) | new;
06234          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06235       }
06236       if (ast_test_flag(p, IAX_HASCALLERID)) {
06237          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06238          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06239       }
06240    }
06241    version = iax_check_version(devtype);
06242    if (version) 
06243       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06244 
06245    res = 0;
06246 
06247 return_unref:
06248    peer_unref(p);
06249 
06250    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06251 }
06252 
06253 static int registry_authrequest(int callno)
06254 {
06255    struct iax_ie_data ied;
06256    struct iax2_peer *p;
06257    char challenge[10];
06258    const char *peer_name;
06259    int res = -1;
06260 
06261    peer_name = ast_strdupa(iaxs[callno]->peer);
06262 
06263    /* SLD: third call to find_peer in registration */
06264    ast_mutex_unlock(&iaxsl[callno]);
06265    p = find_peer(peer_name, 1);
06266    ast_mutex_lock(&iaxsl[callno]);
06267    if (!iaxs[callno])
06268       goto return_unref;
06269    if (!p) {
06270       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06271       goto return_unref;
06272    }
06273    
06274    memset(&ied, 0, sizeof(ied));
06275    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06276    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06277       /* Build the challenge */
06278       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06279       ast_string_field_set(iaxs[callno], challenge, challenge);
06280       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06281    }
06282    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06283 
06284    res = 0;
06285 
06286 return_unref:
06287    peer_unref(p);
06288 
06289    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06290 }
06291 
06292 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06293 {
06294    struct iax2_registry *reg;
06295    /* Start pessimistic */
06296    struct iax_ie_data ied;
06297    char peer[256] = "";
06298    char challenge[256] = "";
06299    int res;
06300    int authmethods = 0;
06301    if (ies->authmethods)
06302       authmethods = ies->authmethods;
06303    if (ies->username)
06304       ast_copy_string(peer, ies->username, sizeof(peer));
06305    if (ies->challenge)
06306       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06307    memset(&ied, 0, sizeof(ied));
06308    reg = iaxs[callno]->reg;
06309    if (reg) {
06310          if (inaddrcmp(&reg->addr, sin)) {
06311             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06312             return -1;
06313          }
06314          if (ast_strlen_zero(reg->secret)) {
06315             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06316             reg->regstate = REG_STATE_NOAUTH;
06317             return -1;
06318          }
06319          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06320          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06321          if (reg->secret[0] == '[') {
06322             char tmpkey[256];
06323             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06324             tmpkey[strlen(tmpkey) - 1] = '\0';
06325             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06326          } else
06327             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06328          if (!res) {
06329             reg->regstate = REG_STATE_AUTHSENT;
06330             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06331          } else
06332             return -1;
06333          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06334    } else   
06335       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06336    return -1;
06337 }
06338 
06339 static void stop_stuff(int callno)
06340 {
06341    iax2_destroy_helper(iaxs[callno]);
06342 }
06343 
06344 static void __auth_reject(const void *nothing)
06345 {
06346    /* Called from IAX thread only, without iaxs lock */
06347    int callno = (int)(long)(nothing);
06348    struct iax_ie_data ied;
06349    ast_mutex_lock(&iaxsl[callno]);
06350    if (iaxs[callno]) {
06351       memset(&ied, 0, sizeof(ied));
06352       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06353          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06354          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06355       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06356          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06357          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06358       }
06359       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06360    }
06361    ast_mutex_unlock(&iaxsl[callno]);
06362 }
06363 
06364 static int auth_reject(const void *data)
06365 {
06366    int callno = (int)(long)(data);
06367    ast_mutex_lock(&iaxsl[callno]);
06368    if (iaxs[callno])
06369       iaxs[callno]->authid = -1;
06370    ast_mutex_unlock(&iaxsl[callno]);
06371 #ifdef SCHED_MULTITHREADED
06372    if (schedule_action(__auth_reject, data))
06373 #endif      
06374       __auth_reject(data);
06375    return 0;
06376 }
06377 
06378 static int auth_fail(int callno, int failcode)
06379 {
06380    /* Schedule sending the authentication failure in one second, to prevent
06381       guessing */
06382    if (iaxs[callno]) {
06383       iaxs[callno]->authfail = failcode;
06384       if (delayreject) {
06385          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06386          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06387       } else
06388          auth_reject((void *)(long)callno);
06389    }
06390    return 0;
06391 }
06392 
06393 static void __auto_hangup(const void *nothing)
06394 {
06395    /* Called from IAX thread only, without iaxs lock */
06396    int callno = (int)(long)(nothing);
06397    struct iax_ie_data ied;
06398    ast_mutex_lock(&iaxsl[callno]);
06399    if (iaxs[callno]) {
06400       memset(&ied, 0, sizeof(ied));
06401       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06402       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06403       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06404    }
06405    ast_mutex_unlock(&iaxsl[callno]);
06406 }
06407 
06408 static int auto_hangup(const void *data)
06409 {
06410    int callno = (int)(long)(data);
06411    ast_mutex_lock(&iaxsl[callno]);
06412    if (iaxs[callno]) {
06413       iaxs[callno]->autoid = -1;
06414    }
06415    ast_mutex_unlock(&iaxsl[callno]);
06416 #ifdef SCHED_MULTITHREADED
06417    if (schedule_action(__auto_hangup, data))
06418 #endif      
06419       __auto_hangup(data);
06420    return 0;
06421 }
06422 
06423 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06424 {
06425    struct iax_ie_data ied;
06426    /* Auto-hangup with 30 seconds of inactivity */
06427    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06428    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06429    memset(&ied, 0, sizeof(ied));
06430    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06431    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06432    dp->flags |= CACHE_FLAG_TRANSMITTED;
06433 }
06434 
06435 static int iax2_vnak(int callno)
06436 {
06437    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06438 }
06439 
06440 static void vnak_retransmit(int callno, int last)
06441 {
06442    struct iax_frame *f;
06443 
06444    AST_LIST_LOCK(&iaxq.queue);
06445    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06446       /* Send a copy immediately */
06447       if ((f->callno == callno) && iaxs[f->callno] &&
06448          ((unsigned char ) (f->oseqno - last) < 128) &&
06449          (f->retries >= 0)) {
06450          send_packet(f);
06451       }
06452    }
06453    AST_LIST_UNLOCK(&iaxq.queue);
06454 }
06455 
06456 static void __iax2_poke_peer_s(const void *data)
06457 {
06458    struct iax2_peer *peer = (struct iax2_peer *)data;
06459    iax2_poke_peer(peer, 0);
06460    peer_unref(peer);
06461 }
06462 
06463 static int iax2_poke_peer_s(const void *data)
06464 {
06465    struct iax2_peer *peer = (struct iax2_peer *)data;
06466    peer->pokeexpire = -1;
06467 #ifdef SCHED_MULTITHREADED
06468    if (schedule_action(__iax2_poke_peer_s, data))
06469 #endif      
06470       __iax2_poke_peer_s(data);
06471    return 0;
06472 }
06473 
06474 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06475 {
06476    int res = 0;
06477    struct iax_frame *fr;
06478    struct ast_iax2_meta_hdr *meta;
06479    struct ast_iax2_meta_trunk_hdr *mth;
06480    int calls = 0;
06481    
06482    /* Point to frame */
06483    fr = (struct iax_frame *)tpeer->trunkdata;
06484    /* Point to meta data */
06485    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06486    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06487    if (tpeer->trunkdatalen) {
06488       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06489       meta->zeros = 0;
06490       meta->metacmd = IAX_META_TRUNK;
06491       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06492          meta->cmddata = IAX_META_TRUNK_MINI;
06493       else
06494          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06495       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06496       /* And the rest of the ast_iax2 header */
06497       fr->direction = DIRECTION_OUTGRESS;
06498       fr->retrans = -1;
06499       fr->transfer = 0;
06500       /* Any appropriate call will do */
06501       fr->data = fr->afdata;
06502       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06503       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06504       calls = tpeer->calls;
06505 #if 0
06506       if (option_debug)
06507          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));
06508 #endif      
06509       /* Reset transmit trunk side data */
06510       tpeer->trunkdatalen = 0;
06511       tpeer->calls = 0;
06512    }
06513    if (res < 0)
06514       return res;
06515    return calls;
06516 }
06517 
06518 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06519 {
06520    /* Drop when trunk is about 5 seconds idle */
06521    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06522       return 1;
06523    return 0;
06524 }
06525 
06526 static int timing_read(int *id, int fd, short events, void *cbdata)
06527 {
06528    char buf[1024];
06529    int res;
06530    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06531    int processed = 0;
06532    int totalcalls = 0;
06533 #ifdef ZT_TIMERACK
06534    int x = 1;
06535 #endif
06536    struct timeval now;
06537    if (iaxtrunkdebug)
06538       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06539    gettimeofday(&now, NULL);
06540    if (events & AST_IO_PRI) {
06541 #ifdef ZT_TIMERACK
06542       /* Great, this is a timing interface, just call the ioctl */
06543       if (ioctl(fd, ZT_TIMERACK, &x)) {
06544          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06545          usleep(1);
06546          return -1;
06547       }
06548 #endif      
06549    } else {
06550       /* Read and ignore from the pseudo channel for timing */
06551       res = read(fd, buf, sizeof(buf));
06552       if (res < 1) {
06553          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06554          return 1;
06555       }
06556    }
06557    /* For each peer that supports trunking... */
06558    ast_mutex_lock(&tpeerlock);
06559    tpeer = tpeers;
06560    while(tpeer) {
06561       processed++;
06562       res = 0;
06563       ast_mutex_lock(&tpeer->lock);
06564       /* We can drop a single tpeer per pass.  That makes all this logic
06565          substantially easier */
06566       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06567          /* Take it out of the list, but don't free it yet, because it
06568             could be in use */
06569          if (prev)
06570             prev->next = tpeer->next;
06571          else
06572             tpeers = tpeer->next;
06573          drop = tpeer;
06574       } else {
06575          res = send_trunk(tpeer, &now);
06576          if (iaxtrunkdebug)
06577             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);
06578       }     
06579       totalcalls += res;   
06580       res = 0;
06581       ast_mutex_unlock(&tpeer->lock);
06582       prev = tpeer;
06583       tpeer = tpeer->next;
06584    }
06585    ast_mutex_unlock(&tpeerlock);
06586    if (drop) {
06587       ast_mutex_lock(&drop->lock);
06588       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06589          because by the time they could get tpeerlock, we've already grabbed it */
06590       if (option_debug)
06591          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06592       if (drop->trunkdata) {
06593          free(drop->trunkdata);
06594          drop->trunkdata = NULL;
06595       }
06596       ast_mutex_unlock(&drop->lock);
06597       ast_mutex_destroy(&drop->lock);
06598       free(drop);
06599       
06600    }
06601    if (iaxtrunkdebug)
06602       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06603    iaxtrunkdebug =0;
06604    return 1;
06605 }
06606 
06607 struct dpreq_data {
06608    int callno;
06609    char context[AST_MAX_EXTENSION];
06610    char callednum[AST_MAX_EXTENSION];
06611    char *callerid;
06612 };
06613 
06614 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06615 {
06616    unsigned short dpstatus = 0;
06617    struct iax_ie_data ied1;
06618    int mm;
06619 
06620    memset(&ied1, 0, sizeof(ied1));
06621    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06622    /* Must be started */
06623    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06624       dpstatus = IAX_DPSTATUS_EXISTS;
06625    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06626       dpstatus = IAX_DPSTATUS_CANEXIST;
06627    } else {
06628       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06629    }
06630    if (ast_ignore_pattern(context, callednum))
06631       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06632    if (mm)
06633       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06634    if (!skiplock)
06635       ast_mutex_lock(&iaxsl[callno]);
06636    if (iaxs[callno]) {
06637       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06638       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06639       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06640       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06641    }
06642    if (!skiplock)
06643       ast_mutex_unlock(&iaxsl[callno]);
06644 }
06645 
06646 static void *dp_lookup_thread(void *data)
06647 {
06648    /* Look up for dpreq */
06649    struct dpreq_data *dpr = data;
06650    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06651    if (dpr->callerid)
06652       free(dpr->callerid);
06653    free(dpr);
06654    return NULL;
06655 }
06656 
06657 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06658 {
06659    pthread_t newthread;
06660    struct dpreq_data *dpr;
06661    pthread_attr_t attr;
06662    
06663    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06664       return;
06665 
06666    pthread_attr_init(&attr);
06667    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06668 
06669    dpr->callno = callno;
06670    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06671    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06672    if (callerid)
06673       dpr->callerid = ast_strdup(callerid);
06674    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06675       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06676    }
06677 
06678    pthread_attr_destroy(&attr);
06679 }
06680 
06681 struct iax_dual {
06682    struct ast_channel *chan1;
06683    struct ast_channel *chan2;
06684 };
06685 
06686 static void *iax_park_thread(void *stuff)
06687 {
06688    struct ast_channel *chan1, *chan2;
06689    struct iax_dual *d;
06690    struct ast_frame *f;
06691    int ext;
06692    int res;
06693    d = stuff;
06694    chan1 = d->chan1;
06695    chan2 = d->chan2;
06696    free(d);
06697    f = ast_read(chan1);
06698    if (f)
06699       ast_frfree(f);
06700    res = ast_park_call(chan1, chan2, 0, &ext);
06701    ast_hangup(chan2);
06702    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06703    return NULL;
06704 }
06705 
06706 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06707 {
06708    struct iax_dual *d;
06709    struct ast_channel *chan1m, *chan2m;
06710    pthread_t th;
06711    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06712    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06713    if (chan2m && chan1m) {
06714       /* Make formats okay */
06715       chan1m->readformat = chan1->readformat;
06716       chan1m->writeformat = chan1->writeformat;
06717       ast_channel_masquerade(chan1m, chan1);
06718       /* Setup the extensions and such */
06719       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06720       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06721       chan1m->priority = chan1->priority;
06722       
06723       /* We make a clone of the peer channel too, so we can play
06724          back the announcement */
06725       /* Make formats okay */
06726       chan2m->readformat = chan2->readformat;
06727       chan2m->writeformat = chan2->writeformat;
06728       ast_channel_masquerade(chan2m, chan2);
06729       /* Setup the extensions and such */
06730       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06731       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06732       chan2m->priority = chan2->priority;
06733       if (ast_do_masquerade(chan2m)) {
06734          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06735          ast_hangup(chan2m);
06736          return -1;
06737       }
06738    } else {
06739       if (chan1m)
06740          ast_hangup(chan1m);
06741       if (chan2m)
06742          ast_hangup(chan2m);
06743       return -1;
06744    }
06745    if ((d = ast_calloc(1, sizeof(*d)))) {
06746       pthread_attr_t attr;
06747 
06748       pthread_attr_init(&attr);
06749       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06750 
06751       d->chan1 = chan1m;
06752       d->chan2 = chan2m;
06753       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06754          pthread_attr_destroy(&attr);
06755          return 0;
06756       }
06757       pthread_attr_destroy(&attr);
06758       free(d);
06759    }
06760    return -1;
06761 }
06762 
06763 
06764 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06765 
06766 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06767 {
06768    unsigned int ourver;
06769    char rsi[80];
06770    snprintf(rsi, sizeof(rsi), "si-%s", si);
06771    if (iax_provision_version(&ourver, rsi, 1))
06772       return 0;
06773    if (option_debug)
06774       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06775    if (ourver != ver) 
06776       iax2_provision(sin, sockfd, NULL, rsi, 1);
06777    return 0;
06778 }
06779 
06780 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06781 {
06782    jb_info stats;
06783    jb_getinfo(pvt->jb, &stats);
06784    
06785    memset(iep, 0, sizeof(*iep));
06786 
06787    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06788    if(stats.frames_in == 0) stats.frames_in = 1;
06789    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06790    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06791    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06792    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06793    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06794 }
06795 
06796 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06797 {
06798    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06799    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06800    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06801    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06802    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06803    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06804    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06805 }
06806 
06807 static int socket_process(struct iax2_thread *thread);
06808 
06809 /*!
06810  * \brief Handle any deferred full frames for this thread
06811  */
06812 static void handle_deferred_full_frames(struct iax2_thread *thread)
06813 {
06814    struct iax2_pkt_buf *pkt_buf;
06815 
06816    ast_mutex_lock(&thread->lock);
06817 
06818    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06819       ast_mutex_unlock(&thread->lock);
06820 
06821       thread->buf = pkt_buf->buf;
06822       thread->buf_len = pkt_buf->len;
06823       thread->buf_size = pkt_buf->len + 1;
06824       
06825       socket_process(thread);
06826 
06827       thread->buf = NULL;
06828       ast_free(pkt_buf);
06829 
06830       ast_mutex_lock(&thread->lock);
06831    }
06832 
06833    ast_mutex_unlock(&thread->lock);
06834 }
06835 
06836 /*!
06837  * \brief Queue the last read full frame for processing by a certain thread
06838  *
06839  * If there are already any full frames queued, they are sorted
06840  * by sequence number.
06841  */
06842 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06843 {
06844    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06845    struct ast_iax2_full_hdr *fh, *cur_fh;
06846 
06847    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06848       return;
06849 
06850    pkt_buf->len = from_here->buf_len;
06851    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06852 
06853    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06854    ast_mutex_lock(&to_here->lock);
06855    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06856       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06857       if (fh->oseqno < cur_fh->oseqno) {
06858          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06859          break;
06860       }
06861    }
06862    AST_LIST_TRAVERSE_SAFE_END
06863 
06864    if (!cur_pkt_buf)
06865       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06866    
06867    ast_mutex_unlock(&to_here->lock);
06868 }
06869 
06870 static int socket_read(int *id, int fd, short events, void *cbdata)
06871 {
06872    struct iax2_thread *thread;
06873    socklen_t len;
06874    time_t t;
06875    static time_t last_errtime = 0;
06876    struct ast_iax2_full_hdr *fh;
06877 
06878    if (!(thread = find_idle_thread())) {
06879       time(&t);
06880       if (t != last_errtime && option_debug)
06881          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06882       last_errtime = t;
06883       usleep(1);
06884       return 1;
06885    }
06886 
06887    len = sizeof(thread->iosin);
06888    thread->iofd = fd;
06889    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06890    thread->buf_size = sizeof(thread->readbuf);
06891    thread->buf = thread->readbuf;
06892    if (thread->buf_len < 0) {
06893       if (errno != ECONNREFUSED && errno != EAGAIN)
06894          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06895       handle_error();
06896       thread->iostate = IAX_IOSTATE_IDLE;
06897       signal_condition(&thread->lock, &thread->cond);
06898       return 1;
06899    }
06900    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06901       thread->iostate = IAX_IOSTATE_IDLE;
06902       signal_condition(&thread->lock, &thread->cond);
06903       return 1;
06904    }
06905    
06906    /* Determine if this frame is a full frame; if so, and any thread is currently
06907       processing a full frame for the same callno from this peer, then drop this
06908       frame (and the peer will retransmit it) */
06909    fh = (struct ast_iax2_full_hdr *) thread->buf;
06910    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06911       struct iax2_thread *cur = NULL;
06912       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06913       
06914       AST_LIST_LOCK(&active_list);
06915       AST_LIST_TRAVERSE(&active_list, cur, list) {
06916          if ((cur->ffinfo.callno == callno) &&
06917              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06918             break;
06919       }
06920       if (cur) {
06921          /* we found another thread processing a full frame for this call,
06922             so queue it up for processing later. */
06923          defer_full_frame(thread, cur);
06924          AST_LIST_UNLOCK(&active_list);
06925          thread->iostate = IAX_IOSTATE_IDLE;
06926          signal_condition(&thread->lock, &thread->cond);
06927          return 1;
06928       } else {
06929          /* this thread is going to process this frame, so mark it */
06930          thread->ffinfo.callno = callno;
06931          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06932          thread->ffinfo.type = fh->type;
06933          thread->ffinfo.csub = fh->csub;
06934       }
06935       AST_LIST_UNLOCK(&active_list);
06936    }
06937    
06938    /* Mark as ready and send on its way */
06939    thread->iostate = IAX_IOSTATE_READY;
06940 #ifdef DEBUG_SCHED_MULTITHREAD
06941    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06942 #endif
06943    signal_condition(&thread->lock, &thread->cond);
06944 
06945    return 1;
06946 }
06947 
06948 static int socket_process(struct iax2_thread *thread)
06949 {
06950    struct sockaddr_in sin;
06951    int res;
06952    int updatehistory=1;
06953    int new = NEW_PREVENT;
06954    void *ptr;
06955    int dcallno = 0;
06956    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06957    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06958    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06959    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06960    struct ast_iax2_meta_trunk_hdr *mth;
06961    struct ast_iax2_meta_trunk_entry *mte;
06962    struct ast_iax2_meta_trunk_mini *mtm;
06963    struct iax_frame *fr;
06964    struct iax_frame *cur;
06965    struct ast_frame f = { 0, };
06966    struct ast_channel *c;
06967    struct iax2_dpcache *dp;
06968    struct iax2_peer *peer;
06969    struct iax2_trunk_peer *tpeer;
06970    struct timeval rxtrunktime;
06971    struct iax_ies ies;
06972    struct iax_ie_data ied0, ied1;
06973    int format;
06974    int fd;
06975    int exists;
06976    int minivid = 0;
06977    unsigned int ts;
06978    char empty[32]="";      /* Safety measure */
06979    struct iax_frame *duped_fr;
06980    char host_pref_buf[128];
06981    char caller_pref_buf[128];
06982    struct ast_codec_pref pref;
06983    char *using_prefs = "mine";
06984 
06985    /* allocate an iax_frame with 4096 bytes of data buffer */
06986    fr = alloca(sizeof(*fr) + 4096);
06987    memset(fr, 0, sizeof(*fr));
06988    fr->afdatalen = 4096; /* From alloca() above */
06989 
06990    /* Copy frequently used parameters to the stack */
06991    res = thread->buf_len;
06992    fd = thread->iofd;
06993    memcpy(&sin, &thread->iosin, sizeof(sin));
06994 
06995    if (res < sizeof(*mh)) {
06996       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06997       return 1;
06998    }
06999    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07000       if (res < sizeof(*vh)) {
07001          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));
07002          return 1;
07003       }
07004 
07005       /* This is a video frame, get call number */
07006       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07007       minivid = 1;
07008    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07009       unsigned char metatype;
07010 
07011       if (res < sizeof(*meta)) {
07012          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));
07013          return 1;
07014       }
07015 
07016       /* This is a meta header */
07017       switch(meta->metacmd) {
07018       case IAX_META_TRUNK:
07019          if (res < (sizeof(*meta) + sizeof(*mth))) {
07020             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07021                sizeof(*meta) + sizeof(*mth));
07022             return 1;
07023          }
07024          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07025          ts = ntohl(mth->ts);
07026          metatype = meta->cmddata;
07027          res -= (sizeof(*meta) + sizeof(*mth));
07028          ptr = mth->data;
07029          tpeer = find_tpeer(&sin, fd);
07030          if (!tpeer) {
07031             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));
07032             return 1;
07033          }
07034          tpeer->trunkact = ast_tvnow();
07035          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07036             tpeer->rxtrunktime = tpeer->trunkact;
07037          rxtrunktime = tpeer->rxtrunktime;
07038          ast_mutex_unlock(&tpeer->lock);
07039          while(res >= sizeof(*mte)) {
07040             /* Process channels */
07041             unsigned short callno, trunked_ts, len;
07042 
07043             if (metatype == IAX_META_TRUNK_MINI) {
07044                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07045                ptr += sizeof(*mtm);
07046                res -= sizeof(*mtm);
07047                len = ntohs(mtm->len);
07048                callno = ntohs(mtm->mini.callno);
07049                trunked_ts = ntohs(mtm->mini.ts);
07050             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07051                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07052                ptr += sizeof(*mte);
07053                res -= sizeof(*mte);
07054                len = ntohs(mte->len);
07055                callno = ntohs(mte->callno);
07056                trunked_ts = 0;
07057             } else {
07058                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07059                break;
07060             }
07061             /* Stop if we don't have enough data */
07062             if (len > res)
07063                break;
07064             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07065             if (fr->callno) {
07066                /* If it's a valid call, deliver the contents.  If not, we
07067                   drop it, since we don't have a scallno to use for an INVAL */
07068                /* Process as a mini frame */
07069                memset(&f, 0, sizeof(f));
07070                f.frametype = AST_FRAME_VOICE;
07071                if (iaxs[fr->callno]) {
07072                   if (iaxs[fr->callno]->voiceformat > 0) {
07073                      f.subclass = iaxs[fr->callno]->voiceformat;
07074                      f.datalen = len;
07075                      if (f.datalen >= 0) {
07076                         if (f.datalen)
07077                            f.data = ptr;
07078                         if(trunked_ts) {
07079                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07080                         } else
07081                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07082                         /* Don't pass any packets until we're started */
07083                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07084                            /* Common things */
07085                            f.src = "IAX2";
07086                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07087                               f.samples = ast_codec_get_samples(&f);
07088                            iax_frame_wrap(fr, &f);
07089                            duped_fr = iaxfrdup2(fr);
07090                            if (duped_fr) {
07091                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07092                            }
07093                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07094                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07095                               iaxs[fr->callno]->last = fr->ts;
07096 #if 1
07097                               if (option_debug && iaxdebug)
07098                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07099 #endif
07100                            }
07101                         }
07102                      } else {
07103                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07104                      }
07105                   } else {
07106                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07107                      iax2_vnak(fr->callno);
07108                   }
07109                }
07110                ast_mutex_unlock(&iaxsl[fr->callno]);
07111             }
07112             ptr += len;
07113             res -= len;
07114          }
07115          
07116       }
07117       return 1;
07118    }
07119 
07120 #ifdef DEBUG_SUPPORT
07121    if (iaxdebug && (res >= sizeof(*fh)))
07122       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07123 #endif
07124    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07125       if (res < sizeof(*fh)) {
07126          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));
07127          return 1;
07128       }
07129 
07130       /* Get the destination call number */
07131       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07132       /* Retrieve the type and subclass */
07133       f.frametype = fh->type;
07134       if (f.frametype == AST_FRAME_VIDEO) {
07135          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07136       } else {
07137          f.subclass = uncompress_subclass(fh->csub);
07138       }
07139 
07140       /* Deal with POKE/PONG without allocating a callno */
07141       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07142          /* Reply back with a PONG, but don't care about the result. */
07143          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07144          return 1;
07145       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07146          /* Ignore */
07147          return 1;
07148       }
07149 
07150       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07151                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07152                          (f.subclass == IAX_COMMAND_REGREL)))
07153          new = NEW_ALLOW;
07154    } else {
07155       /* Don't know anything about it yet */
07156       f.frametype = AST_FRAME_NULL;
07157       f.subclass = 0;
07158    }
07159 
07160    if (!fr->callno) {
07161       int check_dcallno = 0;
07162 
07163       /*
07164        * We enforce accurate destination call numbers for all full frames except
07165        * LAGRQ and PING commands.  This is because older versions of Asterisk
07166        * schedule these commands to get sent very quickly, and they will sometimes
07167        * be sent before they receive the first frame from the other side.  When
07168        * that happens, it doesn't contain the destination call number.  However,
07169        * not checking it for these frames is safe.
07170        * 
07171        * Discussed in the following thread:
07172        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07173        */
07174 
07175       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07176          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07177       }
07178 
07179       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07180    }
07181 
07182    if (fr->callno > 0)
07183       ast_mutex_lock(&iaxsl[fr->callno]);
07184 
07185    if (!fr->callno || !iaxs[fr->callno]) {
07186       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07187          frame, reply with an inval */
07188       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07189          /* We can only raw hangup control frames */
07190          if (((f.subclass != IAX_COMMAND_INVAL) &&
07191              (f.subclass != IAX_COMMAND_TXCNT) &&
07192              (f.subclass != IAX_COMMAND_TXACC) &&
07193              (f.subclass != IAX_COMMAND_FWDOWNL))||
07194              (f.frametype != AST_FRAME_IAX))
07195             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07196             fd);
07197       }
07198       if (fr->callno > 0) 
07199          ast_mutex_unlock(&iaxsl[fr->callno]);
07200       return 1;
07201    }
07202    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07203       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07204          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07205          ast_mutex_unlock(&iaxsl[fr->callno]);
07206          return 1;
07207       }
07208 #ifdef DEBUG_SUPPORT
07209       else if (iaxdebug)
07210          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07211 #endif
07212    }
07213 
07214    /* count this frame */
07215    iaxs[fr->callno]->frames_received++;
07216 
07217    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07218       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07219       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07220       unsigned short new_peercallno;
07221 
07222       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07223       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07224          if (iaxs[fr->callno]->peercallno) {
07225             remove_by_peercallno(iaxs[fr->callno]);
07226          }
07227          iaxs[fr->callno]->peercallno = new_peercallno;
07228          store_by_peercallno(iaxs[fr->callno]);
07229       }
07230    }
07231    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07232       if (option_debug  && iaxdebug)
07233          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07234       /* Check if it's out of order (and not an ACK or INVAL) */
07235       fr->oseqno = fh->oseqno;
07236       fr->iseqno = fh->iseqno;
07237       fr->ts = ntohl(fh->ts);
07238 #ifdef IAXTESTS
07239       if (test_resync) {
07240          if (option_debug)
07241             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07242          fr->ts += test_resync;
07243       }
07244 #endif /* IAXTESTS */
07245 #if 0
07246       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07247            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07248                         (f.subclass == IAX_COMMAND_NEW ||
07249                          f.subclass == IAX_COMMAND_AUTHREQ ||
07250                          f.subclass == IAX_COMMAND_ACCEPT ||
07251                          f.subclass == IAX_COMMAND_REJECT))      ) )
07252 #endif
07253       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07254          updatehistory = 0;
07255       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07256          (iaxs[fr->callno]->iseqno ||
07257             ((f.subclass != IAX_COMMAND_TXCNT) &&
07258             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07259             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07260             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07261             (f.subclass != IAX_COMMAND_TXACC)) ||
07262             (f.frametype != AST_FRAME_IAX))) {
07263          if (
07264           ((f.subclass != IAX_COMMAND_ACK) &&
07265            (f.subclass != IAX_COMMAND_INVAL) &&
07266            (f.subclass != IAX_COMMAND_TXCNT) &&
07267            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07268            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07269            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07270            (f.subclass != IAX_COMMAND_TXACC) &&
07271            (f.subclass != IAX_COMMAND_VNAK)) ||
07272            (f.frametype != AST_FRAME_IAX)) {
07273             /* If it's not an ACK packet, it's out of order. */
07274             if (option_debug)
07275                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07276                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07277             /* Check to see if we need to request retransmission,
07278              * and take sequence number wraparound into account */
07279             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07280                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07281                if ((f.frametype != AST_FRAME_IAX) || 
07282                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07283                   if (option_debug)
07284                      ast_log(LOG_DEBUG, "Acking anyway\n");
07285                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07286                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07287                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07288                }
07289             } else {
07290                /* Send a VNAK requesting retransmission */
07291                iax2_vnak(fr->callno);
07292             }
07293             ast_mutex_unlock(&iaxsl[fr->callno]);
07294             return 1;
07295          }
07296       } else {
07297          /* Increment unless it's an ACK or VNAK */
07298          if (((f.subclass != IAX_COMMAND_ACK) &&
07299              (f.subclass != IAX_COMMAND_INVAL) &&
07300              (f.subclass != IAX_COMMAND_TXCNT) &&
07301              (f.subclass != IAX_COMMAND_TXACC) &&
07302             (f.subclass != IAX_COMMAND_VNAK)) ||
07303              (f.frametype != AST_FRAME_IAX))
07304             iaxs[fr->callno]->iseqno++;
07305       }
07306       /* A full frame */
07307       if (res < sizeof(*fh)) {
07308          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07309          ast_mutex_unlock(&iaxsl[fr->callno]);
07310          return 1;
07311       }
07312       /* Ensure text frames are NULL-terminated */
07313       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07314          if (res < thread->buf_size)
07315             thread->buf[res++] = '\0';
07316          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07317             thread->buf[res - 1] = '\0';
07318       }
07319       f.datalen = res - sizeof(*fh);
07320 
07321       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07322          from the real peer, not the transfer peer */
07323       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07324           ((f.subclass != IAX_COMMAND_INVAL) ||
07325            (f.frametype != AST_FRAME_IAX))) {
07326          unsigned char x;
07327          int call_to_destroy;
07328          /* XXX This code is not very efficient.  Surely there is a better way which still
07329                 properly handles boundary conditions? XXX */
07330          /* First we have to qualify that the ACKed value is within our window */
07331          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07332             if (fr->iseqno == x)
07333                break;
07334          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07335             /* The acknowledgement is within our window.  Time to acknowledge everything
07336                that it says to */
07337             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07338                /* Ack the packet with the given timestamp */
07339                if (option_debug && iaxdebug)
07340                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07341                call_to_destroy = 0;
07342                AST_LIST_LOCK(&iaxq.queue);
07343                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07344                   /* If it's our call, and our timestamp, mark -1 retries */
07345                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07346                      cur->retries = -1;
07347                      /* Destroy call if this is the end */
07348                      if (cur->final)
07349                         call_to_destroy = fr->callno;
07350                   }
07351                }
07352                AST_LIST_UNLOCK(&iaxq.queue);
07353                if (call_to_destroy) {
07354                   if (iaxdebug && option_debug)
07355                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07356                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07357                   iax2_destroy(call_to_destroy);
07358                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07359                }
07360             }
07361             /* Note how much we've received acknowledgement for */
07362             if (iaxs[fr->callno])
07363                iaxs[fr->callno]->rseqno = fr->iseqno;
07364             else {
07365                /* Stop processing now */
07366                ast_mutex_unlock(&iaxsl[fr->callno]);
07367                return 1;
07368             }
07369          } else if (option_debug)
07370             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07371       }
07372       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07373          ((f.frametype != AST_FRAME_IAX) || 
07374           ((f.subclass != IAX_COMMAND_TXACC) &&
07375            (f.subclass != IAX_COMMAND_TXCNT)))) {
07376          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07377          ast_mutex_unlock(&iaxsl[fr->callno]);
07378          return 1;
07379       }
07380 
07381       if (f.datalen) {
07382          if (f.frametype == AST_FRAME_IAX) {
07383             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07384                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07385                ast_mutex_unlock(&iaxsl[fr->callno]);
07386                return 1;
07387             }
07388             f.data = NULL;
07389             f.datalen = 0;
07390          } else
07391             f.data = thread->buf + sizeof(*fh);
07392       } else {
07393          if (f.frametype == AST_FRAME_IAX)
07394             f.data = NULL;
07395          else
07396             f.data = empty;
07397          memset(&ies, 0, sizeof(ies));
07398       }
07399 
07400       /* when we receive the first full frame for a new incoming channel,
07401          it is safe to start the PBX on the channel because we have now
07402          completed a 3-way handshake with the peer */
07403       if ((f.frametype == AST_FRAME_VOICE) ||
07404           (f.frametype == AST_FRAME_VIDEO) ||
07405           (f.frametype == AST_FRAME_IAX)) {
07406          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07407             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07408             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07409                ast_mutex_unlock(&iaxsl[fr->callno]);
07410                return 1;
07411             }
07412          }
07413       }
07414 
07415       if (f.frametype == AST_FRAME_VOICE) {
07416          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07417                iaxs[fr->callno]->voiceformat = f.subclass;
07418                if (option_debug)
07419                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07420                if (iaxs[fr->callno]->owner) {
07421                   int orignative;
07422 retryowner:
07423                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07424                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07425                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07426                   }
07427                   if (iaxs[fr->callno]) {
07428                      if (iaxs[fr->callno]->owner) {
07429                         orignative = iaxs[fr->callno]->owner->nativeformats;
07430                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07431                         if (iaxs[fr->callno]->owner->readformat)
07432                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07433                         iaxs[fr->callno]->owner->nativeformats = orignative;
07434                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07435                      }
07436                   } else {
07437                      if (option_debug)
07438                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07439                      ast_mutex_unlock(&iaxsl[fr->callno]);
07440                      return 1;
07441                   }
07442                }
07443          }
07444       }
07445       if (f.frametype == AST_FRAME_VIDEO) {
07446          if (f.subclass != iaxs[fr->callno]->videoformat) {
07447             if (option_debug)
07448                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07449             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07450          }
07451       }
07452       if (f.frametype == AST_FRAME_IAX) {
07453          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07454          /* Handle the IAX pseudo frame itself */
07455          if (option_debug && iaxdebug)
07456             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07457 
07458                         /* Update last ts unless the frame's timestamp originated with us. */
07459          if (iaxs[fr->callno]->last < fr->ts &&
07460                             f.subclass != IAX_COMMAND_ACK &&
07461                             f.subclass != IAX_COMMAND_PONG &&
07462                             f.subclass != IAX_COMMAND_LAGRP) {
07463             iaxs[fr->callno]->last = fr->ts;
07464             if (option_debug && iaxdebug)
07465                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07466          }
07467 
07468          switch(f.subclass) {
07469          case IAX_COMMAND_ACK:
07470             /* Do nothing */
07471             break;
07472          case IAX_COMMAND_QUELCH:
07473             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07474                     /* Generate Manager Hold event, if necessary*/
07475                if (iaxs[fr->callno]->owner) {
07476                   manager_event(EVENT_FLAG_CALL, "Hold",
07477                      "Channel: %s\r\n"
07478                      "Uniqueid: %s\r\n",
07479                      iaxs[fr->callno]->owner->name, 
07480                      iaxs[fr->callno]->owner->uniqueid);
07481                }
07482 
07483                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07484                if (ies.musiconhold) {
07485                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07486                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07487                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07488                         S_OR(mohsuggest, NULL),
07489                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07490                      if (!iaxs[fr->callno]) {
07491                         ast_mutex_unlock(&iaxsl[fr->callno]);
07492                         return 1;
07493                      }
07494                   }
07495                }
07496             }
07497             break;
07498          case IAX_COMMAND_UNQUELCH:
07499             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07500                     /* Generate Manager Unhold event, if necessary*/
07501                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07502                   manager_event(EVENT_FLAG_CALL, "Unhold",
07503                      "Channel: %s\r\n"
07504                      "Uniqueid: %s\r\n",
07505                      iaxs[fr->callno]->owner->name, 
07506                      iaxs[fr->callno]->owner->uniqueid);
07507                }
07508 
07509                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07510                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07511                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07512                   if (!iaxs[fr->callno]) {
07513                      ast_mutex_unlock(&iaxsl[fr->callno]);
07514                      return 1;
07515                   }
07516                }
07517             }
07518             break;
07519          case IAX_COMMAND_TXACC:
07520             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07521                /* Ack the packet with the given timestamp */
07522                AST_LIST_LOCK(&iaxq.queue);
07523                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07524                   /* Cancel any outstanding txcnt's */
07525                   if ((fr->callno == cur->callno) && (cur->transfer))
07526                      cur->retries = -1;
07527                }
07528                AST_LIST_UNLOCK(&iaxq.queue);
07529                memset(&ied1, 0, sizeof(ied1));
07530                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07531                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07532                iaxs[fr->callno]->transferring = TRANSFER_READY;
07533             }
07534             break;
07535          case IAX_COMMAND_NEW:
07536             /* Ignore if it's already up */
07537             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07538                break;
07539             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07540                ast_mutex_unlock(&iaxsl[fr->callno]);
07541                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07542                ast_mutex_lock(&iaxsl[fr->callno]);
07543                if (!iaxs[fr->callno]) {
07544                   ast_mutex_unlock(&iaxsl[fr->callno]);
07545                   return 1;
07546                }
07547             }
07548             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07549             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07550                int new_callno;
07551                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07552                   fr->callno = new_callno;
07553             }
07554             /* For security, always ack immediately */
07555             if (delayreject)
07556                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07557             if (check_access(fr->callno, &sin, &ies)) {
07558                /* They're not allowed on */
07559                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07560                if (authdebug)
07561                   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);
07562                break;
07563             }
07564             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07565                const char *context, *exten, *cid_num;
07566 
07567                context = ast_strdupa(iaxs[fr->callno]->context);
07568                exten = ast_strdupa(iaxs[fr->callno]->exten);
07569                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07570 
07571                /* This might re-enter the IAX code and need the lock */
07572                ast_mutex_unlock(&iaxsl[fr->callno]);
07573                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07574                ast_mutex_lock(&iaxsl[fr->callno]);
07575 
07576                if (!iaxs[fr->callno]) {
07577                   ast_mutex_unlock(&iaxsl[fr->callno]);
07578                   return 1;
07579                }
07580             } else
07581                exists = 0;
07582             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07583                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07584                   memset(&ied0, 0, sizeof(ied0));
07585                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07586                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07587                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07588                   if (!iaxs[fr->callno]) {
07589                      ast_mutex_unlock(&iaxsl[fr->callno]);
07590                      return 1;
07591                   }
07592                   if (authdebug)
07593                      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);
07594                } else {
07595                   /* Select an appropriate format */
07596 
07597                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07598                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07599                         using_prefs = "reqonly";
07600                      } else {
07601                         using_prefs = "disabled";
07602                      }
07603                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07604                      memset(&pref, 0, sizeof(pref));
07605                      strcpy(caller_pref_buf, "disabled");
07606                      strcpy(host_pref_buf, "disabled");
07607                   } else {
07608                      using_prefs = "mine";
07609                      /* If the information elements are in here... use them */
07610                      if (ies.codec_prefs)
07611                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07612                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07613                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07614                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07615                            pref = iaxs[fr->callno]->rprefs;
07616                            using_prefs = "caller";
07617                         } else {
07618                            pref = iaxs[fr->callno]->prefs;
07619                         }
07620                      } else
07621                         pref = iaxs[fr->callno]->prefs;
07622                      
07623                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07624                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07625                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07626                   }
07627                   if (!format) {
07628                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07629                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07630                      if (!format) {
07631                         memset(&ied0, 0, sizeof(ied0));
07632                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07633                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07634                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07635                         if (!iaxs[fr->callno]) {
07636                            ast_mutex_unlock(&iaxsl[fr->callno]);
07637                            return 1;
07638                         }
07639                         if (authdebug) {
07640                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07641                               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);
07642                            else 
07643                               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);
07644                         }
07645                      } else {
07646                         /* Pick one... */
07647                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07648                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07649                               format = 0;
07650                         } else {
07651                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07652                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07653                               memset(&pref, 0, sizeof(pref));
07654                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07655                               strcpy(caller_pref_buf,"disabled");
07656                               strcpy(host_pref_buf,"disabled");
07657                            } else {
07658                               using_prefs = "mine";
07659                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07660                                  /* Do the opposite of what we tried above. */
07661                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07662                                     pref = iaxs[fr->callno]->prefs;                       
07663                                  } else {
07664                                     pref = iaxs[fr->callno]->rprefs;
07665                                     using_prefs = "caller";
07666                                  }
07667                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07668                            
07669                               } else /* if no codec_prefs IE do it the old way */
07670                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07671                            }
07672                         }
07673 
07674                         if (!format) {
07675                            memset(&ied0, 0, sizeof(ied0));
07676                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07677                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07678                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07679                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07680                            if (!iaxs[fr->callno]) {
07681                               ast_mutex_unlock(&iaxsl[fr->callno]);
07682                               return 1;
07683                            }
07684                            if (authdebug)
07685                               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);
07686                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07687                            break;
07688                         }
07689                      }
07690                   }
07691                   if (format) {
07692                      /* No authentication required, let them in */
07693                      memset(&ied1, 0, sizeof(ied1));
07694                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07695                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07696                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07697                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07698                         if (option_verbose > 2) 
07699                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07700                                     "%srequested format = %s,\n"
07701                                     "%srequested prefs = %s,\n"
07702                                     "%sactual format = %s,\n"
07703                                     "%shost prefs = %s,\n"
07704                                     "%spriority = %s\n",
07705                                     ast_inet_ntoa(sin.sin_addr), 
07706                                     VERBOSE_PREFIX_4,
07707                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07708                                     VERBOSE_PREFIX_4,
07709                                     caller_pref_buf,
07710                                     VERBOSE_PREFIX_4,
07711                                     ast_getformatname(format), 
07712                                     VERBOSE_PREFIX_4,
07713                                     host_pref_buf, 
07714                                     VERBOSE_PREFIX_4,
07715                                     using_prefs);
07716                         
07717                         iaxs[fr->callno]->chosenformat = format;
07718                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07719                      } else {
07720                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07721                         /* If this is a TBD call, we're ready but now what...  */
07722                         if (option_verbose > 2)
07723                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07724                      }
07725                   }
07726                }
07727                break;
07728             }
07729             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07730                merge_encryption(iaxs[fr->callno],ies.encmethods);
07731             else
07732                iaxs[fr->callno]->encmethods = 0;
07733             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07734                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07735             if (!iaxs[fr->callno]) {
07736                ast_mutex_unlock(&iaxsl[fr->callno]);
07737                return 1;
07738             }
07739             break;
07740          case IAX_COMMAND_DPREQ:
07741             /* Request status in the dialplan */
07742             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07743                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07744                if (iaxcompat) {
07745                   /* Spawn a thread for the lookup */
07746                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07747                } else {
07748                   /* Just look it up */
07749                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07750                }
07751             }
07752             break;
07753          case IAX_COMMAND_HANGUP:
07754             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07755             if (option_debug)
07756                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07757             /* Set hangup cause according to remote */
07758             if (ies.causecode && iaxs[fr->callno]->owner)
07759                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07760             /* Send ack immediately, before we destroy */
07761             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07762             iax2_destroy(fr->callno);
07763             break;
07764          case IAX_COMMAND_REJECT:
07765             /* Set hangup cause according to remote */
07766             if (ies.causecode && iaxs[fr->callno]->owner)
07767                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07768 
07769             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07770                if (iaxs[fr->callno]->owner && authdebug)
07771                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07772                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07773                      ies.cause ? ies.cause : "<Unknown>");
07774                if (option_debug)
07775                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07776                      fr->callno);
07777             }
07778             /* Send ack immediately, before we destroy */
07779             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07780                          fr->ts, NULL, 0, fr->iseqno);
07781             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07782                iaxs[fr->callno]->error = EPERM;
07783             iax2_destroy(fr->callno);
07784             break;
07785          case IAX_COMMAND_TRANSFER:
07786          {
07787             struct ast_channel *bridged_chan;
07788 
07789             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07790                /* Set BLINDTRANSFER channel variables */
07791 
07792                ast_mutex_unlock(&iaxsl[fr->callno]);
07793                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07794                ast_mutex_lock(&iaxsl[fr->callno]);
07795                if (!iaxs[fr->callno]) {
07796                   ast_mutex_unlock(&iaxsl[fr->callno]);
07797                   return 1;
07798                }
07799 
07800                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07801                if (!strcmp(ies.called_number, ast_parking_ext())) {
07802                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07803                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07804                   } else {
07805                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07806                   }
07807                } else {
07808                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07809                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07810                         ies.called_number, iaxs[fr->callno]->context);
07811                   else
07812                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07813                         ies.called_number, iaxs[fr->callno]->context);
07814                }
07815             } else
07816                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07817 
07818             break;
07819          }
07820          case IAX_COMMAND_ACCEPT:
07821             /* Ignore if call is already up or needs authentication or is a TBD */
07822             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07823                break;
07824             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07825                /* Send ack immediately, before we destroy */
07826                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07827                iax2_destroy(fr->callno);
07828                break;
07829             }
07830             if (ies.format) {
07831                iaxs[fr->callno]->peerformat = ies.format;
07832             } else {
07833                if (iaxs[fr->callno]->owner)
07834                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07835                else
07836                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07837             }
07838             if (option_verbose > 2)
07839                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));
07840             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07841                memset(&ied0, 0, sizeof(ied0));
07842                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07843                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07844                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07845                if (!iaxs[fr->callno]) {
07846                   ast_mutex_unlock(&iaxsl[fr->callno]);
07847                   return 1;
07848                }
07849                if (authdebug)
07850                   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);
07851             } else {
07852                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07853                if (iaxs[fr->callno]->owner) {
07854                   /* Switch us to use a compatible format */
07855                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07856                   if (option_verbose > 2)
07857                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07858 retryowner2:
07859                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07860                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07861                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07862                   }
07863                   
07864                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07865                      /* Setup read/write formats properly. */
07866                      if (iaxs[fr->callno]->owner->writeformat)
07867                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07868                      if (iaxs[fr->callno]->owner->readformat)
07869                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07870                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07871                   }
07872                }
07873             }
07874             if (iaxs[fr->callno]) {
07875                ast_mutex_lock(&dpcache_lock);
07876                dp = iaxs[fr->callno]->dpentries;
07877                while(dp) {
07878                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07879                      iax2_dprequest(dp, fr->callno);
07880                   }
07881                   dp = dp->peer;
07882                }
07883                ast_mutex_unlock(&dpcache_lock);
07884             }
07885             break;
07886          case IAX_COMMAND_POKE:
07887             /* Send back a pong packet with the original timestamp */
07888             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07889             if (!iaxs[fr->callno]) {
07890                ast_mutex_unlock(&iaxsl[fr->callno]);
07891                return 1;
07892             }
07893             break;
07894          case IAX_COMMAND_PING:
07895          {
07896             struct iax_ie_data pingied;
07897             construct_rr(iaxs[fr->callno], &pingied);
07898             /* Send back a pong packet with the original timestamp */
07899             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07900          }
07901             break;
07902          case IAX_COMMAND_PONG:
07903             /* Calculate ping time */
07904             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07905             /* save RR info */
07906             save_rr(fr, &ies);
07907 
07908             if (iaxs[fr->callno]->peerpoke) {
07909                peer = iaxs[fr->callno]->peerpoke;
07910                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07911                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07912                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07913                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07914                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07915                   }
07916                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07917                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07918                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07919                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07920                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07921                   }
07922                }
07923                peer->lastms = iaxs[fr->callno]->pingtime;
07924                if (peer->smoothing && (peer->lastms > -1))
07925                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07926                else if (peer->smoothing && peer->lastms < 0)
07927                   peer->historicms = (0 + peer->historicms) / 2;
07928                else              
07929                   peer->historicms = iaxs[fr->callno]->pingtime;
07930 
07931                /* Remove scheduled iax2_poke_noanswer */
07932                if (peer->pokeexpire > -1) {
07933                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07934                      peer_unref(peer);
07935                      peer->pokeexpire = -1;
07936                   }
07937                }
07938                /* Schedule the next cycle */
07939                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07940                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07941                else
07942                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07943                if (peer->pokeexpire == -1)
07944                   peer_unref(peer);
07945                /* and finally send the ack */
07946                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07947                /* And wrap up the qualify call */
07948                iax2_destroy(fr->callno);
07949                peer->callno = 0;
07950                if (option_debug)
07951                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07952             }
07953             break;
07954          case IAX_COMMAND_LAGRQ:
07955          case IAX_COMMAND_LAGRP:
07956             f.src = "LAGRQ";
07957             f.mallocd = 0;
07958             f.offset = 0;
07959             f.samples = 0;
07960             iax_frame_wrap(fr, &f);
07961             if(f.subclass == IAX_COMMAND_LAGRQ) {
07962                /* Received a LAGRQ - echo back a LAGRP */
07963                fr->af.subclass = IAX_COMMAND_LAGRP;
07964                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07965             } else {
07966                /* Received LAGRP in response to our LAGRQ */
07967                unsigned int ts;
07968                /* This is a reply we've been given, actually measure the difference */
07969                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07970                iaxs[fr->callno]->lag = ts - fr->ts;
07971                if (option_debug && iaxdebug)
07972                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07973                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07974             }
07975             break;
07976          case IAX_COMMAND_AUTHREQ:
07977             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07978                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>");
07979                break;
07980             }
07981             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07982                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
07983                         .subclass = AST_CONTROL_HANGUP,
07984                };
07985                ast_log(LOG_WARNING, 
07986                   "I don't know how to authenticate %s to %s\n", 
07987                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07988                iax2_queue_frame(fr->callno, &hangup_fr);
07989             }
07990             if (!iaxs[fr->callno]) {
07991                ast_mutex_unlock(&iaxsl[fr->callno]);
07992                return 1;
07993             }
07994             break;
07995          case IAX_COMMAND_AUTHREP:
07996             /* For security, always ack immediately */
07997             if (delayreject)
07998                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07999             /* Ignore once we've started */
08000             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08001                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>");
08002                break;
08003             }
08004             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08005                if (authdebug)
08006                   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);
08007                memset(&ied0, 0, sizeof(ied0));
08008                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08009                break;
08010             }
08011             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08012                /* This might re-enter the IAX code and need the lock */
08013                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08014             } else
08015                exists = 0;
08016             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08017                if (authdebug)
08018                   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);
08019                memset(&ied0, 0, sizeof(ied0));
08020                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08021                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08022                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08023                if (!iaxs[fr->callno]) {
08024                   ast_mutex_unlock(&iaxsl[fr->callno]);
08025                   return 1;
08026                }
08027             } else {
08028                /* Select an appropriate format */
08029                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08030                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08031                      using_prefs = "reqonly";
08032                   } else {
08033                      using_prefs = "disabled";
08034                   }
08035                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08036                   memset(&pref, 0, sizeof(pref));
08037                   strcpy(caller_pref_buf, "disabled");
08038                   strcpy(host_pref_buf, "disabled");
08039                } else {
08040                   using_prefs = "mine";
08041                   if (ies.codec_prefs)
08042                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08043                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08044                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08045                         pref = iaxs[fr->callno]->rprefs;
08046                         using_prefs = "caller";
08047                      } else {
08048                         pref = iaxs[fr->callno]->prefs;
08049                      }
08050                   } else /* if no codec_prefs IE do it the old way */
08051                      pref = iaxs[fr->callno]->prefs;
08052                
08053                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08054                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08055                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08056                }
08057                if (!format) {
08058                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08059                      if (option_debug)
08060                         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);
08061                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08062                   }
08063                   if (!format) {
08064                      if (authdebug) {
08065                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08066                            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);
08067                         else
08068                            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);
08069                      }
08070                      memset(&ied0, 0, sizeof(ied0));
08071                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08072                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08073                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08074                      if (!iaxs[fr->callno]) {
08075                         ast_mutex_unlock(&iaxsl[fr->callno]);
08076                         return 1;
08077                      }
08078                   } else {
08079                      /* Pick one... */
08080                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08081                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08082                            format = 0;
08083                      } else {
08084                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08085                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08086                            memset(&pref, 0, sizeof(pref));
08087                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08088                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08089                            strcpy(caller_pref_buf,"disabled");
08090                            strcpy(host_pref_buf,"disabled");
08091                         } else {
08092                            using_prefs = "mine";
08093                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08094                               /* Do the opposite of what we tried above. */
08095                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08096                                  pref = iaxs[fr->callno]->prefs;                 
08097                               } else {
08098                                  pref = iaxs[fr->callno]->rprefs;
08099                                  using_prefs = "caller";
08100                               }
08101                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08102                            } else /* if no codec_prefs IE do it the old way */
08103                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08104                         }
08105                      }
08106                      if (!format) {
08107                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08108                         if (authdebug) {
08109                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08110                               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);
08111                            else
08112                               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);
08113                         }
08114                         memset(&ied0, 0, sizeof(ied0));
08115                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08116                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08117                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08118                         if (!iaxs[fr->callno]) {
08119                            ast_mutex_unlock(&iaxsl[fr->callno]);
08120                            return 1;
08121                         }
08122                      }
08123                   }
08124                }
08125                if (format) {
08126                   /* Authentication received */
08127                   memset(&ied1, 0, sizeof(ied1));
08128                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08129                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08130                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08131                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08132                      if (option_verbose > 2) 
08133                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08134                                  "%srequested format = %s,\n"
08135                                  "%srequested prefs = %s,\n"
08136                                  "%sactual format = %s,\n"
08137                                  "%shost prefs = %s,\n"
08138                                  "%spriority = %s\n", 
08139                                  ast_inet_ntoa(sin.sin_addr), 
08140                                  VERBOSE_PREFIX_4,
08141                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08142                                  VERBOSE_PREFIX_4,
08143                                  caller_pref_buf,
08144                                  VERBOSE_PREFIX_4,
08145                                  ast_getformatname(format),
08146                                  VERBOSE_PREFIX_4,
08147                                  host_pref_buf,
08148                                  VERBOSE_PREFIX_4,
08149                                  using_prefs);
08150 
08151                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08152                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08153                         iax2_destroy(fr->callno);
08154                   } else {
08155                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08156                      /* If this is a TBD call, we're ready but now what...  */
08157                      if (option_verbose > 2)
08158                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08159                   }
08160                }
08161             }
08162             break;
08163          case IAX_COMMAND_DIAL:
08164             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08165                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08166                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08167                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08168                   if (authdebug)
08169                      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);
08170                   memset(&ied0, 0, sizeof(ied0));
08171                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08172                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08173                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08174                   if (!iaxs[fr->callno]) {
08175                      ast_mutex_unlock(&iaxsl[fr->callno]);
08176                      return 1;
08177                   }
08178                } else {
08179                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08180                   if (option_verbose > 2) 
08181                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08182                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08183                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08184                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08185                      iax2_destroy(fr->callno);
08186                }
08187             }
08188             break;
08189          case IAX_COMMAND_INVAL:
08190             iaxs[fr->callno]->error = ENOTCONN;
08191             if (option_debug)
08192                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08193             iax2_destroy(fr->callno);
08194             if (option_debug)
08195                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08196             break;
08197          case IAX_COMMAND_VNAK:
08198             if (option_debug)
08199                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08200             /* Force retransmission */
08201             vnak_retransmit(fr->callno, fr->iseqno);
08202             break;
08203          case IAX_COMMAND_REGREQ:
08204          case IAX_COMMAND_REGREL:
08205             /* For security, always ack immediately */
08206             if (delayreject)
08207                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08208             if (register_verify(fr->callno, &sin, &ies)) {
08209                if (!iaxs[fr->callno]) {
08210                   ast_mutex_unlock(&iaxsl[fr->callno]);
08211                   return 1;
08212                }
08213                /* Send delayed failure */
08214                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08215                break;
08216             }
08217             if (!iaxs[fr->callno]) {
08218                ast_mutex_unlock(&iaxsl[fr->callno]);
08219                return 1;
08220             }
08221             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08222                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08223                if (f.subclass == IAX_COMMAND_REGREL)
08224                   memset(&sin, 0, sizeof(sin));
08225                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08226                   ast_log(LOG_WARNING, "Registry error\n");
08227                if (!iaxs[fr->callno]) {
08228                   ast_mutex_unlock(&iaxsl[fr->callno]);
08229                   return 1;
08230                }
08231                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08232                   ast_mutex_unlock(&iaxsl[fr->callno]);
08233                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08234                   ast_mutex_lock(&iaxsl[fr->callno]);
08235                   if (!iaxs[fr->callno]) {
08236                      ast_mutex_unlock(&iaxsl[fr->callno]);
08237                      return 1;
08238                   }
08239                }
08240                break;
08241             }
08242             registry_authrequest(fr->callno);
08243             if (!iaxs[fr->callno]) {
08244                ast_mutex_unlock(&iaxsl[fr->callno]);
08245                return 1;
08246             }
08247             break;
08248          case IAX_COMMAND_REGACK:
08249             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08250                ast_log(LOG_WARNING, "Registration failure\n");
08251             /* Send ack immediately, before we destroy */
08252             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08253             iax2_destroy(fr->callno);
08254             break;
08255          case IAX_COMMAND_REGREJ:
08256             if (iaxs[fr->callno]->reg) {
08257                if (authdebug) {
08258                   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));
08259                   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>");
08260                }
08261                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08262             }
08263             /* Send ack immediately, before we destroy */
08264             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08265             iax2_destroy(fr->callno);
08266             break;
08267          case IAX_COMMAND_REGAUTH:
08268             /* Authentication request */
08269             if (registry_rerequest(&ies, fr->callno, &sin)) {
08270                memset(&ied0, 0, sizeof(ied0));
08271                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08272                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08273                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08274                if (!iaxs[fr->callno]) {
08275                   ast_mutex_unlock(&iaxsl[fr->callno]);
08276                   return 1;
08277                }
08278             }
08279             break;
08280          case IAX_COMMAND_TXREJ:
08281             iaxs[fr->callno]->transferring = 0;
08282             if (option_verbose > 2) 
08283                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08284             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08285             if (iaxs[fr->callno]->bridgecallno) {
08286                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08287                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08288                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08289                }
08290             }
08291             break;
08292          case IAX_COMMAND_TXREADY:
08293             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08294                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08295                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08296                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08297                else
08298                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08299                if (option_verbose > 2) 
08300                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08301                if (iaxs[fr->callno]->bridgecallno) {
08302                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08303                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08304                      /* They're both ready, now release them. */
08305                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08306                         if (option_verbose > 2) 
08307                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08308                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08309 
08310                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08311                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08312 
08313                         memset(&ied0, 0, sizeof(ied0));
08314                         memset(&ied1, 0, sizeof(ied1));
08315                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08316                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08317                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08318                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08319                      } else {
08320                         if (option_verbose > 2) 
08321                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08322                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08323 
08324                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08325                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08326                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08327                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08328 
08329                         /* Stop doing lag & ping requests */
08330                         stop_stuff(fr->callno);
08331                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08332 
08333                         memset(&ied0, 0, sizeof(ied0));
08334                         memset(&ied1, 0, sizeof(ied1));
08335                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08336                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08337                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08338                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08339                      }
08340 
08341                   }
08342                }
08343             }
08344             break;
08345          case IAX_COMMAND_TXREQ:
08346             try_transfer(iaxs[fr->callno], &ies);
08347             break;
08348          case IAX_COMMAND_TXCNT:
08349             if (iaxs[fr->callno]->transferring)
08350                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08351             break;
08352          case IAX_COMMAND_TXREL:
08353             /* Send ack immediately, rather than waiting until we've changed addresses */
08354             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08355             complete_transfer(fr->callno, &ies);
08356             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08357             break;   
08358          case IAX_COMMAND_TXMEDIA:
08359             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08360                                         AST_LIST_LOCK(&iaxq.queue);
08361                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08362                                                 /* Cancel any outstanding frames and start anew */
08363                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08364                                                         cur->retries = -1;
08365                                                 }
08366                                         }
08367                                         AST_LIST_UNLOCK(&iaxq.queue);
08368                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08369                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08370             }
08371             break;   
08372          case IAX_COMMAND_DPREP:
08373             complete_dpreply(iaxs[fr->callno], &ies);
08374             break;
08375          case IAX_COMMAND_UNSUPPORT:
08376             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08377             break;
08378          case IAX_COMMAND_FWDOWNL:
08379             /* Firmware download */
08380             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08381                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08382                break;
08383             }
08384             memset(&ied0, 0, sizeof(ied0));
08385             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08386             if (res < 0)
08387                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08388             else if (res > 0)
08389                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08390             else
08391                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08392             if (!iaxs[fr->callno]) {
08393                ast_mutex_unlock(&iaxsl[fr->callno]);
08394                return 1;
08395             }
08396             break;
08397          default:
08398             if (option_debug)
08399                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08400             memset(&ied0, 0, sizeof(ied0));
08401             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08402             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08403          }
08404          /* Don't actually pass these frames along */
08405          if ((f.subclass != IAX_COMMAND_ACK) && 
08406            (f.subclass != IAX_COMMAND_TXCNT) && 
08407            (f.subclass != IAX_COMMAND_TXACC) && 
08408            (f.subclass != IAX_COMMAND_INVAL) &&
08409            (f.subclass != IAX_COMMAND_VNAK)) { 
08410             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08411                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08412          }
08413          ast_mutex_unlock(&iaxsl[fr->callno]);
08414          return 1;
08415       }
08416       /* Unless this is an ACK or INVAL frame, ack it */
08417       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08418          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08419    } else if (minivid) {
08420       f.frametype = AST_FRAME_VIDEO;
08421       if (iaxs[fr->callno]->videoformat > 0) 
08422          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08423       else {
08424          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08425          iax2_vnak(fr->callno);
08426          ast_mutex_unlock(&iaxsl[fr->callno]);
08427          return 1;
08428       }
08429       f.datalen = res - sizeof(*vh);
08430       if (f.datalen)
08431          f.data = thread->buf + sizeof(*vh);
08432       else
08433          f.data = NULL;
08434 #ifdef IAXTESTS
08435       if (test_resync) {
08436          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08437       } else
08438 #endif /* IAXTESTS */
08439          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08440    } else {
08441       /* A mini frame */
08442       f.frametype = AST_FRAME_VOICE;
08443       if (iaxs[fr->callno]->voiceformat > 0)
08444          f.subclass = iaxs[fr->callno]->voiceformat;
08445       else {
08446          if (option_debug)
08447             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08448          iax2_vnak(fr->callno);
08449          ast_mutex_unlock(&iaxsl[fr->callno]);
08450          return 1;
08451       }
08452       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08453       if (f.datalen < 0) {
08454          ast_log(LOG_WARNING, "Datalen < 0?\n");
08455          ast_mutex_unlock(&iaxsl[fr->callno]);
08456          return 1;
08457       }
08458       if (f.datalen)
08459          f.data = thread->buf + sizeof(*mh);
08460       else
08461          f.data = NULL;
08462 #ifdef IAXTESTS
08463       if (test_resync) {
08464          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08465       } else
08466 #endif /* IAXTESTS */
08467       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08468       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08469    }
08470    /* Don't pass any packets until we're started */
08471    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08472       ast_mutex_unlock(&iaxsl[fr->callno]);
08473       return 1;
08474    }
08475    /* Common things */
08476    f.src = "IAX2";
08477    f.mallocd = 0;
08478    f.offset = 0;
08479    f.len = 0;
08480    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08481       f.samples = ast_codec_get_samples(&f);
08482       /* We need to byteswap incoming slinear samples from network byte order */
08483       if (f.subclass == AST_FORMAT_SLINEAR)
08484          ast_frame_byteswap_be(&f);
08485    } else
08486       f.samples = 0;
08487    iax_frame_wrap(fr, &f);
08488 
08489    /* If this is our most recent packet, use it as our basis for timestamping */
08490    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08491       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08492       fr->outoforder = 0;
08493    } else {
08494       if (option_debug && iaxdebug && iaxs[fr->callno])
08495          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);
08496       fr->outoforder = -1;
08497    }
08498    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08499    duped_fr = iaxfrdup2(fr);
08500    if (duped_fr) {
08501       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08502    }
08503    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08504       iaxs[fr->callno]->last = fr->ts;
08505 #if 1
08506       if (option_debug && iaxdebug)
08507          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08508 #endif
08509    }
08510 
08511    /* Always run again */
08512    ast_mutex_unlock(&iaxsl[fr->callno]);
08513    return 1;
08514 }
08515 
08516 /* Function to clean up process thread if it is cancelled */
08517 static void iax2_process_thread_cleanup(void *data)
08518 {
08519    struct iax2_thread *thread = data;
08520    ast_mutex_destroy(&thread->lock);
08521    ast_cond_destroy(&thread->cond);
08522    free(thread);
08523    ast_atomic_dec_and_test(&iaxactivethreadcount);
08524 }
08525 
08526 static void *iax2_process_thread(void *data)
08527 {
08528    struct iax2_thread *thread = data;
08529    struct timeval tv;
08530    struct timespec ts;
08531    int put_into_idle = 0;
08532 
08533    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08534    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08535    for(;;) {
08536       /* Wait for something to signal us to be awake */
08537       ast_mutex_lock(&thread->lock);
08538 
08539       /* Flag that we're ready to accept signals */
08540       thread->ready_for_signal = 1;
08541       
08542       /* Put into idle list if applicable */
08543       if (put_into_idle)
08544          insert_idle_thread(thread);
08545 
08546       if (thread->type == IAX_TYPE_DYNAMIC) {
08547          struct iax2_thread *t = NULL;
08548          /* Wait to be signalled or time out */
08549          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08550          ts.tv_sec = tv.tv_sec;
08551          ts.tv_nsec = tv.tv_usec * 1000;
08552          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08553             /* This thread was never put back into the available dynamic
08554              * thread list, so just go away. */
08555             if (!put_into_idle) {
08556                ast_mutex_unlock(&thread->lock);
08557                break;
08558             }
08559             AST_LIST_LOCK(&dynamic_list);
08560             /* Account for the case where this thread is acquired *right* after a timeout */
08561             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08562                iaxdynamicthreadcount--;
08563             AST_LIST_UNLOCK(&dynamic_list);
08564             if (t) {
08565                /* This dynamic thread timed out waiting for a task and was
08566                 * not acquired immediately after the timeout, 
08567                 * so it's time to go away. */
08568                ast_mutex_unlock(&thread->lock);
08569                break;
08570             }
08571             /* Someone grabbed our thread *right* after we timed out.
08572              * Wait for them to set us up with something to do and signal
08573              * us to continue. */
08574             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08575             ts.tv_sec = tv.tv_sec;
08576             ts.tv_nsec = tv.tv_usec * 1000;
08577             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08578             {
08579                ast_mutex_unlock(&thread->lock);
08580                break;
08581             }
08582          }
08583       } else {
08584          ast_cond_wait(&thread->cond, &thread->lock);
08585       }
08586 
08587       /* Go back into our respective list */
08588       put_into_idle = 1;
08589 
08590       ast_mutex_unlock(&thread->lock);
08591 
08592       if (thread->iostate == IAX_IOSTATE_IDLE)
08593          continue;
08594 
08595       /* Add ourselves to the active list now */
08596       AST_LIST_LOCK(&active_list);
08597       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08598       AST_LIST_UNLOCK(&active_list);
08599 
08600       /* See what we need to do */
08601       switch(thread->iostate) {
08602       case IAX_IOSTATE_READY:
08603          thread->actions++;
08604          thread->iostate = IAX_IOSTATE_PROCESSING;
08605          socket_process(thread);
08606          handle_deferred_full_frames(thread);
08607          break;
08608       case IAX_IOSTATE_SCHEDREADY:
08609          thread->actions++;
08610          thread->iostate = IAX_IOSTATE_PROCESSING;
08611 #ifdef SCHED_MULTITHREADED
08612          thread->schedfunc(thread->scheddata);
08613 #endif      
08614          break;
08615       }
08616       time(&thread->checktime);
08617       thread->iostate = IAX_IOSTATE_IDLE;
08618 #ifdef DEBUG_SCHED_MULTITHREAD
08619       thread->curfunc[0]='\0';
08620 #endif      
08621 
08622       /* Now... remove ourselves from the active list, and return to the idle list */
08623       AST_LIST_LOCK(&active_list);
08624       AST_LIST_REMOVE(&active_list, thread, list);
08625       AST_LIST_UNLOCK(&active_list);
08626 
08627       /* Make sure another frame didn't sneak in there after we thought we were done. */
08628       handle_deferred_full_frames(thread);
08629    }
08630 
08631    /*!\note For some reason, idle threads are exiting without being removed
08632     * from an idle list, which is causing memory corruption.  Forcibly remove
08633     * it from the list, if it's there.
08634     */
08635    AST_LIST_LOCK(&idle_list);
08636    AST_LIST_REMOVE(&idle_list, thread, list);
08637    AST_LIST_UNLOCK(&idle_list);
08638 
08639    AST_LIST_LOCK(&dynamic_list);
08640    AST_LIST_REMOVE(&dynamic_list, thread, list);
08641    AST_LIST_UNLOCK(&dynamic_list);
08642 
08643    /* I am exiting here on my own volition, I need to clean up my own data structures
08644    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08645    */
08646    pthread_cleanup_pop(1);
08647 
08648    return NULL;
08649 }
08650 
08651 static int iax2_do_register(struct iax2_registry *reg)
08652 {
08653    struct iax_ie_data ied;
08654    if (option_debug && iaxdebug)
08655       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08656 
08657    if (reg->dnsmgr && 
08658        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08659       /* Maybe the IP has changed, force DNS refresh */
08660       ast_dnsmgr_refresh(reg->dnsmgr);
08661    }
08662    
08663    /*
08664     * if IP has Changed, free allocated call to create a new one with new IP
08665     * call has the pointer to IP and must be updated to the new one
08666     */
08667    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08668       ast_mutex_lock(&iaxsl[reg->callno]);
08669       iax2_destroy(reg->callno);
08670       ast_mutex_unlock(&iaxsl[reg->callno]);
08671       reg->callno = 0;
08672    }
08673    if (!reg->addr.sin_addr.s_addr) {
08674       if (option_debug && iaxdebug)
08675          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08676       /* Setup the next registration attempt */
08677       AST_SCHED_DEL(sched, reg->expire);
08678       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08679       return -1;
08680    }
08681 
08682    if (!reg->callno) {
08683       if (option_debug)
08684          ast_log(LOG_DEBUG, "Allocate call number\n");
08685       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08686       if (reg->callno < 1) {
08687          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08688          return -1;
08689       } else if (option_debug)
08690          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08691       iaxs[reg->callno]->reg = reg;
08692       ast_mutex_unlock(&iaxsl[reg->callno]);
08693    }
08694    /* Schedule the next registration attempt */
08695    AST_SCHED_DEL(sched, reg->expire);
08696    /* Setup the next registration a little early */
08697    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08698    /* Send the request */
08699    memset(&ied, 0, sizeof(ied));
08700    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08701    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08702    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08703    reg->regstate = REG_STATE_REGSENT;
08704    return 0;
08705 }
08706 
08707 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08708 {
08709    if (pos != 3)
08710       return NULL;
08711    return iax_prov_complete_template(line, word, pos, state);
08712 }
08713 
08714 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08715 {
08716    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08717       is found for template */
08718    struct iax_ie_data provdata;
08719    struct iax_ie_data ied;
08720    unsigned int sig;
08721    struct sockaddr_in sin;
08722    int callno;
08723    struct create_addr_info cai;
08724 
08725    memset(&cai, 0, sizeof(cai));
08726 
08727    if (option_debug)
08728       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08729 
08730    if (iax_provision_build(&provdata, &sig, template, force)) {
08731       if (option_debug)
08732          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08733       return 0;
08734    }
08735 
08736    if (end) {
08737       memcpy(&sin, end, sizeof(sin));
08738       cai.sockfd = sockfd;
08739    } else if (create_addr(dest, NULL, &sin, &cai))
08740       return -1;
08741 
08742    /* Build the rest of the message */
08743    memset(&ied, 0, sizeof(ied));
08744    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08745 
08746    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08747    if (!callno)
08748       return -1;
08749 
08750    if (iaxs[callno]) {
08751       /* Schedule autodestruct in case they don't ever give us anything back */
08752       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08753       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08754       ast_set_flag(iaxs[callno], IAX_PROVISION);
08755       /* Got a call number now, so go ahead and send the provisioning information */
08756       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08757    }
08758    ast_mutex_unlock(&iaxsl[callno]);
08759 
08760    return 1;
08761 }
08762 
08763 static char *papp = "IAX2Provision";
08764 static char *psyn = "Provision a calling IAXy with a given template";
08765 static char *pdescrip = 
08766 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08767 "the calling entity is in fact an IAXy) with the given template or\n"
08768 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08769 
08770 /*! iax2provision
08771 \ingroup applications
08772 */
08773 static int iax2_prov_app(struct ast_channel *chan, void *data)
08774 {
08775    int res;
08776    char *sdata;
08777    char *opts;
08778    int force =0;
08779    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08780    if (ast_strlen_zero(data))
08781       data = "default";
08782    sdata = ast_strdupa(data);
08783    opts = strchr(sdata, '|');
08784    if (opts)
08785       *opts='\0';
08786 
08787    if (chan->tech != &iax2_tech) {
08788       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08789       return -1;
08790    } 
08791    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08792       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08793       return -1;
08794    }
08795    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08796    if (option_verbose > 2)
08797       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08798       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08799       sdata, res);
08800    return res;
08801 }
08802 
08803 
08804 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08805 {
08806    int force = 0;
08807    int res;
08808    if (argc < 4)
08809       return RESULT_SHOWUSAGE;
08810    if ((argc > 4)) {
08811       if (!strcasecmp(argv[4], "forced"))
08812          force = 1;
08813       else
08814          return RESULT_SHOWUSAGE;
08815    }
08816    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08817    if (res < 0)
08818       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08819    else if (res < 1)
08820       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08821    else
08822       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08823    return RESULT_SUCCESS;
08824 }
08825 
08826 static void __iax2_poke_noanswer(const void *data)
08827 {
08828    struct iax2_peer *peer = (struct iax2_peer *)data;
08829    int callno;
08830 
08831    if (peer->lastms > -1) {
08832       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08833       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08834       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08835    }
08836    if ((callno = peer->callno) > 0) {
08837       ast_mutex_lock(&iaxsl[callno]);
08838       iax2_destroy(callno);
08839       ast_mutex_unlock(&iaxsl[callno]);
08840    }
08841    peer->callno = 0;
08842    peer->lastms = -1;
08843    /* Try again quickly */
08844    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08845    if (peer->pokeexpire == -1)
08846       peer_unref(peer);
08847 }
08848 
08849 static int iax2_poke_noanswer(const void *data)
08850 {
08851    struct iax2_peer *peer = (struct iax2_peer *)data;
08852    peer->pokeexpire = -1;
08853 #ifdef SCHED_MULTITHREADED
08854    if (schedule_action(__iax2_poke_noanswer, data))
08855 #endif      
08856       __iax2_poke_noanswer(data);
08857    peer_unref(peer);
08858    return 0;
08859 }
08860 
08861 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08862 {
08863    struct iax2_peer *peer = obj;
08864 
08865    iax2_poke_peer(peer, 0);
08866 
08867    return 0;
08868 }
08869 
08870 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08871 {
08872    int callno;
08873    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08874       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08875         immediately after clearing things out */
08876       peer->lastms = 0;
08877       peer->historicms = 0;
08878       peer->pokeexpire = -1;
08879       peer->callno = 0;
08880       return 0;
08881    }
08882 
08883    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
08884    if ((callno = peer->callno) > 0) {
08885       ast_log(LOG_NOTICE, "Still have a callno...\n");
08886       ast_mutex_lock(&iaxsl[callno]);
08887       iax2_destroy(callno);
08888       ast_mutex_unlock(&iaxsl[callno]);
08889    }
08890    if (heldcall)
08891       ast_mutex_unlock(&iaxsl[heldcall]);
08892    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08893    if (heldcall)
08894       ast_mutex_lock(&iaxsl[heldcall]);
08895    if (peer->callno < 1) {
08896       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08897       return -1;
08898    }
08899 
08900    /* Speed up retransmission times for this qualify call */
08901    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08902    iaxs[peer->callno]->peerpoke = peer;
08903    
08904    /* Remove any pending pokeexpire task */
08905    if (peer->pokeexpire > -1) {
08906       if (!ast_sched_del(sched, peer->pokeexpire)) {
08907          peer->pokeexpire = -1;
08908          peer_unref(peer);
08909       }
08910    }
08911 
08912    /* Queue up a new task to handle no reply */
08913    /* If the host is already unreachable then use the unreachable interval instead */
08914    if (peer->lastms < 0) {
08915       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08916    } else
08917       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08918 
08919    if (peer->pokeexpire == -1)
08920       peer_unref(peer);
08921 
08922    /* And send the poke */
08923    ast_mutex_lock(&iaxsl[callno]);
08924    if (iaxs[callno]) {
08925       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08926    }
08927    ast_mutex_unlock(&iaxsl[callno]);
08928 
08929    return 0;
08930 }
08931 
08932 static void free_context(struct iax2_context *con)
08933 {
08934    struct iax2_context *conl;
08935    while(con) {
08936       conl = con;
08937       con = con->next;
08938       free(conl);
08939    }
08940 }
08941 
08942 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08943 {
08944    int callno;
08945    int res;
08946    int fmt, native;
08947    struct sockaddr_in sin;
08948    struct ast_channel *c;
08949    struct parsed_dial_string pds;
08950    struct create_addr_info cai;
08951    char *tmpstr;
08952 
08953    memset(&pds, 0, sizeof(pds));
08954    tmpstr = ast_strdupa(data);
08955    parse_dial_string(tmpstr, &pds);
08956 
08957    if (ast_strlen_zero(pds.peer)) {
08958       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
08959       return NULL;
08960    }
08961           
08962    memset(&cai, 0, sizeof(cai));
08963    cai.capability = iax2_capability;
08964 
08965    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08966    
08967    /* Populate our address from the given */
08968    if (create_addr(pds.peer, NULL, &sin, &cai)) {
08969       *cause = AST_CAUSE_UNREGISTERED;
08970       return NULL;
08971    }
08972 
08973    if (pds.port)
08974       sin.sin_port = htons(atoi(pds.port));
08975 
08976    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08977    if (callno < 1) {
08978       ast_log(LOG_WARNING, "Unable to create call\n");
08979       *cause = AST_CAUSE_CONGESTION;
08980       return NULL;
08981    }
08982 
08983    /* If this is a trunk, update it now */
08984    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08985    if (ast_test_flag(&cai, IAX_TRUNK)) {
08986       int new_callno;
08987       if ((new_callno = make_trunk(callno, 1)) != -1)
08988          callno = new_callno;
08989    }
08990    iaxs[callno]->maxtime = cai.maxtime;
08991    if (cai.found)
08992       ast_string_field_set(iaxs[callno], host, pds.peer);
08993 
08994    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08995 
08996    ast_mutex_unlock(&iaxsl[callno]);
08997 
08998    if (c) {
08999       /* Choose a format we can live with */
09000       if (c->nativeformats & format) 
09001          c->nativeformats &= format;
09002       else {
09003          native = c->nativeformats;
09004          fmt = format;
09005          res = ast_translator_best_choice(&fmt, &native);
09006          if (res < 0) {
09007             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09008                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09009             ast_hangup(c);
09010             return NULL;
09011          }
09012          c->nativeformats = native;
09013       }
09014       c->readformat = ast_best_codec(c->nativeformats);
09015       c->writeformat = c->readformat;
09016    }
09017 
09018    return c;
09019 }
09020 
09021 static void *sched_thread(void *ignore)
09022 {
09023    int count;
09024    int res;
09025    struct timeval tv;
09026    struct timespec ts;
09027 
09028    for (;;) {
09029       res = ast_sched_wait(sched);
09030       if ((res > 1000) || (res < 0))
09031          res = 1000;
09032       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09033       ts.tv_sec = tv.tv_sec;
09034       ts.tv_nsec = tv.tv_usec * 1000;
09035 
09036       pthread_testcancel();
09037       ast_mutex_lock(&sched_lock);
09038       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09039       ast_mutex_unlock(&sched_lock);
09040       pthread_testcancel();
09041 
09042       count = ast_sched_runq(sched);
09043       if (option_debug && count >= 20)
09044          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09045    }
09046    return NULL;
09047 }
09048 
09049 static void *network_thread(void *ignore)
09050 {
09051    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09052       from the network, and queue them for delivery to the channels */
09053    int res, count, wakeup;
09054    struct iax_frame *f;
09055 
09056    if (timingfd > -1)
09057       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09058    
09059    for(;;) {
09060       pthread_testcancel();
09061 
09062       /* Go through the queue, sending messages which have not yet been
09063          sent, and scheduling retransmissions if appropriate */
09064       AST_LIST_LOCK(&iaxq.queue);
09065       count = 0;
09066       wakeup = -1;
09067       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09068          if (f->sentyet)
09069             continue;
09070          
09071          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09072          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09073             wakeup = 1;
09074             continue;
09075          }
09076 
09077          f->sentyet++;
09078 
09079          if (iaxs[f->callno]) {
09080             send_packet(f);
09081             count++;
09082          } 
09083 
09084          ast_mutex_unlock(&iaxsl[f->callno]);
09085 
09086          if (f->retries < 0) {
09087             /* This is not supposed to be retransmitted */
09088             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09089             iaxq.count--;
09090             /* Free the iax frame */
09091             iax_frame_free(f);
09092          } else {
09093             /* We need reliable delivery.  Schedule a retransmission */
09094             f->retries++;
09095             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09096          }
09097       }
09098       AST_LIST_TRAVERSE_SAFE_END
09099       AST_LIST_UNLOCK(&iaxq.queue);
09100 
09101       pthread_testcancel();
09102 
09103       if (option_debug && count >= 20)
09104          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09105 
09106       /* Now do the IO, and run scheduled tasks */
09107       res = ast_io_wait(io, wakeup);
09108       if (res >= 0) {
09109          if (option_debug && res >= 20)
09110             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09111       }
09112    }
09113    return NULL;
09114 }
09115 
09116 static int start_network_thread(void)
09117 {
09118    pthread_attr_t attr;
09119    int threadcount = 0;
09120    int x;
09121    for (x = 0; x < iaxthreadcount; x++) {
09122       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09123       if (thread) {
09124          thread->type = IAX_TYPE_POOL;
09125          thread->threadnum = ++threadcount;
09126          ast_mutex_init(&thread->lock);
09127          ast_cond_init(&thread->cond, NULL);
09128          pthread_attr_init(&attr);
09129          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09130          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09131             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09132             free(thread);
09133             thread = NULL;
09134          }
09135          AST_LIST_LOCK(&idle_list);
09136          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09137          AST_LIST_UNLOCK(&idle_list);
09138       }
09139    }
09140    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09141    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09142    if (option_verbose > 1)
09143       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09144    return 0;
09145 }
09146 
09147 static struct iax2_context *build_context(char *context)
09148 {
09149    struct iax2_context *con;
09150 
09151    if ((con = ast_calloc(1, sizeof(*con))))
09152       ast_copy_string(con->context, context, sizeof(con->context));
09153    
09154    return con;
09155 }
09156 
09157 static int get_auth_methods(char *value)
09158 {
09159    int methods = 0;
09160    if (strstr(value, "rsa"))
09161       methods |= IAX_AUTH_RSA;
09162    if (strstr(value, "md5"))
09163       methods |= IAX_AUTH_MD5;
09164    if (strstr(value, "plaintext"))
09165       methods |= IAX_AUTH_PLAINTEXT;
09166    return methods;
09167 }
09168 
09169 
09170 /*! \brief Check if address can be used as packet source.
09171  \return 0  address available, 1  address unavailable, -1  error
09172 */
09173 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09174 {
09175    int sd;
09176    int res;
09177    
09178    sd = socket(AF_INET, SOCK_DGRAM, 0);
09179    if (sd < 0) {
09180       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09181       return -1;
09182    }
09183 
09184    res = bind(sd, sa, salen);
09185    if (res < 0) {
09186       if (option_debug)
09187          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09188       close(sd);
09189       return 1;
09190    }
09191 
09192    close(sd);
09193    return 0;
09194 }
09195 
09196 /*! \brief Parse the "sourceaddress" value,
09197   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09198   not found. */
09199 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09200 {
09201    struct sockaddr_in sin;
09202    int nonlocal = 1;
09203    int port = IAX_DEFAULT_PORTNO;
09204    int sockfd = defaultsockfd;
09205    char *tmp;
09206    char *addr;
09207    char *portstr;
09208 
09209    if (!(tmp = ast_strdupa(srcaddr)))
09210       return -1;
09211 
09212    addr = strsep(&tmp, ":");
09213    portstr = tmp;
09214 
09215    if (portstr) {
09216       port = atoi(portstr);
09217       if (port < 1)
09218          port = IAX_DEFAULT_PORTNO;
09219    }
09220    
09221    if (!ast_get_ip(&sin, addr)) {
09222       struct ast_netsock *sock;
09223       int res;
09224 
09225       sin.sin_port = 0;
09226       sin.sin_family = AF_INET;
09227       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09228       if (res == 0) {
09229          /* ip address valid. */
09230          sin.sin_port = htons(port);
09231          if (!(sock = ast_netsock_find(netsock, &sin)))
09232             sock = ast_netsock_find(outsock, &sin);
09233          if (sock) {
09234             sockfd = ast_netsock_sockfd(sock);
09235             nonlocal = 0;
09236          } else {
09237             unsigned int orig_saddr = sin.sin_addr.s_addr;
09238             /* INADDR_ANY matches anyway! */
09239             sin.sin_addr.s_addr = INADDR_ANY;
09240             if (ast_netsock_find(netsock, &sin)) {
09241                sin.sin_addr.s_addr = orig_saddr;
09242                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09243                if (sock) {
09244                   sockfd = ast_netsock_sockfd(sock);
09245                   ast_netsock_unref(sock);
09246                   nonlocal = 0;
09247                } else {
09248                   nonlocal = 2;
09249                }
09250             }
09251          }
09252       }
09253    }
09254       
09255    peer->sockfd = sockfd;
09256 
09257    if (nonlocal == 1) {
09258       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09259          srcaddr, peer->name);
09260       return -1;
09261         } else if (nonlocal == 2) {
09262       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09263          srcaddr, peer->name);
09264          return -1;
09265    } else {
09266       if (option_debug)
09267          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09268       return 0;
09269    }
09270 }
09271 
09272 static void peer_destructor(void *obj)
09273 {
09274    struct iax2_peer *peer = obj;
09275 
09276    ast_free_ha(peer->ha);
09277 
09278    if (peer->callno > 0) {
09279       ast_mutex_lock(&iaxsl[peer->callno]);
09280       iax2_destroy(peer->callno);
09281       ast_mutex_unlock(&iaxsl[peer->callno]);
09282    }
09283 
09284    register_peer_exten(peer, 0);
09285 
09286    if (peer->dnsmgr)
09287       ast_dnsmgr_release(peer->dnsmgr);
09288 
09289    ast_string_field_free_memory(peer);
09290 }
09291 
09292 /*! \brief Create peer structure based on configuration */
09293 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09294 {
09295    struct iax2_peer *peer = NULL;
09296    struct ast_ha *oldha = NULL;
09297    int maskfound=0;
09298    int found=0;
09299    int firstpass=1;
09300    struct iax2_peer tmp_peer = {
09301       .name = name,
09302    };
09303 
09304    if (!temponly) {
09305       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09306       if (peer && !ast_test_flag(peer, IAX_DELME))
09307          firstpass = 0;
09308    }
09309 
09310    if (peer) {
09311       found++;
09312       if (firstpass) {
09313          oldha = peer->ha;
09314          peer->ha = NULL;
09315       }
09316       unlink_peer(peer);
09317    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09318       peer->expire = -1;
09319       peer->pokeexpire = -1;
09320       peer->sockfd = defaultsockfd;
09321       if (ast_string_field_init(peer, 32))
09322          peer = peer_unref(peer);
09323    }
09324 
09325    if (peer) {
09326       if (firstpass) {
09327          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09328          peer->encmethods = iax2_encryption;
09329          peer->adsi = adsi;
09330          ast_string_field_set(peer,secret,"");
09331          if (!found) {
09332             ast_string_field_set(peer, name, name);
09333             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09334             peer->expiry = min_reg_expire;
09335          }
09336          peer->prefs = prefs;
09337          peer->capability = iax2_capability;
09338          peer->smoothing = 0;
09339          peer->pokefreqok = DEFAULT_FREQ_OK;
09340          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09341          ast_string_field_set(peer,context,"");
09342          ast_string_field_set(peer,peercontext,"");
09343          ast_clear_flag(peer, IAX_HASCALLERID);
09344          ast_string_field_set(peer, cid_name, "");
09345          ast_string_field_set(peer, cid_num, "");
09346       }
09347 
09348       if (!v) {
09349          v = alt;
09350          alt = NULL;
09351       }
09352       while(v) {
09353          if (!strcasecmp(v->name, "secret")) {
09354             ast_string_field_set(peer, secret, v->value);
09355          } else if (!strcasecmp(v->name, "mailbox")) {
09356             ast_string_field_set(peer, mailbox, v->value);
09357          } else if (!strcasecmp(v->name, "mohinterpret")) {
09358             ast_string_field_set(peer, mohinterpret, v->value);
09359          } else if (!strcasecmp(v->name, "mohsuggest")) {
09360             ast_string_field_set(peer, mohsuggest, v->value);
09361          } else if (!strcasecmp(v->name, "dbsecret")) {
09362             ast_string_field_set(peer, dbsecret, v->value);
09363          } else if (!strcasecmp(v->name, "trunk")) {
09364             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09365             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09366                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09367                ast_clear_flag(peer, IAX_TRUNK);
09368             }
09369          } else if (!strcasecmp(v->name, "auth")) {
09370             peer->authmethods = get_auth_methods(v->value);
09371          } else if (!strcasecmp(v->name, "encryption")) {
09372             peer->encmethods = get_encrypt_methods(v->value);
09373          } else if (!strcasecmp(v->name, "notransfer")) {
09374             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09375             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09376             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09377          } else if (!strcasecmp(v->name, "transfer")) {
09378             if (!strcasecmp(v->value, "mediaonly")) {
09379                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09380             } else if (ast_true(v->value)) {
09381                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09382             } else 
09383                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09384          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09385             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09386          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09387             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09388          } else if (!strcasecmp(v->name, "host")) {
09389             if (!strcasecmp(v->value, "dynamic")) {
09390                /* They'll register with us */
09391                ast_set_flag(peer, IAX_DYNAMIC); 
09392                if (!found) {
09393                   /* Initialize stuff iff we're not found, otherwise
09394                      we keep going with what we had */
09395                   memset(&peer->addr.sin_addr, 0, 4);
09396                   if (peer->addr.sin_port) {
09397                      /* If we've already got a port, make it the default rather than absolute */
09398                      peer->defaddr.sin_port = peer->addr.sin_port;
09399                      peer->addr.sin_port = 0;
09400                   }
09401                }
09402             } else {
09403                /* Non-dynamic.  Make sure we become that way if we're not */
09404                AST_SCHED_DEL(sched, peer->expire);
09405                ast_clear_flag(peer, IAX_DYNAMIC);
09406                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09407                   return peer_unref(peer);
09408                if (!peer->addr.sin_port)
09409                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09410             }
09411             if (!maskfound)
09412                inet_aton("255.255.255.255", &peer->mask);
09413          } else if (!strcasecmp(v->name, "defaultip")) {
09414             if (ast_get_ip(&peer->defaddr, v->value))
09415                return peer_unref(peer);
09416          } else if (!strcasecmp(v->name, "sourceaddress")) {
09417             peer_set_srcaddr(peer, v->value);
09418          } else if (!strcasecmp(v->name, "permit") ||
09419                   !strcasecmp(v->name, "deny")) {
09420             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09421          } else if (!strcasecmp(v->name, "mask")) {
09422             maskfound++;
09423             inet_aton(v->value, &peer->mask);
09424          } else if (!strcasecmp(v->name, "context")) {
09425             ast_string_field_set(peer, context, v->value);
09426          } else if (!strcasecmp(v->name, "regexten")) {
09427             ast_string_field_set(peer, regexten, v->value);
09428          } else if (!strcasecmp(v->name, "peercontext")) {
09429             ast_string_field_set(peer, peercontext, v->value);
09430          } else if (!strcasecmp(v->name, "port")) {
09431             if (ast_test_flag(peer, IAX_DYNAMIC))
09432                peer->defaddr.sin_port = htons(atoi(v->value));
09433             else
09434                peer->addr.sin_port = htons(atoi(v->value));
09435          } else if (!strcasecmp(v->name, "username")) {
09436             ast_string_field_set(peer, username, v->value);
09437          } else if (!strcasecmp(v->name, "allow")) {
09438             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09439          } else if (!strcasecmp(v->name, "disallow")) {
09440             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09441          } else if (!strcasecmp(v->name, "callerid")) {
09442             if (!ast_strlen_zero(v->value)) {
09443                char name2[80];
09444                char num2[80];
09445                ast_callerid_split(v->value, name2, 80, num2, 80);
09446                ast_string_field_set(peer, cid_name, name2);
09447                ast_string_field_set(peer, cid_num, num2);
09448                ast_set_flag(peer, IAX_HASCALLERID);
09449             } else {
09450                ast_clear_flag(peer, IAX_HASCALLERID);
09451                ast_string_field_set(peer, cid_name, "");
09452                ast_string_field_set(peer, cid_num, "");
09453             }
09454          } else if (!strcasecmp(v->name, "fullname")) {
09455             if (!ast_strlen_zero(v->value)) {
09456                ast_string_field_set(peer, cid_name, v->value);
09457                ast_set_flag(peer, IAX_HASCALLERID);
09458             } else {
09459                ast_string_field_set(peer, cid_name, "");
09460                if (ast_strlen_zero(peer->cid_num))
09461                   ast_clear_flag(peer, IAX_HASCALLERID);
09462             }
09463          } else if (!strcasecmp(v->name, "cid_number")) {
09464             if (!ast_strlen_zero(v->value)) {
09465                ast_string_field_set(peer, cid_num, v->value);
09466                ast_set_flag(peer, IAX_HASCALLERID);
09467             } else {
09468                ast_string_field_set(peer, cid_num, "");
09469                if (ast_strlen_zero(peer->cid_name))
09470                   ast_clear_flag(peer, IAX_HASCALLERID);
09471             }
09472          } else if (!strcasecmp(v->name, "sendani")) {
09473             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09474          } else if (!strcasecmp(v->name, "inkeys")) {
09475             ast_string_field_set(peer, inkeys, v->value);
09476          } else if (!strcasecmp(v->name, "outkey")) {
09477             ast_string_field_set(peer, outkey, v->value);
09478          } else if (!strcasecmp(v->name, "qualify")) {
09479             if (!strcasecmp(v->value, "no")) {
09480                peer->maxms = 0;
09481             } else if (!strcasecmp(v->value, "yes")) {
09482                peer->maxms = DEFAULT_MAXMS;
09483             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09484                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);
09485                peer->maxms = 0;
09486             }
09487          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09488             peer->smoothing = ast_true(v->value);
09489          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09490             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09491                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);
09492             }
09493          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09494             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09495                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);
09496             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09497          } else if (!strcasecmp(v->name, "timezone")) {
09498             ast_string_field_set(peer, zonetag, v->value);
09499          } else if (!strcasecmp(v->name, "adsi")) {
09500             peer->adsi = ast_true(v->value);
09501          }/* else if (strcasecmp(v->name,"type")) */
09502          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09503          v = v->next;
09504          if (!v) {
09505             v = alt;
09506             alt = NULL;
09507          }
09508       }
09509       if (!peer->authmethods)
09510          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09511       ast_clear_flag(peer, IAX_DELME); 
09512       /* Make sure these are IPv4 addresses */
09513       peer->addr.sin_family = AF_INET;
09514    }
09515    if (oldha)
09516       ast_free_ha(oldha);
09517    return peer;
09518 }
09519 
09520 static void user_destructor(void *obj)
09521 {
09522    struct iax2_user *user = obj;
09523 
09524    ast_free_ha(user->ha);
09525    free_context(user->contexts);
09526    if(user->vars) {
09527       ast_variables_destroy(user->vars);
09528       user->vars = NULL;
09529    }
09530    ast_string_field_free_memory(user);
09531 }
09532 
09533 /*! \brief Create in-memory user structure from configuration */
09534 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09535 {
09536    struct iax2_user *user = NULL;
09537    struct iax2_context *con, *conl = NULL;
09538    struct ast_ha *oldha = NULL;
09539    struct iax2_context *oldcon = NULL;
09540    int format;
09541    int firstpass=1;
09542    int oldcurauthreq = 0;
09543    char *varname = NULL, *varval = NULL;
09544    struct ast_variable *tmpvar = NULL;
09545    struct iax2_user tmp_user = {
09546       .name = name,
09547    };
09548 
09549    if (!temponly) {
09550       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09551       if (user && !ast_test_flag(user, IAX_DELME))
09552          firstpass = 0;
09553    }
09554 
09555    if (user) {
09556       if (firstpass) {
09557          oldcurauthreq = user->curauthreq;
09558          oldha = user->ha;
09559          oldcon = user->contexts;
09560          user->ha = NULL;
09561          user->contexts = NULL;
09562       }
09563       /* Already in the list, remove it and it will be added back (or FREE'd) */
09564       ao2_unlink(users, user);
09565    } else {
09566       user = ao2_alloc(sizeof(*user), user_destructor);
09567    }
09568    
09569    if (user) {
09570       if (firstpass) {
09571          ast_string_field_free_memory(user);
09572          memset(user, 0, sizeof(struct iax2_user));
09573          if (ast_string_field_init(user, 32)) {
09574             user = user_unref(user);
09575             goto cleanup;
09576          }
09577          user->maxauthreq = maxauthreq;
09578          user->curauthreq = oldcurauthreq;
09579          user->prefs = prefs;
09580          user->capability = iax2_capability;
09581          user->encmethods = iax2_encryption;
09582          user->adsi = adsi;
09583          ast_string_field_set(user, name, name);
09584          ast_string_field_set(user, language, language);
09585          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09586          ast_clear_flag(user, IAX_HASCALLERID);
09587          ast_string_field_set(user, cid_name, "");
09588          ast_string_field_set(user, cid_num, "");
09589       }
09590       if (!v) {
09591          v = alt;
09592          alt = NULL;
09593       }
09594       while(v) {
09595          if (!strcasecmp(v->name, "context")) {
09596             con = build_context(v->value);
09597             if (con) {
09598                if (conl)
09599                   conl->next = con;
09600                else
09601                   user->contexts = con;
09602                conl = con;
09603             }
09604          } else if (!strcasecmp(v->name, "permit") ||
09605                   !strcasecmp(v->name, "deny")) {
09606             user->ha = ast_append_ha(v->name, v->value, user->ha);
09607          } else if (!strcasecmp(v->name, "setvar")) {
09608             varname = ast_strdupa(v->value);
09609             if (varname && (varval = strchr(varname,'='))) {
09610                *varval = '\0';
09611                varval++;
09612                if((tmpvar = ast_variable_new(varname, varval))) {
09613                   tmpvar->next = user->vars; 
09614                   user->vars = tmpvar;
09615                }
09616             }
09617          } else if (!strcasecmp(v->name, "allow")) {
09618             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09619          } else if (!strcasecmp(v->name, "disallow")) {
09620             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09621          } else if (!strcasecmp(v->name, "trunk")) {
09622             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09623             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09624                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09625                ast_clear_flag(user, IAX_TRUNK);
09626             }
09627          } else if (!strcasecmp(v->name, "auth")) {
09628             user->authmethods = get_auth_methods(v->value);
09629          } else if (!strcasecmp(v->name, "encryption")) {
09630             user->encmethods = get_encrypt_methods(v->value);
09631          } else if (!strcasecmp(v->name, "notransfer")) {
09632             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09633             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09634             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09635          } else if (!strcasecmp(v->name, "transfer")) {
09636             if (!strcasecmp(v->value, "mediaonly")) {
09637                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09638             } else if (ast_true(v->value)) {
09639                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09640             } else 
09641                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09642          } else if (!strcasecmp(v->name, "codecpriority")) {
09643             if(!strcasecmp(v->value, "caller"))
09644                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09645             else if(!strcasecmp(v->value, "disabled"))
09646                ast_set_flag(user, IAX_CODEC_NOPREFS);
09647             else if(!strcasecmp(v->value, "reqonly")) {
09648                ast_set_flag(user, IAX_CODEC_NOCAP);
09649                ast_set_flag(user, IAX_CODEC_NOPREFS);
09650             }
09651          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09652             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09653          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09654             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09655          } else if (!strcasecmp(v->name, "dbsecret")) {
09656             ast_string_field_set(user, dbsecret, v->value);
09657          } else if (!strcasecmp(v->name, "secret")) {
09658             if (!ast_strlen_zero(user->secret)) {
09659                char *old = ast_strdupa(user->secret);
09660 
09661                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09662             } else
09663                ast_string_field_set(user, secret, v->value);
09664          } else if (!strcasecmp(v->name, "callerid")) {
09665             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09666                char name2[80];
09667                char num2[80];
09668                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09669                ast_string_field_set(user, cid_name, name2);
09670                ast_string_field_set(user, cid_num, num2);
09671                ast_set_flag(user, IAX_HASCALLERID);
09672             } else {
09673                ast_clear_flag(user, IAX_HASCALLERID);
09674                ast_string_field_set(user, cid_name, "");
09675                ast_string_field_set(user, cid_num, "");
09676             }
09677          } else if (!strcasecmp(v->name, "fullname")) {
09678             if (!ast_strlen_zero(v->value)) {
09679                ast_string_field_set(user, cid_name, v->value);
09680                ast_set_flag(user, IAX_HASCALLERID);
09681             } else {
09682                ast_string_field_set(user, cid_name, "");
09683                if (ast_strlen_zero(user->cid_num))
09684                   ast_clear_flag(user, IAX_HASCALLERID);
09685             }
09686          } else if (!strcasecmp(v->name, "cid_number")) {
09687             if (!ast_strlen_zero(v->value)) {
09688                ast_string_field_set(user, cid_num, v->value);
09689                ast_set_flag(user, IAX_HASCALLERID);
09690             } else {
09691                ast_string_field_set(user, cid_num, "");
09692                if (ast_strlen_zero(user->cid_name))
09693                   ast_clear_flag(user, IAX_HASCALLERID);
09694             }
09695          } else if (!strcasecmp(v->name, "accountcode")) {
09696             ast_string_field_set(user, accountcode, v->value);
09697          } else if (!strcasecmp(v->name, "mohinterpret")) {
09698             ast_string_field_set(user, mohinterpret, v->value);
09699          } else if (!strcasecmp(v->name, "mohsuggest")) {
09700             ast_string_field_set(user, mohsuggest, v->value);
09701          } else if (!strcasecmp(v->name, "language")) {
09702             ast_string_field_set(user, language, v->value);
09703          } else if (!strcasecmp(v->name, "amaflags")) {
09704             format = ast_cdr_amaflags2int(v->value);
09705             if (format < 0) {
09706                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09707             } else {
09708                user->amaflags = format;
09709             }
09710          } else if (!strcasecmp(v->name, "inkeys")) {
09711             ast_string_field_set(user, inkeys, v->value);
09712          } else if (!strcasecmp(v->name, "maxauthreq")) {
09713             user->maxauthreq = atoi(v->value);
09714             if (user->maxauthreq < 0)
09715                user->maxauthreq = 0;
09716          } else if (!strcasecmp(v->name, "adsi")) {
09717             user->adsi = ast_true(v->value);
09718          }/* else if (strcasecmp(v->name,"type")) */
09719          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09720          v = v->next;
09721          if (!v) {
09722             v = alt;
09723             alt = NULL;
09724          }
09725       }
09726       if (!user->authmethods) {
09727          if (!ast_strlen_zero(user->secret)) {
09728             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09729             if (!ast_strlen_zero(user->inkeys))
09730                user->authmethods |= IAX_AUTH_RSA;
09731          } else if (!ast_strlen_zero(user->inkeys)) {
09732             user->authmethods = IAX_AUTH_RSA;
09733          } else {
09734             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09735          }
09736       }
09737       ast_clear_flag(user, IAX_DELME);
09738    }
09739 cleanup:
09740    if (oldha)
09741       ast_free_ha(oldha);
09742    if (oldcon)
09743       free_context(oldcon);
09744    return user;
09745 }
09746 
09747 static int peer_delme_cb(void *obj, void *arg, int flags)
09748 {
09749    struct iax2_peer *peer = obj;
09750 
09751    ast_set_flag(peer, IAX_DELME);
09752 
09753    return 0;
09754 }
09755 
09756 static int user_delme_cb(void *obj, void *arg, int flags)
09757 {
09758    struct iax2_user *user = obj;
09759 
09760    ast_set_flag(user, IAX_DELME);
09761 
09762    return 0;
09763 }
09764 
09765 static void delete_users(void)
09766 {
09767    struct iax2_registry *reg;
09768 
09769    ao2_callback(users, 0, user_delme_cb, NULL);
09770 
09771    AST_LIST_LOCK(&registrations);
09772    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09773       ast_sched_del(sched, reg->expire);
09774       if (reg->callno) {
09775          ast_mutex_lock(&iaxsl[reg->callno]);
09776          if (iaxs[reg->callno]) {
09777             iaxs[reg->callno]->reg = NULL;
09778             iax2_destroy(reg->callno);
09779          }
09780          ast_mutex_unlock(&iaxsl[reg->callno]);
09781       }
09782       if (reg->dnsmgr)
09783          ast_dnsmgr_release(reg->dnsmgr);
09784       free(reg);
09785    }
09786    AST_LIST_UNLOCK(&registrations);
09787 
09788    ao2_callback(peers, 0, peer_delme_cb, NULL);
09789 }
09790 
09791 static void prune_users(void)
09792 {
09793    struct iax2_user *user;
09794    struct ao2_iterator i;
09795 
09796    i = ao2_iterator_init(users, 0);
09797    while ((user = ao2_iterator_next(&i))) {
09798       if (ast_test_flag(user, IAX_DELME))
09799          ao2_unlink(users, user);
09800       user_unref(user);
09801    }
09802 }
09803 
09804 /* Prune peers who still are supposed to be deleted */
09805 static void prune_peers(void)
09806 {
09807    struct iax2_peer *peer;
09808    struct ao2_iterator i;
09809 
09810    i = ao2_iterator_init(peers, 0);
09811    while ((peer = ao2_iterator_next(&i))) {
09812       if (ast_test_flag(peer, IAX_DELME))
09813          unlink_peer(peer);
09814       peer_unref(peer);
09815    }
09816 }
09817 
09818 static void set_timing(void)
09819 {
09820 #ifdef HAVE_ZAPTEL
09821    int bs = trunkfreq * 8;
09822    if (timingfd > -1) {
09823       if (
09824 #ifdef ZT_TIMERACK
09825          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09826 #endif         
09827          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09828          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09829    }
09830 #endif
09831 }
09832 
09833 static void set_config_destroy(void)
09834 {
09835    strcpy(accountcode, "");
09836    strcpy(language, "");
09837    strcpy(mohinterpret, "default");
09838    strcpy(mohsuggest, "");
09839    amaflags = 0;
09840    delayreject = 0;
09841    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09842    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09843    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09844    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09845    delete_users();
09846 }
09847 
09848 /*! \brief Load configuration */
09849 static int set_config(char *config_file, int reload)
09850 {
09851    struct ast_config *cfg, *ucfg;
09852    int capability=iax2_capability;
09853    struct ast_variable *v;
09854    char *cat;
09855    const char *utype;
09856    const char *tosval;
09857    int format;
09858    int portno = IAX_DEFAULT_PORTNO;
09859    int  x;
09860    struct iax2_user *user;
09861    struct iax2_peer *peer;
09862    struct ast_netsock *ns;
09863 #if 0
09864    static unsigned short int last_port=0;
09865 #endif
09866 
09867    cfg = ast_config_load(config_file);
09868    
09869    if (!cfg) {
09870       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09871       return -1;
09872    }
09873 
09874    if (reload) {
09875       set_config_destroy();
09876    }
09877 
09878    /* Reset global codec prefs */   
09879    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09880    
09881    /* Reset Global Flags */
09882    memset(&globalflags, 0, sizeof(globalflags));
09883    ast_set_flag(&globalflags, IAX_RTUPDATE);
09884 
09885 #ifdef SO_NO_CHECK
09886    nochecksums = 0;
09887 #endif
09888 
09889    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09890    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09891 
09892    maxauthreq = 3;
09893 
09894    v = ast_variable_browse(cfg, "general");
09895 
09896    /* Seed initial tos value */
09897    tosval = ast_variable_retrieve(cfg, "general", "tos");
09898    if (tosval) {
09899       if (ast_str2tos(tosval, &tos))
09900          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09901    }
09902    while(v) {
09903       if (!strcasecmp(v->name, "bindport")){ 
09904          if (reload)
09905             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09906          else
09907             portno = atoi(v->value);
09908       } else if (!strcasecmp(v->name, "pingtime")) 
09909          ping_time = atoi(v->value);
09910       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09911          if (reload) {
09912             if (atoi(v->value) != iaxthreadcount)
09913                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09914          } else {
09915             iaxthreadcount = atoi(v->value);
09916             if (iaxthreadcount < 1) {
09917                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09918                iaxthreadcount = 1;
09919             } else if (iaxthreadcount > 256) {
09920                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09921                iaxthreadcount = 256;
09922             }
09923          }
09924       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09925          if (reload) {
09926             AST_LIST_LOCK(&dynamic_list);
09927             iaxmaxthreadcount = atoi(v->value);
09928             AST_LIST_UNLOCK(&dynamic_list);
09929          } else {
09930             iaxmaxthreadcount = atoi(v->value);
09931             if (iaxmaxthreadcount < 0) {
09932                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09933                iaxmaxthreadcount = 0;
09934             } else if (iaxmaxthreadcount > 256) {
09935                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09936                iaxmaxthreadcount = 256;
09937             }
09938          }
09939       } else if (!strcasecmp(v->name, "nochecksums")) {
09940 #ifdef SO_NO_CHECK
09941          if (ast_true(v->value))
09942             nochecksums = 1;
09943          else
09944             nochecksums = 0;
09945 #else
09946          if (ast_true(v->value))
09947             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09948 #endif
09949       }
09950       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09951          maxjitterbuffer = atoi(v->value);
09952       else if (!strcasecmp(v->name, "resyncthreshold")) 
09953          resyncthreshold = atoi(v->value);
09954       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09955          maxjitterinterps = atoi(v->value);
09956       else if (!strcasecmp(v->name, "lagrqtime")) 
09957          lagrq_time = atoi(v->value);
09958       else if (!strcasecmp(v->name, "maxregexpire")) 
09959          max_reg_expire = atoi(v->value);
09960       else if (!strcasecmp(v->name, "minregexpire")) 
09961          min_reg_expire = atoi(v->value);
09962       else if (!strcasecmp(v->name, "bindaddr")) {
09963          if (reload) {
09964             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09965          } else {
09966             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09967                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09968             } else {
09969                if (option_verbose > 1) {
09970                   if (strchr(v->value, ':'))
09971                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09972                   else
09973                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09974                }
09975                if (defaultsockfd < 0) 
09976                   defaultsockfd = ast_netsock_sockfd(ns);
09977                ast_netsock_unref(ns);
09978             }
09979          }
09980       } else if (!strcasecmp(v->name, "authdebug"))
09981          authdebug = ast_true(v->value);
09982       else if (!strcasecmp(v->name, "encryption"))
09983          iax2_encryption = get_encrypt_methods(v->value);
09984       else if (!strcasecmp(v->name, "notransfer")) {
09985          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09986          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09987          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09988       } else if (!strcasecmp(v->name, "transfer")) {
09989          if (!strcasecmp(v->value, "mediaonly")) {
09990             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09991          } else if (ast_true(v->value)) {
09992             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09993          } else 
09994             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09995       } else if (!strcasecmp(v->name, "codecpriority")) {
09996          if(!strcasecmp(v->value, "caller"))
09997             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09998          else if(!strcasecmp(v->value, "disabled"))
09999             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10000          else if(!strcasecmp(v->value, "reqonly")) {
10001             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10002             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10003          }
10004       } else if (!strcasecmp(v->name, "jitterbuffer"))
10005          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10006       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10007          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10008       else if (!strcasecmp(v->name, "delayreject"))
10009          delayreject = ast_true(v->value);
10010       else if (!strcasecmp(v->name, "allowfwdownload"))
10011          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10012       else if (!strcasecmp(v->name, "rtcachefriends"))
10013          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10014       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10015          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10016       else if (!strcasecmp(v->name, "rtupdate"))
10017          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10018       else if (!strcasecmp(v->name, "trunktimestamps"))
10019          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10020       else if (!strcasecmp(v->name, "rtautoclear")) {
10021          int i = atoi(v->value);
10022          if(i > 0)
10023             global_rtautoclear = i;
10024          else
10025             i = 0;
10026          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10027       } else if (!strcasecmp(v->name, "trunkfreq")) {
10028          trunkfreq = atoi(v->value);
10029          if (trunkfreq < 10)
10030             trunkfreq = 10;
10031       } else if (!strcasecmp(v->name, "autokill")) {
10032          if (sscanf(v->value, "%d", &x) == 1) {
10033             if (x >= 0)
10034                autokill = x;
10035             else
10036                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10037          } else if (ast_true(v->value)) {
10038             autokill = DEFAULT_MAXMS;
10039          } else {
10040             autokill = 0;
10041          }
10042       } else if (!strcasecmp(v->name, "bandwidth")) {
10043          if (!strcasecmp(v->value, "low")) {
10044             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10045          } else if (!strcasecmp(v->value, "medium")) {
10046             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10047          } else if (!strcasecmp(v->value, "high")) {
10048             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10049          } else
10050             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10051       } else if (!strcasecmp(v->name, "allow")) {
10052          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10053       } else if (!strcasecmp(v->name, "disallow")) {
10054          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10055       } else if (!strcasecmp(v->name, "register")) {
10056          iax2_register(v->value, v->lineno);
10057       } else if (!strcasecmp(v->name, "iaxcompat")) {
10058          iaxcompat = ast_true(v->value);
10059       } else if (!strcasecmp(v->name, "regcontext")) {
10060          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10061          /* Create context if it doesn't exist already */
10062          if (!ast_context_find(regcontext))
10063             ast_context_create(NULL, regcontext, "IAX2");
10064       } else if (!strcasecmp(v->name, "tos")) {
10065          if (ast_str2tos(v->value, &tos))
10066             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10067       } else if (!strcasecmp(v->name, "accountcode")) {
10068          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10069       } else if (!strcasecmp(v->name, "mohinterpret")) {
10070          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10071       } else if (!strcasecmp(v->name, "mohsuggest")) {
10072          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10073       } else if (!strcasecmp(v->name, "amaflags")) {
10074          format = ast_cdr_amaflags2int(v->value);
10075          if (format < 0) {
10076             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10077          } else {
10078             amaflags = format;
10079          }
10080       } else if (!strcasecmp(v->name, "language")) {
10081          ast_copy_string(language, v->value, sizeof(language));
10082       } else if (!strcasecmp(v->name, "maxauthreq")) {
10083          maxauthreq = atoi(v->value);
10084          if (maxauthreq < 0)
10085             maxauthreq = 0;
10086       } else if (!strcasecmp(v->name, "adsi")) {
10087          adsi = ast_true(v->value);
10088       } /*else if (strcasecmp(v->name,"type")) */
10089       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10090       v = v->next;
10091    }
10092    
10093    if (defaultsockfd < 0) {
10094       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10095          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10096       } else {
10097          if (option_verbose > 1)
10098             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10099          defaultsockfd = ast_netsock_sockfd(ns);
10100          ast_netsock_unref(ns);
10101       }
10102    }
10103    if (reload) {
10104       ast_netsock_release(outsock);
10105       outsock = ast_netsock_list_alloc();
10106       if (!outsock) {
10107          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10108          return -1;
10109       }
10110       ast_netsock_init(outsock);
10111    }
10112 
10113    if (min_reg_expire > max_reg_expire) {
10114       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10115          min_reg_expire, max_reg_expire, max_reg_expire);
10116       min_reg_expire = max_reg_expire;
10117    }
10118    iax2_capability = capability;
10119    
10120    ucfg = ast_config_load("users.conf");
10121    if (ucfg) {
10122       struct ast_variable *gen;
10123       int genhasiax;
10124       int genregisteriax;
10125       const char *hasiax, *registeriax;
10126       
10127       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10128       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10129       gen = ast_variable_browse(ucfg, "general");
10130       cat = ast_category_browse(ucfg, NULL);
10131       while (cat) {
10132          if (strcasecmp(cat, "general")) {
10133             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10134             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10135             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10136                /* Start with general parameters, then specific parameters, user and peer */
10137                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10138                if (user) {
10139                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10140                   user = user_unref(user);
10141                }
10142                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10143                if (peer) {
10144                   if (ast_test_flag(peer, IAX_DYNAMIC))
10145                      reg_source_db(peer);
10146                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10147                   peer = peer_unref(peer);
10148                }
10149             }
10150             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10151                char tmp[256];
10152                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10153                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10154                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10155                if (!host)
10156                   host = ast_variable_retrieve(ucfg, "general", "host");
10157                if (!username)
10158                   username = ast_variable_retrieve(ucfg, "general", "username");
10159                if (!secret)
10160                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10161                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10162                   if (!ast_strlen_zero(secret))
10163                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10164                   else
10165                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10166                   iax2_register(tmp, 0);
10167                }
10168             }
10169          }
10170          cat = ast_category_browse(ucfg, cat);
10171       }
10172       ast_config_destroy(ucfg);
10173    }
10174    
10175    cat = ast_category_browse(cfg, NULL);
10176    while(cat) {
10177       if (strcasecmp(cat, "general")) {
10178          utype = ast_variable_retrieve(cfg, cat, "type");
10179          if (utype) {
10180             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10181                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10182                if (user) {
10183                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10184                   user = user_unref(user);
10185                }
10186             }
10187             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10188                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10189                if (peer) {
10190                   if (ast_test_flag(peer, IAX_DYNAMIC))
10191                      reg_source_db(peer);
10192                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10193                   peer = peer_unref(peer);
10194                }
10195             } else if (strcasecmp(utype, "user")) {
10196                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10197             }
10198          } else
10199             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10200       }
10201       cat = ast_category_browse(cfg, cat);
10202    }
10203    ast_config_destroy(cfg);
10204    set_timing();
10205    return 1;
10206 }
10207 
10208 static void poke_all_peers(void)
10209 {
10210    struct ao2_iterator i;
10211    struct iax2_peer *peer;
10212 
10213    i = ao2_iterator_init(peers, 0);
10214    while ((peer = ao2_iterator_next(&i))) {
10215       iax2_poke_peer(peer, 0);
10216       peer_unref(peer);
10217    }
10218 }
10219 static int reload_config(void)
10220 {
10221    char *config = "iax.conf";
10222    struct iax2_registry *reg;
10223 
10224    if (set_config(config, 1) > 0) {
10225       prune_peers();
10226       prune_users();
10227       AST_LIST_LOCK(&registrations);
10228       AST_LIST_TRAVERSE(&registrations, reg, entry)
10229          iax2_do_register(reg);
10230       AST_LIST_UNLOCK(&registrations);
10231       /* Qualify hosts, too */
10232       poke_all_peers();
10233    }
10234    reload_firmware(0);
10235    iax_provision_reload();
10236 
10237    return 0;
10238 }
10239 
10240 static int iax2_reload(int fd, int argc, char *argv[])
10241 {
10242    return reload_config();
10243 }
10244 
10245 static int reload(void)
10246 {
10247    return reload_config();
10248 }
10249 
10250 static int cache_get_callno_locked(const char *data)
10251 {
10252    struct sockaddr_in sin;
10253    int x;
10254    int callno;
10255    struct iax_ie_data ied;
10256    struct create_addr_info cai;
10257    struct parsed_dial_string pds;
10258    char *tmpstr;
10259 
10260    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10261       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10262          look up entries for a single context */
10263       if (!ast_mutex_trylock(&iaxsl[x])) {
10264          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10265             return x;
10266          ast_mutex_unlock(&iaxsl[x]);
10267       }
10268    }
10269 
10270    /* No match found, we need to create a new one */
10271 
10272    memset(&cai, 0, sizeof(cai));
10273    memset(&ied, 0, sizeof(ied));
10274    memset(&pds, 0, sizeof(pds));
10275 
10276    tmpstr = ast_strdupa(data);
10277    parse_dial_string(tmpstr, &pds);
10278 
10279    if (ast_strlen_zero(pds.peer)) {
10280       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10281       return -1;
10282    }
10283 
10284    /* Populate our address from the given */
10285    if (create_addr(pds.peer, NULL, &sin, &cai))
10286       return -1;
10287 
10288    if (option_debug)
10289       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10290          pds.peer, pds.username, pds.password, pds.context);
10291 
10292    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10293    if (callno < 1) {
10294       ast_log(LOG_WARNING, "Unable to create call\n");
10295       return -1;
10296    }
10297 
10298    ast_string_field_set(iaxs[callno], dproot, data);
10299    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10300 
10301    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10302    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10303    /* the string format is slightly different from a standard dial string,
10304       because the context appears in the 'exten' position
10305    */
10306    if (pds.exten)
10307       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10308    if (pds.username)
10309       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10310    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10311    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10312    /* Keep password handy */
10313    if (pds.password)
10314       ast_string_field_set(iaxs[callno], secret, pds.password);
10315    if (pds.key)
10316       ast_string_field_set(iaxs[callno], outkey, pds.key);
10317    /* Start the call going */
10318    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10319 
10320    return callno;
10321 }
10322 
10323 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10324 {
10325    struct iax2_dpcache *dp, *prev = NULL, *next;
10326    struct timeval tv;
10327    int x;
10328    int com[2];
10329    int timeout;
10330    int old=0;
10331    int outfd;
10332    int abort;
10333    int callno;
10334    struct ast_channel *c;
10335    struct ast_frame *f;
10336    gettimeofday(&tv, NULL);
10337    dp = dpcache;
10338    while(dp) {
10339       next = dp->next;
10340       /* Expire old caches */
10341       if (ast_tvcmp(tv, dp->expiry) > 0) {
10342             /* It's expired, let it disappear */
10343             if (prev)
10344                prev->next = dp->next;
10345             else
10346                dpcache = dp->next;
10347             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10348                /* Free memory and go again */
10349                free(dp);
10350             } else {
10351                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);
10352             }
10353             dp = next;
10354             continue;
10355       }
10356       /* We found an entry that matches us! */
10357       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10358          break;
10359       prev = dp;
10360       dp = next;
10361    }
10362    if (!dp) {
10363       /* No matching entry.  Create a new one. */
10364       /* First, can we make a callno? */
10365       callno = cache_get_callno_locked(data);
10366       if (callno < 0) {
10367          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10368          return NULL;
10369       }
10370       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10371          ast_mutex_unlock(&iaxsl[callno]);
10372          return NULL;
10373       }
10374       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10375       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10376       gettimeofday(&dp->expiry, NULL);
10377       dp->orig = dp->expiry;
10378       /* Expires in 30 mins by default */
10379       dp->expiry.tv_sec += iaxdefaultdpcache;
10380       dp->next = dpcache;
10381       dp->flags = CACHE_FLAG_PENDING;
10382       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10383          dp->waiters[x] = -1;
10384       dpcache = dp;
10385       dp->peer = iaxs[callno]->dpentries;
10386       iaxs[callno]->dpentries = dp;
10387       /* Send the request if we're already up */
10388       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10389          iax2_dprequest(dp, callno);
10390       ast_mutex_unlock(&iaxsl[callno]);
10391    }
10392    /* By here we must have a dp */
10393    if (dp->flags & CACHE_FLAG_PENDING) {
10394       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10395          for a reply to come back so long as it's pending */
10396       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10397          /* Find an empty slot */
10398          if (dp->waiters[x] < 0)
10399             break;
10400       }
10401       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10402          ast_log(LOG_WARNING, "No more waiter positions available\n");
10403          return NULL;
10404       }
10405       if (pipe(com)) {
10406          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10407          return NULL;
10408       }
10409       dp->waiters[x] = com[1];
10410       /* Okay, now we wait */
10411       timeout = iaxdefaulttimeout * 1000;
10412       /* Temporarily unlock */
10413       ast_mutex_unlock(&dpcache_lock);
10414       /* Defer any dtmf */
10415       if (chan)
10416          old = ast_channel_defer_dtmf(chan);
10417       abort = 0;
10418       while(timeout) {
10419          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10420          if (outfd > -1) {
10421             break;
10422          }
10423          if (c) {
10424             f = ast_read(c);
10425             if (f)
10426                ast_frfree(f);
10427             else {
10428                /* Got hung up on, abort! */
10429                break;
10430                abort = 1;
10431             }
10432          }
10433       }
10434       if (!timeout) {
10435          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10436       }
10437       ast_mutex_lock(&dpcache_lock);
10438       dp->waiters[x] = -1;
10439       close(com[1]);
10440       close(com[0]);
10441       if (abort) {
10442          /* Don't interpret anything, just abort.  Not sure what th epoint
10443            of undeferring dtmf on a hung up channel is but hey whatever */
10444          if (!old && chan)
10445             ast_channel_undefer_dtmf(chan);
10446          return NULL;
10447       }
10448       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10449          /* Now to do non-independent analysis the results of our wait */
10450          if (dp->flags & CACHE_FLAG_PENDING) {
10451             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10452                pending.  Don't let it take as long to timeout. */
10453             dp->flags &= ~CACHE_FLAG_PENDING;
10454             dp->flags |= CACHE_FLAG_TIMEOUT;
10455             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10456                systems without leaving it unavailable once the server comes back online */
10457             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10458             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10459                if (dp->waiters[x] > -1)
10460                   write(dp->waiters[x], "asdf", 4);
10461          }
10462       }
10463       /* Our caller will obtain the rest */
10464       if (!old && chan)
10465          ast_channel_undefer_dtmf(chan);
10466    }
10467    return dp;  
10468 }
10469 
10470 /*! \brief Part of the IAX2 switch interface */
10471 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10472 {
10473    struct iax2_dpcache *dp;
10474    int res = 0;
10475 #if 0
10476    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10477 #endif
10478    if ((priority != 1) && (priority != 2))
10479       return 0;
10480    ast_mutex_lock(&dpcache_lock);
10481    dp = find_cache(chan, data, context, exten, priority);
10482    if (dp) {
10483       if (dp->flags & CACHE_FLAG_EXISTS)
10484          res= 1;
10485    }
10486    ast_mutex_unlock(&dpcache_lock);
10487    if (!dp) {
10488       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10489    }
10490    return res;
10491 }
10492 
10493 /*! \brief part of the IAX2 dial plan switch interface */
10494 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10495 {
10496    int res = 0;
10497    struct iax2_dpcache *dp;
10498 #if 0
10499    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10500 #endif
10501    if ((priority != 1) && (priority != 2))
10502       return 0;
10503    ast_mutex_lock(&dpcache_lock);
10504    dp = find_cache(chan, data, context, exten, priority);
10505    if (dp) {
10506       if (dp->flags & CACHE_FLAG_CANEXIST)
10507          res= 1;
10508    }
10509    ast_mutex_unlock(&dpcache_lock);
10510    if (!dp) {
10511       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10512    }
10513    return res;
10514 }
10515 
10516 /*! \brief Part of the IAX2 Switch interface */
10517 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10518 {
10519    int res = 0;
10520    struct iax2_dpcache *dp;
10521 #if 0
10522    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10523 #endif
10524    if ((priority != 1) && (priority != 2))
10525       return 0;
10526    ast_mutex_lock(&dpcache_lock);
10527    dp = find_cache(chan, data, context, exten, priority);
10528    if (dp) {
10529       if (dp->flags & CACHE_FLAG_MATCHMORE)
10530          res= 1;
10531    }
10532    ast_mutex_unlock(&dpcache_lock);
10533    if (!dp) {
10534       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10535    }
10536    return res;
10537 }
10538 
10539 /*! \brief Execute IAX2 dialplan switch */
10540 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10541 {
10542    char odata[256];
10543    char req[256];
10544    char *ncontext;
10545    struct iax2_dpcache *dp;
10546    struct ast_app *dial;
10547 #if 0
10548    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);
10549 #endif
10550    if (priority == 2) {
10551       /* Indicate status, can be overridden in dialplan */
10552       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10553       if (dialstatus) {
10554          dial = pbx_findapp(dialstatus);
10555          if (dial) 
10556             pbx_exec(chan, dial, "");
10557       }
10558       return -1;
10559    } else if (priority != 1)
10560       return -1;
10561    ast_mutex_lock(&dpcache_lock);
10562    dp = find_cache(chan, data, context, exten, priority);
10563    if (dp) {
10564       if (dp->flags & CACHE_FLAG_EXISTS) {
10565          ast_copy_string(odata, data, sizeof(odata));
10566          ncontext = strchr(odata, '/');
10567          if (ncontext) {
10568             *ncontext = '\0';
10569             ncontext++;
10570             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10571          } else {
10572             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10573          }
10574          if (option_verbose > 2)
10575             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10576       } else {
10577          ast_mutex_unlock(&dpcache_lock);
10578          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10579          return -1;
10580       }
10581    }
10582    ast_mutex_unlock(&dpcache_lock);
10583    dial = pbx_findapp("Dial");
10584    if (dial) {
10585       return pbx_exec(chan, dial, req);
10586    } else {
10587       ast_log(LOG_WARNING, "No dial application registered\n");
10588    }
10589    return -1;
10590 }
10591 
10592 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10593 {
10594    struct iax2_peer *peer;
10595    char *peername, *colname;
10596 
10597    peername = ast_strdupa(data);
10598 
10599    /* if our channel, return the IP address of the endpoint of current channel */
10600    if (!strcmp(peername,"CURRENTCHANNEL")) {
10601            unsigned short callno;
10602       if (chan->tech != &iax2_tech)
10603          return -1;
10604       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10605       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10606       return 0;
10607    }
10608 
10609    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10610       *colname++ = '\0';
10611    else if ((colname = strchr(peername, '|')))
10612       *colname++ = '\0';
10613    else
10614       colname = "ip";
10615 
10616    if (!(peer = find_peer(peername, 1)))
10617       return -1;
10618 
10619    if (!strcasecmp(colname, "ip")) {
10620       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10621    } else  if (!strcasecmp(colname, "status")) {
10622       peer_status(peer, buf, len); 
10623    } else  if (!strcasecmp(colname, "mailbox")) {
10624       ast_copy_string(buf, peer->mailbox, len);
10625    } else  if (!strcasecmp(colname, "context")) {
10626       ast_copy_string(buf, peer->context, len);
10627    } else  if (!strcasecmp(colname, "expire")) {
10628       snprintf(buf, len, "%d", peer->expire);
10629    } else  if (!strcasecmp(colname, "dynamic")) {
10630       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10631    } else  if (!strcasecmp(colname, "callerid_name")) {
10632       ast_copy_string(buf, peer->cid_name, len);
10633    } else  if (!strcasecmp(colname, "callerid_num")) {
10634       ast_copy_string(buf, peer->cid_num, len);
10635    } else  if (!strcasecmp(colname, "codecs")) {
10636       ast_getformatname_multiple(buf, len -1, peer->capability);
10637    } else  if (!strncasecmp(colname, "codec[", 6)) {
10638       char *codecnum, *ptr;
10639       int index = 0, codec = 0;
10640       
10641       codecnum = strchr(colname, '[');
10642       *codecnum = '\0';
10643       codecnum++;
10644       if ((ptr = strchr(codecnum, ']'))) {
10645          *ptr = '\0';
10646       }
10647       index = atoi(codecnum);
10648       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10649          ast_copy_string(buf, ast_getformatname(codec), len);
10650       }
10651    }
10652 
10653    peer_unref(peer);
10654 
10655    return 0;
10656 }
10657 
10658 struct ast_custom_function iaxpeer_function = {
10659    .name = "IAXPEER",
10660    .synopsis = "Gets IAX peer information",
10661    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10662    .read = function_iaxpeer,
10663    .desc = "If peername specified, valid items are:\n"
10664    "- ip (default)          The IP address.\n"
10665    "- status                The peer's status (if qualify=yes)\n"
10666    "- mailbox               The configured mailbox.\n"
10667    "- context               The configured context.\n"
10668    "- expire                The epoch time of the next expire.\n"
10669    "- dynamic               Is it dynamic? (yes/no).\n"
10670    "- callerid_name         The configured Caller ID name.\n"
10671    "- callerid_num          The configured Caller ID number.\n"
10672    "- codecs                The configured codecs.\n"
10673    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10674    "\n"
10675    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10676    "\n"
10677 };
10678 
10679 
10680 /*! \brief Part of the device state notification system ---*/
10681 static int iax2_devicestate(void *data) 
10682 {
10683    struct parsed_dial_string pds;
10684    char *tmp = ast_strdupa(data);
10685    struct iax2_peer *p;
10686    int res = AST_DEVICE_INVALID;
10687 
10688    memset(&pds, 0, sizeof(pds));
10689    parse_dial_string(tmp, &pds);
10690 
10691    if (ast_strlen_zero(pds.peer)) {
10692       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10693       return res;
10694    }
10695    
10696    if (option_debug > 2)
10697       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10698 
10699    /* SLD: FIXME: second call to find_peer during registration */
10700    if (!(p = find_peer(pds.peer, 1)))
10701       return res;
10702 
10703    res = AST_DEVICE_UNAVAILABLE;
10704    if (option_debug > 2) 
10705       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10706          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10707    
10708    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10709        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10710       /* Peer is registered, or have default IP address
10711          and a valid registration */
10712       if (p->historicms == 0 || p->historicms <= p->maxms)
10713          /* let the core figure out whether it is in use or not */
10714          res = AST_DEVICE_UNKNOWN;  
10715    }
10716 
10717    peer_unref(p);
10718 
10719    return res;
10720 }
10721 
10722 static struct ast_switch iax2_switch = 
10723 {
10724    name:          "IAX2",
10725    description:      "IAX Remote Dialplan Switch",
10726    exists:        iax2_exists,
10727    canmatch:      iax2_canmatch,
10728    exec:       iax2_exec,
10729    matchmore:     iax2_matchmore,
10730 };
10731 
10732 static char show_stats_usage[] =
10733 "Usage: iax2 show stats\n"
10734 "       Display statistics on IAX channel driver.\n";
10735 
10736 static char show_cache_usage[] =
10737 "Usage: iax2 show cache\n"
10738 "       Display currently cached IAX Dialplan results.\n";
10739 
10740 static char show_peer_usage[] =
10741 "Usage: iax2 show peer <name>\n"
10742 "       Display details on specific IAX peer\n";
10743 
10744 static char prune_realtime_usage[] =
10745 "Usage: iax2 prune realtime [<peername>|all]\n"
10746 "       Prunes object(s) from the cache\n";
10747 
10748 static char iax2_reload_usage[] =
10749 "Usage: iax2 reload\n"
10750 "       Reloads IAX configuration from iax.conf\n";
10751 
10752 static char show_prov_usage[] =
10753 "Usage: iax2 provision <host> <template> [forced]\n"
10754 "       Provisions the given peer or IP address using a template\n"
10755 "       matching either 'template' or '*' if the template is not\n"
10756 "       found.  If 'forced' is specified, even empty provisioning\n"
10757 "       fields will be provisioned as empty fields.\n";
10758 
10759 static char show_users_usage[] = 
10760 "Usage: iax2 show users [like <pattern>]\n"
10761 "       Lists all known IAX2 users.\n"
10762 "       Optional regular expression pattern is used to filter the user list.\n";
10763 
10764 static char show_channels_usage[] = 
10765 "Usage: iax2 show channels\n"
10766 "       Lists all currently active IAX channels.\n";
10767 
10768 static char show_netstats_usage[] = 
10769 "Usage: iax2 show netstats\n"
10770 "       Lists network status for all currently active IAX channels.\n";
10771 
10772 static char show_threads_usage[] = 
10773 "Usage: iax2 show threads\n"
10774 "       Lists status of IAX helper threads\n";
10775 
10776 static char show_peers_usage[] = 
10777 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10778 "       Lists all known IAX2 peers.\n"
10779 "       Optional 'registered' argument lists only peers with known addresses.\n"
10780 "       Optional regular expression pattern is used to filter the peer list.\n";
10781 
10782 static char show_firmware_usage[] = 
10783 "Usage: iax2 show firmware\n"
10784 "       Lists all known IAX firmware images.\n";
10785 
10786 static char show_reg_usage[] =
10787 "Usage: iax2 show registry\n"
10788 "       Lists all registration requests and status.\n";
10789 
10790 static char debug_usage[] = 
10791 "Usage: iax2 set debug\n"
10792 "       Enables dumping of IAX packets for debugging purposes\n";
10793 
10794 static char no_debug_usage[] = 
10795 "Usage: iax2 set debug off\n"
10796 "       Disables dumping of IAX packets for debugging purposes\n";
10797 
10798 static char debug_trunk_usage[] =
10799 "Usage: iax2 set debug trunk\n"
10800 "       Requests current status of IAX trunking\n";
10801 
10802 static char no_debug_trunk_usage[] =
10803 "Usage: iax2 set debug trunk off\n"
10804 "       Requests current status of IAX trunking\n";
10805 
10806 static char debug_jb_usage[] =
10807 "Usage: iax2 set debug jb\n"
10808 "       Enables jitterbuffer debugging information\n";
10809 
10810 static char no_debug_jb_usage[] =
10811 "Usage: iax2 set debug jb off\n"
10812 "       Disables jitterbuffer debugging information\n";
10813 
10814 static char iax2_test_losspct_usage[] =
10815 "Usage: iax2 test losspct <percentage>\n"
10816 "       For testing, throws away <percentage> percent of incoming packets\n";
10817 
10818 #ifdef IAXTESTS
10819 static char iax2_test_late_usage[] =
10820 "Usage: iax2 test late <ms>\n"
10821 "       For testing, count the next frame as <ms> ms late\n";
10822 
10823 static char iax2_test_resync_usage[] =
10824 "Usage: iax2 test resync <ms>\n"
10825 "       For testing, adjust all future frames by <ms> ms\n";
10826 
10827 static char iax2_test_jitter_usage[] =
10828 "Usage: iax2 test jitter <ms> <pct>\n"
10829 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10830 #endif /* IAXTESTS */
10831 
10832 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10833    { "iax2", "trunk", "debug", NULL },
10834    iax2_do_trunk_debug, NULL,
10835    NULL };
10836 
10837 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10838    { "iax2", "jb", "debug", NULL },
10839    iax2_do_jb_debug, NULL,
10840    NULL };
10841 
10842 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10843    { "iax2", "no", "debug", NULL },
10844    iax2_no_debug, NULL,
10845    NULL };
10846 
10847 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10848    { "iax2", "no", "trunk", "debug", NULL },
10849    iax2_no_trunk_debug, NULL,
10850    NULL };
10851 
10852 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10853    { "iax2", "no", "jb", "debug", NULL },
10854    iax2_no_jb_debug, NULL,
10855    NULL };
10856 
10857 static struct ast_cli_entry cli_iax2[] = {
10858    { { "iax2", "show", "cache", NULL },
10859    iax2_show_cache, "Display IAX cached dialplan",
10860    show_cache_usage, NULL, },
10861 
10862    { { "iax2", "show", "channels", NULL },
10863    iax2_show_channels, "List active IAX channels",
10864    show_channels_usage, NULL, },
10865 
10866    { { "iax2", "show", "firmware", NULL },
10867    iax2_show_firmware, "List available IAX firmwares",
10868    show_firmware_usage, NULL, },
10869 
10870    { { "iax2", "show", "netstats", NULL },
10871    iax2_show_netstats, "List active IAX channel netstats",
10872    show_netstats_usage, NULL, },
10873 
10874    { { "iax2", "show", "peers", NULL },
10875    iax2_show_peers, "List defined IAX peers",
10876    show_peers_usage, NULL, },
10877 
10878    { { "iax2", "show", "registry", NULL },
10879    iax2_show_registry, "Display IAX registration status",
10880    show_reg_usage, NULL, },
10881 
10882    { { "iax2", "show", "stats", NULL },
10883    iax2_show_stats, "Display IAX statistics",
10884    show_stats_usage, NULL, },
10885 
10886    { { "iax2", "show", "threads", NULL },
10887    iax2_show_threads, "Display IAX helper thread info",
10888    show_threads_usage, NULL, },
10889 
10890    { { "iax2", "show", "users", NULL },
10891    iax2_show_users, "List defined IAX users",
10892    show_users_usage, NULL, },
10893 
10894    { { "iax2", "prune", "realtime", NULL },
10895    iax2_prune_realtime, "Prune a cached realtime lookup",
10896    prune_realtime_usage, complete_iax2_show_peer },
10897 
10898    { { "iax2", "reload", NULL },
10899    iax2_reload, "Reload IAX configuration",
10900    iax2_reload_usage },
10901 
10902    { { "iax2", "show", "peer", NULL },
10903    iax2_show_peer, "Show details on specific IAX peer",
10904    show_peer_usage, complete_iax2_show_peer },
10905 
10906    { { "iax2", "set", "debug", NULL },
10907    iax2_do_debug, "Enable IAX debugging",
10908    debug_usage },
10909 
10910    { { "iax2", "set", "debug", "trunk", NULL },
10911    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10912    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10913 
10914    { { "iax2", "set", "debug", "jb", NULL },
10915    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10916    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10917 
10918    { { "iax2", "set", "debug", "off", NULL },
10919    iax2_no_debug, "Disable IAX debugging",
10920    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10921 
10922    { { "iax2", "set", "debug", "trunk", "off", NULL },
10923    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10924    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10925 
10926    { { "iax2", "set", "debug", "jb", "off", NULL },
10927    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10928    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10929 
10930    { { "iax2", "test", "losspct", NULL },
10931    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10932    iax2_test_losspct_usage },
10933 
10934    { { "iax2", "provision", NULL },
10935    iax2_prov_cmd, "Provision an IAX device",
10936    show_prov_usage, iax2_prov_complete_template_3rd },
10937 
10938 #ifdef IAXTESTS
10939    { { "iax2", "test", "late", NULL },
10940    iax2_test_late, "Test the receipt of a late frame",
10941    iax2_test_late_usage },
10942 
10943    { { "iax2", "test", "resync", NULL },
10944    iax2_test_resync, "Test a resync in received timestamps",
10945    iax2_test_resync_usage },
10946 
10947    { { "iax2", "test", "jitter", NULL },
10948    iax2_test_jitter, "Simulates jitter for testing",
10949    iax2_test_jitter_usage },
10950 #endif /* IAXTESTS */
10951 };
10952 
10953 static int __unload_module(void)
10954 {
10955    struct iax2_thread *thread = NULL;
10956    int x;
10957 
10958    /* Make sure threads do not hold shared resources when they are canceled */
10959    
10960    /* Grab the sched lock resource to keep it away from threads about to die */
10961    /* Cancel the network thread, close the net socket */
10962    if (netthreadid != AST_PTHREADT_NULL) {
10963       AST_LIST_LOCK(&iaxq.queue);
10964       ast_mutex_lock(&sched_lock);
10965       pthread_cancel(netthreadid);
10966       ast_cond_signal(&sched_cond);
10967       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10968       AST_LIST_UNLOCK(&iaxq.queue);
10969       pthread_join(netthreadid, NULL);
10970    }
10971    if (schedthreadid != AST_PTHREADT_NULL) {
10972       ast_mutex_lock(&sched_lock);  
10973       pthread_cancel(schedthreadid);
10974       ast_cond_signal(&sched_cond);
10975       ast_mutex_unlock(&sched_lock);   
10976       pthread_join(schedthreadid, NULL);
10977    }
10978    
10979    /* Call for all threads to halt */
10980    AST_LIST_LOCK(&idle_list);
10981    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10982       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10983       pthread_cancel(thread->threadid);
10984    }
10985    AST_LIST_TRAVERSE_SAFE_END
10986    AST_LIST_UNLOCK(&idle_list);
10987 
10988    AST_LIST_LOCK(&active_list);
10989    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10990       AST_LIST_REMOVE_CURRENT(&active_list, list);
10991       pthread_cancel(thread->threadid);
10992    }
10993    AST_LIST_TRAVERSE_SAFE_END
10994    AST_LIST_UNLOCK(&active_list);
10995 
10996    AST_LIST_LOCK(&dynamic_list);
10997         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10998       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10999       pthread_cancel(thread->threadid);
11000         }
11001    AST_LIST_TRAVERSE_SAFE_END
11002         AST_LIST_UNLOCK(&dynamic_list);
11003 
11004    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11005 
11006    /* Wait for threads to exit */
11007    while(0 < iaxactivethreadcount)
11008       usleep(10000);
11009    
11010    ast_netsock_release(netsock);
11011    ast_netsock_release(outsock);
11012    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11013       if (iaxs[x]) {
11014          iax2_destroy(x);
11015       }
11016    }
11017    ast_manager_unregister( "IAXpeers" );
11018    ast_manager_unregister( "IAXnetstats" );
11019    ast_unregister_application(papp);
11020    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11021    ast_unregister_switch(&iax2_switch);
11022    ast_channel_unregister(&iax2_tech);
11023    delete_users();
11024    iax_provision_unload();
11025    sched_context_destroy(sched);
11026    reload_firmware(1);
11027 
11028    ast_mutex_destroy(&waresl.lock);
11029 
11030    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11031       ast_mutex_destroy(&iaxsl[x]);
11032    }
11033 
11034    ao2_ref(peers, -1);
11035    ao2_ref(users, -1);
11036    ao2_ref(iax_peercallno_pvts, -1);
11037 
11038    return 0;
11039 }
11040 
11041 static int unload_module(void)
11042 {
11043    ast_custom_function_unregister(&iaxpeer_function);
11044    return __unload_module();
11045 }
11046 
11047 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11048 {
11049    struct iax2_peer *peer = obj;
11050 
11051    if (peer->sockfd < 0)
11052       peer->sockfd = defaultsockfd;
11053 
11054    return 0;
11055 }
11056 
11057 static int pvt_hash_cb(const void *obj, const int flags)
11058 {
11059    const struct chan_iax2_pvt *pvt = obj;
11060 
11061    return pvt->peercallno;
11062 }
11063 
11064 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11065 {
11066    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11067 
11068    /* The frames_received field is used to hold whether we're matching
11069     * against a full frame or not ... */
11070 
11071    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11072       pvt2->frames_received) ? CMP_MATCH : 0;
11073 }
11074 
11075 /*! \brief Load IAX2 module, load configuraiton ---*/
11076 static int load_module(void)
11077 {
11078    char *config = "iax.conf";
11079    int res = 0;
11080    int x;
11081    struct iax2_registry *reg = NULL;
11082 
11083    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11084    if (!peers)
11085       return AST_MODULE_LOAD_FAILURE;
11086    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11087    if (!users) {
11088       ao2_ref(peers, -1);
11089       return AST_MODULE_LOAD_FAILURE;
11090    }
11091    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11092    if (!iax_peercallno_pvts) {
11093       ao2_ref(peers, -1);
11094       ao2_ref(users, -1);
11095       return AST_MODULE_LOAD_FAILURE;
11096    }
11097 
11098    ast_custom_function_register(&iaxpeer_function);
11099 
11100    iax_set_output(iax_debug_output);
11101    iax_set_error(iax_error_output);
11102    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11103    
11104 #ifdef HAVE_ZAPTEL
11105 #ifdef ZT_TIMERACK
11106    timingfd = open("/dev/zap/timer", O_RDWR);
11107    if (timingfd < 0)
11108 #endif
11109       timingfd = open("/dev/zap/pseudo", O_RDWR);
11110    if (timingfd < 0) 
11111       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11112 #endif      
11113 
11114    memset(iaxs, 0, sizeof(iaxs));
11115 
11116    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11117       ast_mutex_init(&iaxsl[x]);
11118    }
11119    
11120    ast_cond_init(&sched_cond, NULL);
11121 
11122    io = io_context_create();
11123    sched = sched_context_create();
11124    
11125    if (!io || !sched) {
11126       ast_log(LOG_ERROR, "Out of memory\n");
11127       return -1;
11128    }
11129 
11130    netsock = ast_netsock_list_alloc();
11131    if (!netsock) {
11132       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11133       return -1;
11134    }
11135    ast_netsock_init(netsock);
11136 
11137    outsock = ast_netsock_list_alloc();
11138    if (!outsock) {
11139       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11140       return -1;
11141    }
11142    ast_netsock_init(outsock);
11143 
11144    ast_mutex_init(&waresl.lock);
11145 
11146    AST_LIST_HEAD_INIT(&iaxq.queue);
11147    
11148    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11149 
11150    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11151    
11152    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11153    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11154 
11155    if(set_config(config, 0) == -1)
11156       return AST_MODULE_LOAD_DECLINE;
11157 
11158    if (ast_channel_register(&iax2_tech)) {
11159       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11160       __unload_module();
11161       return -1;
11162    }
11163 
11164    if (ast_register_switch(&iax2_switch)) 
11165       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11166 
11167    res = start_network_thread();
11168    if (!res) {
11169       if (option_verbose > 1) 
11170          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11171    } else {
11172       ast_log(LOG_ERROR, "Unable to start network thread\n");
11173       ast_netsock_release(netsock);
11174       ast_netsock_release(outsock);
11175    }
11176 
11177    AST_LIST_LOCK(&registrations);
11178    AST_LIST_TRAVERSE(&registrations, reg, entry)
11179       iax2_do_register(reg);
11180    AST_LIST_UNLOCK(&registrations); 
11181 
11182    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11183    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11184 
11185    reload_firmware(0);
11186    iax_provision_reload();
11187    return res;
11188 }
11189 
11190 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11191       .load = load_module,
11192       .unload = unload_module,
11193       .reload = reload,
11194           );

Generated on Tue Nov 4 13:20:15 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7