Sat Apr 12 07:12:19 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  * Hangup cause signalling implementation by
00015  * Levent Guendogdu <levon@feature-it.com>
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Implementation of Inter-Asterisk eXchange Version 2
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  *
00028  * \par See also
00029  * \arg \ref Config_iax
00030  *
00031  * \ingroup channel_drivers
00032  */
00033 
00034 /*** MODULEINFO
00035    <use>zaptel</use>
00036         <depend>res_features</depend>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 94256 $")
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <sys/types.h>
00046 #include <sys/mman.h>
00047 #include <dirent.h>
00048 #include <sys/socket.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #include <netinet/in_systm.h>
00052 #include <netinet/ip.h>
00053 #include <sys/time.h>
00054 #include <sys/signal.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include <strings.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netdb.h>
00061 #include <fcntl.h>
00062 #include <sys/stat.h>
00063 #include <regex.h>
00064 
00065 #ifdef HAVE_ZAPTEL
00066 #include <sys/ioctl.h>
00067 #include <zaptel/zaptel.h>
00068 #endif
00069 
00070 #include "asterisk/lock.h"
00071 #include "asterisk/frame.h" 
00072 #include "asterisk/channel.h"
00073 #include "asterisk/logger.h"
00074 #include "asterisk/module.h"
00075 #include "asterisk/pbx.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/io.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/options.h"
00080 #include "asterisk/cli.h"
00081 #include "asterisk/translate.h"
00082 #include "asterisk/md5.h"
00083 #include "asterisk/cdr.h"
00084 #include "asterisk/crypto.h"
00085 #include "asterisk/acl.h"
00086 #include "asterisk/manager.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/app.h"
00089 #include "asterisk/astdb.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/utils.h"
00093 #include "asterisk/causes.h"
00094 #include "asterisk/localtime.h"
00095 #include "asterisk/aes.h"
00096 #include "asterisk/dnsmgr.h"
00097 #include "asterisk/devicestate.h"
00098 #include "asterisk/netsock.h"
00099 #include "asterisk/stringfields.h"
00100 #include "asterisk/linkedlists.h"
00101 #include "asterisk/astobj2.h"
00102 
00103 #include "iax2.h"
00104 #include "iax2-parser.h"
00105 #include "iax2-provision.h"
00106 #include "jitterbuf.h"
00107 
00108 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00109    multithreaded mode. */
00110 #define SCHED_MULTITHREADED
00111 
00112 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00113    thread is actually doing. */
00114 #define DEBUG_SCHED_MULTITHREAD
00115 
00116 #ifndef IPTOS_MINCOST
00117 #define IPTOS_MINCOST 0x02
00118 #endif
00119 
00120 #ifdef SO_NO_CHECK
00121 static int nochecksums = 0;
00122 #endif
00123 
00124 
00125 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00126 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00127 
00128 #define DEFAULT_THREAD_COUNT 10
00129 #define DEFAULT_MAX_THREAD_COUNT 100
00130 #define DEFAULT_RETRY_TIME 1000
00131 #define MEMORY_SIZE 100
00132 #define DEFAULT_DROP 3
00133 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00134    but keeps the division between trunked and non-trunked better. */
00135 #define TRUNK_CALL_START   0x4000
00136 
00137 #define DEBUG_SUPPORT
00138 
00139 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00140 
00141 /* Sample over last 100 units to determine historic jitter */
00142 #define GAMMA (0.01)
00143 
00144 static struct ast_codec_pref prefs;
00145 
00146 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00147 
00148 static char context[80] = "default";
00149 
00150 static char language[MAX_LANGUAGE] = "";
00151 static char regcontext[AST_MAX_CONTEXT] = "";
00152 
00153 static int maxauthreq = 3;
00154 static int max_retries = 4;
00155 static int ping_time = 21;
00156 static int lagrq_time = 10;
00157 static int maxtrunkcall = TRUNK_CALL_START;
00158 static int maxnontrunkcall = 1;
00159 static int maxjitterbuffer=1000;
00160 static int resyncthreshold=1000;
00161 static int maxjitterinterps=10;
00162 static int trunkfreq = 20;
00163 static int authdebug = 1;
00164 static int autokill = 0;
00165 static int iaxcompat = 0;
00166 
00167 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00168 
00169 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00170 
00171 static unsigned int tos = 0;
00172 
00173 static int min_reg_expire;
00174 static int max_reg_expire;
00175 
00176 static int timingfd = -1;           /* Timing file descriptor */
00177 
00178 static struct ast_netsock_list *netsock;
00179 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00180 static int defaultsockfd = -1;
00181 
00182 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00183 
00184 /* Ethernet, etc */
00185 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00186 /* T1, maybe ISDN */
00187 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00188                 ~AST_FORMAT_SLINEAR &        \
00189                 ~AST_FORMAT_ULAW &        \
00190                 ~AST_FORMAT_ALAW &        \
00191                 ~AST_FORMAT_G722) 
00192 /* A modem */
00193 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00194                 ~AST_FORMAT_G726 &        \
00195                 ~AST_FORMAT_G726_AAL2 &      \
00196                 ~AST_FORMAT_ADPCM)
00197 
00198 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00199                 ~AST_FORMAT_G723_1)
00200 
00201 
00202 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00203 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00204 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00205 
00206 static   struct io_context *io;
00207 static   struct sched_context *sched;
00208 
00209 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00210 
00211 static int iaxdebug = 0;
00212 
00213 static int iaxtrunkdebug = 0;
00214 
00215 static int test_losspct = 0;
00216 #ifdef IAXTESTS
00217 static int test_late = 0;
00218 static int test_resync = 0;
00219 static int test_jit = 0;
00220 static int test_jitpct = 0;
00221 #endif /* IAXTESTS */
00222 
00223 static char accountcode[AST_MAX_ACCOUNT_CODE];
00224 static char mohinterpret[MAX_MUSICCLASS];
00225 static char mohsuggest[MAX_MUSICCLASS];
00226 static int amaflags = 0;
00227 static int adsi = 0;
00228 static int delayreject = 0;
00229 static int iax2_encryption = 0;
00230 
00231 static struct ast_flags globalflags = { 0 };
00232 
00233 static pthread_t netthreadid = AST_PTHREADT_NULL;
00234 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00235 AST_MUTEX_DEFINE_STATIC(sched_lock);
00236 static ast_cond_t sched_cond;
00237 
00238 enum {
00239    IAX_STATE_STARTED =     (1 << 0),
00240    IAX_STATE_AUTHENTICATED =  (1 << 1),
00241    IAX_STATE_TBD =      (1 << 2),
00242    IAX_STATE_UNCHANGED =      (1 << 3),
00243 } iax2_state;
00244 
00245 struct iax2_context {
00246    char context[AST_MAX_CONTEXT];
00247    struct iax2_context *next;
00248 };
00249 
00250 enum {
00251    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00252    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00253    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00254    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00255    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00256    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00257    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00258    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00259         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00260    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00261    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00262    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00263    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00264    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00265    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00266    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00267    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00268    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00269    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00270    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00271    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00272    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00273    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00274    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00275    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00276    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00277                        response, so that we've achieved a three-way handshake with
00278                        them before sending voice or anything else*/
00279 } iax2_flags;
00280 
00281 static int global_rtautoclear = 120;
00282 
00283 static int reload_config(void);
00284 static int iax2_reload(int fd, int argc, char *argv[]);
00285 
00286 
00287 struct iax2_user {
00288    AST_DECLARE_STRING_FIELDS(
00289       AST_STRING_FIELD(name);
00290       AST_STRING_FIELD(secret);
00291       AST_STRING_FIELD(dbsecret);
00292       AST_STRING_FIELD(accountcode);
00293       AST_STRING_FIELD(mohinterpret);
00294       AST_STRING_FIELD(mohsuggest);
00295       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00296       AST_STRING_FIELD(language);
00297       AST_STRING_FIELD(cid_num);
00298       AST_STRING_FIELD(cid_name);
00299    );
00300    
00301    int authmethods;
00302    int encmethods;
00303    int amaflags;
00304    int adsi;
00305    unsigned int flags;
00306    int capability;
00307    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00308    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00309    struct ast_codec_pref prefs;
00310    struct ast_ha *ha;
00311    struct iax2_context *contexts;
00312    struct ast_variable *vars;
00313 };
00314 
00315 struct iax2_peer {
00316    AST_DECLARE_STRING_FIELDS(
00317       AST_STRING_FIELD(name);
00318       AST_STRING_FIELD(username);
00319       AST_STRING_FIELD(secret);
00320       AST_STRING_FIELD(dbsecret);
00321       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00322 
00323       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00324       AST_STRING_FIELD(context);      /*!< For transfers only */
00325       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00326       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00327       AST_STRING_FIELD(mohinterpret);
00328       AST_STRING_FIELD(mohsuggest);
00329       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00330       /* Suggested caller id if registering */
00331       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00332       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00333       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00334    );
00335    struct ast_codec_pref prefs;
00336    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00337    struct sockaddr_in addr;
00338    int formats;
00339    int sockfd;             /*!< Socket to use for transmission */
00340    struct in_addr mask;
00341    int adsi;
00342    unsigned int flags;
00343 
00344    /* Dynamic Registration fields */
00345    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00346    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00347    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00348 
00349    int expire;             /*!< Schedule entry for expiry */
00350    int expiry;             /*!< How soon to expire */
00351    int capability;               /*!< Capability */
00352 
00353    /* Qualification */
00354    int callno;             /*!< Call number of POKE request */
00355    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00356    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00357    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00358 
00359    int pokefreqok;               /*!< How often to check if the host is up */
00360    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00361    int historicms;               /*!< How long recent average responses took */
00362    int smoothing;             /*!< Sample over how many units to determine historic ms */
00363    
00364    struct ast_ha *ha;
00365 };
00366 
00367 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00368 
00369 static struct iax2_trunk_peer {
00370    ast_mutex_t lock;
00371    int sockfd;
00372    struct sockaddr_in addr;
00373    struct timeval txtrunktime;      /*!< Transmit trunktime */
00374    struct timeval rxtrunktime;      /*!< Receive trunktime */
00375    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00376    struct timeval trunkact;      /*!< Last trunk activity */
00377    unsigned int lastsent;        /*!< Last sent time */
00378    /* Trunk data and length */
00379    unsigned char *trunkdata;
00380    unsigned int trunkdatalen;
00381    unsigned int trunkdataalloc;
00382    struct iax2_trunk_peer *next;
00383    int trunkerror;
00384    int calls;
00385 } *tpeers = NULL;
00386 
00387 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00388 
00389 struct iax_firmware {
00390    struct iax_firmware *next;
00391    int fd;
00392    int mmaplen;
00393    int dead;
00394    struct ast_iax2_firmware_header *fwh;
00395    unsigned char *buf;
00396 };
00397 
00398 enum iax_reg_state {
00399    REG_STATE_UNREGISTERED = 0,
00400    REG_STATE_REGSENT,
00401    REG_STATE_AUTHSENT,
00402    REG_STATE_REGISTERED,
00403    REG_STATE_REJECTED,
00404    REG_STATE_TIMEOUT,
00405    REG_STATE_NOAUTH
00406 };
00407 
00408 enum iax_transfer_state {
00409    TRANSFER_NONE = 0,
00410    TRANSFER_BEGIN,
00411    TRANSFER_READY,
00412    TRANSFER_RELEASED,
00413    TRANSFER_PASSTHROUGH,
00414    TRANSFER_MBEGIN,
00415    TRANSFER_MREADY,
00416    TRANSFER_MRELEASED,
00417    TRANSFER_MPASSTHROUGH,
00418    TRANSFER_MEDIA,
00419    TRANSFER_MEDIAPASS
00420 };
00421 
00422 struct iax2_registry {
00423    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00424    char username[80];
00425    char secret[80];        /*!< Password or key name in []'s */
00426    char random[80];
00427    int expire;          /*!< Sched ID of expiration */
00428    int refresh;            /*!< How often to refresh */
00429    enum iax_reg_state regstate;
00430    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00431    int callno;          /*!< Associated call number if applicable */
00432    struct sockaddr_in us;        /*!< Who the server thinks we are */
00433    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00434    AST_LIST_ENTRY(iax2_registry) entry;
00435 };
00436 
00437 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00438 
00439 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00440 #define MIN_RETRY_TIME     100
00441 #define MAX_RETRY_TIME     10000
00442 
00443 #define MAX_JITTER_BUFFER  50
00444 #define MIN_JITTER_BUFFER  10
00445 
00446 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00447 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00448 
00449 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00450 
00451 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00452 #define TS_GAP_FOR_JB_RESYNC  5000
00453 
00454 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00455 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00456 static int iaxdynamicthreadcount = 0;
00457 static int iaxactivethreadcount = 0;
00458 
00459 struct iax_rr {
00460    int jitter;
00461    int losspct;
00462    int losscnt;
00463    int packets;
00464    int delay;
00465    int dropped;
00466    int ooo;
00467 };
00468 
00469 struct chan_iax2_pvt {
00470    /*! Socket to send/receive on for this call */
00471    int sockfd;
00472    /*! Last received voice format */
00473    int voiceformat;
00474    /*! Last received video format */
00475    int videoformat;
00476    /*! Last sent voice format */
00477    int svoiceformat;
00478    /*! Last sent video format */
00479    int svideoformat;
00480    /*! What we are capable of sending */
00481    int capability;
00482    /*! Last received timestamp */
00483    unsigned int last;
00484    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00485    unsigned int lastsent;
00486    /*! Next outgoing timestamp if everything is good */
00487    unsigned int nextpred;
00488    /*! True if the last voice we transmitted was not silence/CNG */
00489    int notsilenttx;
00490    /*! Ping time */
00491    unsigned int pingtime;
00492    /*! Max time for initial response */
00493    int maxtime;
00494    /*! Peer Address */
00495    struct sockaddr_in addr;
00496    /*! Actual used codec preferences */
00497    struct ast_codec_pref prefs;
00498    /*! Requested codec preferences */
00499    struct ast_codec_pref rprefs;
00500    /*! Our call number */
00501    unsigned short callno;
00502    /*! Peer callno */
00503    unsigned short peercallno;
00504    /*! Negotiated format, this is only used to remember what format was
00505        chosen for an unauthenticated call so that the channel can get
00506        created later using the right format */
00507    int chosenformat;
00508    /*! Peer selected format */
00509    int peerformat;
00510    /*! Peer capability */
00511    int peercapability;
00512    /*! timeval that we base our transmission on */
00513    struct timeval offset;
00514    /*! timeval that we base our delivery on */
00515    struct timeval rxcore;
00516    /*! The jitterbuffer */
00517         jitterbuf *jb;
00518    /*! active jb read scheduler id */
00519         int jbid;                       
00520    /*! LAG */
00521    int lag;
00522    /*! Error, as discovered by the manager */
00523    int error;
00524    /*! Owner if we have one */
00525    struct ast_channel *owner;
00526    /*! What's our state? */
00527    struct ast_flags state;
00528    /*! Expiry (optional) */
00529    int expiry;
00530    /*! Next outgoing sequence number */
00531    unsigned char oseqno;
00532    /*! Next sequence number they have not yet acknowledged */
00533    unsigned char rseqno;
00534    /*! Next incoming sequence number */
00535    unsigned char iseqno;
00536    /*! Last incoming sequence number we have acknowledged */
00537    unsigned char aseqno;
00538 
00539    AST_DECLARE_STRING_FIELDS(
00540       /*! Peer name */
00541       AST_STRING_FIELD(peer);
00542       /*! Default Context */
00543       AST_STRING_FIELD(context);
00544       /*! Caller ID if available */
00545       AST_STRING_FIELD(cid_num);
00546       AST_STRING_FIELD(cid_name);
00547       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00548       AST_STRING_FIELD(ani);
00549       /*! DNID */
00550       AST_STRING_FIELD(dnid);
00551       /*! RDNIS */
00552       AST_STRING_FIELD(rdnis);
00553       /*! Requested Extension */
00554       AST_STRING_FIELD(exten);
00555       /*! Expected Username */
00556       AST_STRING_FIELD(username);
00557       /*! Expected Secret */
00558       AST_STRING_FIELD(secret);
00559       /*! MD5 challenge */
00560       AST_STRING_FIELD(challenge);
00561       /*! Public keys permitted keys for incoming authentication */
00562       AST_STRING_FIELD(inkeys);
00563       /*! Private key for outgoing authentication */
00564       AST_STRING_FIELD(outkey);
00565       /*! Preferred language */
00566       AST_STRING_FIELD(language);
00567       /*! Hostname/peername for naming purposes */
00568       AST_STRING_FIELD(host);
00569 
00570       AST_STRING_FIELD(dproot);
00571       AST_STRING_FIELD(accountcode);
00572       AST_STRING_FIELD(mohinterpret);
00573       AST_STRING_FIELD(mohsuggest);
00574    );
00575    
00576    /*! permitted authentication methods */
00577    int authmethods;
00578    /*! permitted encryption methods */
00579    int encmethods;
00580    /*! Encryption AES-128 Key */
00581    aes_encrypt_ctx ecx;
00582    /*! Decryption AES-128 Key */
00583    aes_decrypt_ctx dcx;
00584    /*! 32 bytes of semi-random data */
00585    unsigned char semirand[32];
00586    /*! Associated registry */
00587    struct iax2_registry *reg;
00588    /*! Associated peer for poking */
00589    struct iax2_peer *peerpoke;
00590    /*! IAX_ flags */
00591    unsigned int flags;
00592    int adsi;
00593 
00594    /*! Transferring status */
00595    enum iax_transfer_state transferring;
00596    /*! Transfer identifier */
00597    int transferid;
00598    /*! Who we are IAX transfering to */
00599    struct sockaddr_in transfer;
00600    /*! What's the new call number for the transfer */
00601    unsigned short transfercallno;
00602    /*! Transfer decrypt AES-128 Key */
00603    aes_encrypt_ctx tdcx;
00604 
00605    /*! Status of knowledge of peer ADSI capability */
00606    int peeradsicpe;
00607 
00608    /*! Who we are bridged to */
00609    unsigned short bridgecallno;
00610    
00611    int pingid;       /*!< Transmit PING request */
00612    int lagid;        /*!< Retransmit lag request */
00613    int autoid;       /*!< Auto hangup for Dialplan requestor */
00614    int authid;       /*!< Authentication rejection ID */
00615    int authfail;        /*!< Reason to report failure */
00616    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00617    int calling_ton;
00618    int calling_tns;
00619    int calling_pres;
00620    int amaflags;
00621    struct iax2_dpcache *dpentries;
00622    struct ast_variable *vars;
00623    /*! last received remote rr */
00624    struct iax_rr remote_rr;
00625    /*! Current base time: (just for stats) */
00626    int min;
00627    /*! Dropped frame count: (just for stats) */
00628    int frames_dropped;
00629    /*! received frame count: (just for stats) */
00630    int frames_received;
00631 };
00632 
00633 static struct ast_iax2_queue {
00634    AST_LIST_HEAD(, iax_frame) queue;
00635    int count;
00636 } iaxq;
00637 
00638 /*!
00639  * This module will get much higher performance when doing a lot of
00640  * user and peer lookups if the number of buckets is increased from 1.
00641  * However, to maintain old behavior for Asterisk 1.4, these are set to
00642  * 1 by default.  When using multiple buckets, search order through these
00643  * containers is considered random, so you will not be able to depend on
00644  * the order the entires are specified in iax.conf for matching order. */
00645 #ifdef LOW_MEMORY
00646 #define MAX_PEER_BUCKETS 1
00647 /* #define MAX_PEER_BUCKETS 17 */
00648 #else
00649 #define MAX_PEER_BUCKETS 1
00650 /* #define MAX_PEER_BUCKETS 563 */
00651 #endif
00652 static struct ao2_container *peers;
00653 
00654 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00655 static struct ao2_container *users;
00656 
00657 static struct ast_firmware_list {
00658    struct iax_firmware *wares;
00659    ast_mutex_t lock;
00660 } waresl;
00661 
00662 /*! Extension exists */
00663 #define CACHE_FLAG_EXISTS     (1 << 0)
00664 /*! Extension is nonexistent */
00665 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00666 /*! Extension can exist */
00667 #define CACHE_FLAG_CANEXIST      (1 << 2)
00668 /*! Waiting to hear back response */
00669 #define CACHE_FLAG_PENDING    (1 << 3)
00670 /*! Timed out */
00671 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00672 /*! Request transmitted */
00673 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00674 /*! Timeout */
00675 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00676 /*! Matchmore */
00677 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00678 
00679 static struct iax2_dpcache {
00680    char peercontext[AST_MAX_CONTEXT];
00681    char exten[AST_MAX_EXTENSION];
00682    struct timeval orig;
00683    struct timeval expiry;
00684    int flags;
00685    unsigned short callno;
00686    int waiters[256];
00687    struct iax2_dpcache *next;
00688    struct iax2_dpcache *peer; /*!< For linking in peers */
00689 } *dpcache;
00690 
00691 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00692 
00693 static void reg_source_db(struct iax2_peer *p);
00694 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00695 
00696 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00697 
00698 #define IAX_IOSTATE_IDLE      0
00699 #define IAX_IOSTATE_READY     1
00700 #define IAX_IOSTATE_PROCESSING   2
00701 #define IAX_IOSTATE_SCHEDREADY   3
00702 
00703 #define IAX_TYPE_POOL    1
00704 #define IAX_TYPE_DYNAMIC 2
00705 
00706 struct iax2_pkt_buf {
00707    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00708    size_t len;
00709    unsigned char buf[1];
00710 };
00711 
00712 struct iax2_thread {
00713    AST_LIST_ENTRY(iax2_thread) list;
00714    int type;
00715    int iostate;
00716 #ifdef SCHED_MULTITHREADED
00717    void (*schedfunc)(const void *);
00718    const void *scheddata;
00719 #endif
00720 #ifdef DEBUG_SCHED_MULTITHREAD
00721    char curfunc[80];
00722 #endif   
00723    int actions;
00724    pthread_t threadid;
00725    int threadnum;
00726    struct sockaddr_in iosin;
00727    unsigned char readbuf[4096]; 
00728    unsigned char *buf;
00729    ssize_t buf_len;
00730    size_t buf_size;
00731    int iofd;
00732    time_t checktime;
00733    ast_mutex_t lock;
00734    ast_cond_t cond;
00735    unsigned int ready_for_signal:1;
00736    /*! if this thread is processing a full frame,
00737      some information about that frame will be stored
00738      here, so we can avoid dispatching any more full
00739      frames for that callno to other threads */
00740    struct {
00741       unsigned short callno;
00742       struct sockaddr_in sin;
00743       unsigned char type;
00744       unsigned char csub;
00745    } ffinfo;
00746    /*! Queued up full frames for processing.  If more full frames arrive for
00747     *  a call which this thread is already processing a full frame for, they
00748     *  are queued up here. */
00749    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00750 };
00751 
00752 /* Thread lists */
00753 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00754 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00755 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00756 
00757 static void *iax2_process_thread(void *data);
00758 
00759 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00760 {
00761    ast_mutex_lock(lock);
00762    ast_cond_signal(cond);
00763    ast_mutex_unlock(lock);
00764 }
00765 
00766 static void iax_debug_output(const char *data)
00767 {
00768    if (iaxdebug)
00769       ast_verbose("%s", data);
00770 }
00771 
00772 static void iax_error_output(const char *data)
00773 {
00774    ast_log(LOG_WARNING, "%s", data);
00775 }
00776 
00777 static void jb_error_output(const char *fmt, ...)
00778 {
00779    va_list args;
00780    char buf[1024];
00781 
00782    va_start(args, fmt);
00783    vsnprintf(buf, 1024, fmt, args);
00784    va_end(args);
00785 
00786    ast_log(LOG_ERROR, buf);
00787 }
00788 
00789 static void jb_warning_output(const char *fmt, ...)
00790 {
00791    va_list args;
00792    char buf[1024];
00793 
00794    va_start(args, fmt);
00795    vsnprintf(buf, 1024, fmt, args);
00796    va_end(args);
00797 
00798    ast_log(LOG_WARNING, buf);
00799 }
00800 
00801 static void jb_debug_output(const char *fmt, ...)
00802 {
00803    va_list args;
00804    char buf[1024];
00805 
00806    va_start(args, fmt);
00807    vsnprintf(buf, 1024, fmt, args);
00808    va_end(args);
00809 
00810    ast_verbose(buf);
00811 }
00812 
00813 /* XXX We probably should use a mutex when working with this XXX */
00814 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00815 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
00816 static struct timeval lastused[IAX_MAX_CALLS];
00817 
00818 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);
00819 static int expire_registry(const void *data);
00820 static int iax2_answer(struct ast_channel *c);
00821 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00822 static int iax2_devicestate(void *data);
00823 static int iax2_digit_begin(struct ast_channel *c, char digit);
00824 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00825 static int iax2_do_register(struct iax2_registry *reg);
00826 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00827 static int iax2_hangup(struct ast_channel *c);
00828 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00829 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00830 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00831 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00832 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00833 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00834 static int iax2_sendtext(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00835 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00836 static int iax2_transfer(struct ast_channel *c, const char *dest);
00837 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00838 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00839 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00840 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00841 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00842 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00843 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00844 static struct ast_frame *iax2_read(struct ast_channel *c);
00845 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00846 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00847 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00848 static void prune_peers(void);
00849 
00850 static const struct ast_channel_tech iax2_tech = {
00851    .type = "IAX2",
00852    .description = tdesc,
00853    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00854    .properties = AST_CHAN_TP_WANTSJITTER,
00855    .requester = iax2_request,
00856    .devicestate = iax2_devicestate,
00857    .send_digit_begin = iax2_digit_begin,
00858    .send_digit_end = iax2_digit_end,
00859    .send_text = iax2_sendtext,
00860    .send_image = iax2_sendimage,
00861    .send_html = iax2_sendhtml,
00862    .call = iax2_call,
00863    .hangup = iax2_hangup,
00864    .answer = iax2_answer,
00865    .read = iax2_read,
00866    .write = iax2_write,
00867    .write_video = iax2_write,
00868    .indicate = iax2_indicate,
00869    .setoption = iax2_setoption,
00870    .bridge = iax2_bridge,
00871    .transfer = iax2_transfer,
00872    .fixup = iax2_fixup,
00873 };
00874 
00875 /* WARNING: insert_idle_thread should only ever be called within the
00876  * context of an iax2_process_thread() thread.
00877  */
00878 static void insert_idle_thread(struct iax2_thread *thread)
00879 {
00880    if (thread->type == IAX_TYPE_DYNAMIC) {
00881       AST_LIST_LOCK(&dynamic_list);
00882       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00883       AST_LIST_UNLOCK(&dynamic_list);
00884    } else {
00885       AST_LIST_LOCK(&idle_list);
00886       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00887       AST_LIST_UNLOCK(&idle_list);
00888    }
00889 
00890    return;
00891 }
00892 
00893 static struct iax2_thread *find_idle_thread(void)
00894 {
00895    pthread_attr_t attr;
00896    struct iax2_thread *thread = NULL;
00897 
00898    /* Pop the head of the list off */
00899    AST_LIST_LOCK(&idle_list);
00900    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00901    AST_LIST_UNLOCK(&idle_list);
00902 
00903    /* If no idle thread is available from the regular list, try dynamic */
00904    if (thread == NULL) {
00905       AST_LIST_LOCK(&dynamic_list);
00906       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00907       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00908       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00909          /* We need to MAKE a thread! */
00910          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00911             thread->threadnum = iaxdynamicthreadcount;
00912             thread->type = IAX_TYPE_DYNAMIC;
00913             ast_mutex_init(&thread->lock);
00914             ast_cond_init(&thread->cond, NULL);
00915             pthread_attr_init(&attr);
00916             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00917             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00918                free(thread);
00919                thread = NULL;
00920             } else {
00921                /* All went well and the thread is up, so increment our count */
00922                iaxdynamicthreadcount++;
00923                
00924                /* Wait for the thread to be ready before returning it to the caller */
00925                while (!thread->ready_for_signal)
00926                   usleep(1);
00927             }
00928          }
00929       }
00930       AST_LIST_UNLOCK(&dynamic_list);
00931    }
00932 
00933    /* this thread is not processing a full frame (since it is idle),
00934       so ensure that the field for the full frame call number is empty */
00935    if (thread)
00936       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00937 
00938    return thread;
00939 }
00940 
00941 #ifdef SCHED_MULTITHREADED
00942 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00943 {
00944    struct iax2_thread *thread = NULL;
00945    static time_t lasterror;
00946    static time_t t;
00947 
00948    thread = find_idle_thread();
00949 
00950    if (thread != NULL) {
00951       thread->schedfunc = func;
00952       thread->scheddata = data;
00953       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00954 #ifdef DEBUG_SCHED_MULTITHREAD
00955       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00956 #endif
00957       signal_condition(&thread->lock, &thread->cond);
00958       return 0;
00959    }
00960    time(&t);
00961    if (t != lasterror) 
00962       ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
00963    lasterror = t;
00964 
00965    return -1;
00966 }
00967 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00968 #endif
00969 
00970 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00971 {
00972    int res;
00973 
00974    res = ast_sched_add(con, when, callback, data);
00975    signal_condition(&sched_lock, &sched_cond);
00976 
00977    return res;
00978 }
00979 
00980 static int send_ping(const void *data);
00981 
00982 static void __send_ping(const void *data)
00983 {
00984    int callno = (long)data;
00985    ast_mutex_lock(&iaxsl[callno]);
00986    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00987       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00988       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
00989    }
00990    ast_mutex_unlock(&iaxsl[callno]);
00991 }
00992 
00993 static int send_ping(const void *data)
00994 {
00995 #ifdef SCHED_MULTITHREADED
00996    if (schedule_action(__send_ping, data))
00997 #endif      
00998       __send_ping(data);
00999    return 0;
01000 }
01001 
01002 static int get_encrypt_methods(const char *s)
01003 {
01004    int e;
01005    if (!strcasecmp(s, "aes128"))
01006       e = IAX_ENCRYPT_AES128;
01007    else if (ast_true(s))
01008       e = IAX_ENCRYPT_AES128;
01009    else
01010       e = 0;
01011    return e;
01012 }
01013 
01014 static int send_lagrq(const void *data);
01015 
01016 static void __send_lagrq(const void *data)
01017 {
01018    int callno = (long)data;
01019    /* Ping only if it's real not if it's bridged */
01020    ast_mutex_lock(&iaxsl[callno]);
01021    if (iaxs[callno] && iaxs[callno]->lagid != -1) {
01022       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01023       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01024    }
01025    ast_mutex_unlock(&iaxsl[callno]);
01026 }
01027 
01028 static int send_lagrq(const void *data)
01029 {
01030 #ifdef SCHED_MULTITHREADED
01031    if (schedule_action(__send_lagrq, data))
01032 #endif      
01033       __send_lagrq(data);
01034    return 0;
01035 }
01036 
01037 static unsigned char compress_subclass(int subclass)
01038 {
01039    int x;
01040    int power=-1;
01041    /* If it's 128 or smaller, just return it */
01042    if (subclass < IAX_FLAG_SC_LOG)
01043       return subclass;
01044    /* Otherwise find its power */
01045    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01046       if (subclass & (1 << x)) {
01047          if (power > -1) {
01048             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01049             return 0;
01050          } else
01051             power = x;
01052       }
01053    }
01054    return power | IAX_FLAG_SC_LOG;
01055 }
01056 
01057 static int uncompress_subclass(unsigned char csub)
01058 {
01059    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01060    if (csub & IAX_FLAG_SC_LOG) {
01061       /* special case for 'compressed' -1 */
01062       if (csub == 0xff)
01063          return -1;
01064       else
01065          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01066    }
01067    else
01068       return csub;
01069 }
01070 
01071 /*!
01072  * \note The only member of the peer passed here guaranteed to be set is the name field
01073  */
01074 static int peer_hash_cb(const void *obj, const int flags)
01075 {
01076    const struct iax2_peer *peer = obj;
01077 
01078    return ast_str_hash(peer->name);
01079 }
01080 
01081 /*!
01082  * \note The only member of the peer passed here guaranteed to be set is the name field
01083  */
01084 static int peer_cmp_cb(void *obj, void *arg, int flags)
01085 {
01086    struct iax2_peer *peer = obj, *peer2 = arg;
01087 
01088    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01089 }
01090 
01091 /*!
01092  * \note The only member of the user passed here guaranteed to be set is the name field
01093  */
01094 static int user_hash_cb(const void *obj, const int flags)
01095 {
01096    const struct iax2_user *user = obj;
01097 
01098    return ast_str_hash(user->name);
01099 }
01100 
01101 /*!
01102  * \note The only member of the user passed here guaranteed to be set is the name field
01103  */
01104 static int user_cmp_cb(void *obj, void *arg, int flags)
01105 {
01106    struct iax2_user *user = obj, *user2 = arg;
01107 
01108    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01109 }
01110 
01111 /*!
01112  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01113  *       so do not call it with a pvt lock held.
01114  */
01115 static struct iax2_peer *find_peer(const char *name, int realtime) 
01116 {
01117    struct iax2_peer *peer = NULL;
01118    struct iax2_peer tmp_peer = {
01119       .name = name,
01120    };
01121 
01122    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01123 
01124    /* Now go for realtime if applicable */
01125    if(!peer && realtime)
01126       peer = realtime_peer(name, NULL);
01127 
01128    return peer;
01129 }
01130 
01131 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01132 {
01133    ao2_ref(peer, +1);
01134    return peer;
01135 }
01136 
01137 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01138 {
01139    ao2_ref(peer, -1);
01140    return NULL;
01141 }
01142 
01143 static inline struct iax2_user *user_ref(struct iax2_user *user)
01144 {
01145    ao2_ref(user, +1);
01146    return user;
01147 }
01148 
01149 static inline struct iax2_user *user_unref(struct iax2_user *user)
01150 {
01151    ao2_ref(user, -1);
01152    return NULL;
01153 }
01154 
01155 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01156 {
01157    struct iax2_peer *peer = NULL;
01158    int res = 0;
01159    struct ao2_iterator i;
01160 
01161    i = ao2_iterator_init(peers, 0);
01162    while ((peer = ao2_iterator_next(&i))) {
01163       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01164           (peer->addr.sin_port == sin.sin_port)) {
01165          ast_copy_string(host, peer->name, len);
01166          peer_unref(peer);
01167          res = 1;
01168          break;
01169       }
01170       peer_unref(peer);
01171    }
01172 
01173    if (!peer) {
01174       peer = realtime_peer(NULL, &sin);
01175       if (peer) {
01176          ast_copy_string(host, peer->name, len);
01177          peer_unref(peer);
01178          res = 1;
01179       }
01180    }
01181 
01182    return res;
01183 }
01184 
01185 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01186 {
01187    struct chan_iax2_pvt *tmp;
01188    jb_conf jbconf;
01189 
01190    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01191       return NULL;
01192 
01193    if (ast_string_field_init(tmp, 32)) {
01194       free(tmp);
01195       tmp = NULL;
01196       return NULL;
01197    }
01198       
01199    tmp->prefs = prefs;
01200    tmp->callno = 0;
01201    tmp->peercallno = 0;
01202    tmp->transfercallno = 0;
01203    tmp->bridgecallno = 0;
01204    tmp->pingid = -1;
01205    tmp->lagid = -1;
01206    tmp->autoid = -1;
01207    tmp->authid = -1;
01208    tmp->initid = -1;
01209 
01210    ast_string_field_set(tmp,exten, "s");
01211    ast_string_field_set(tmp,host, host);
01212 
01213    tmp->jb = jb_new();
01214    tmp->jbid = -1;
01215    jbconf.max_jitterbuf = maxjitterbuffer;
01216    jbconf.resync_threshold = resyncthreshold;
01217    jbconf.max_contig_interp = maxjitterinterps;
01218    jb_setconf(tmp->jb,&jbconf);
01219 
01220    return tmp;
01221 }
01222 
01223 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01224 {
01225    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01226    if (new) {
01227       size_t afdatalen = new->afdatalen;
01228       memcpy(new, fr, sizeof(*new));
01229       iax_frame_wrap(new, &fr->af);
01230       new->afdatalen = afdatalen;
01231       new->data = NULL;
01232       new->datalen = 0;
01233       new->direction = DIRECTION_INGRESS;
01234       new->retrans = -1;
01235    }
01236    return new;
01237 }
01238 
01239 #define NEW_PREVENT  0
01240 #define NEW_ALLOW    1
01241 #define NEW_FORCE    2
01242 
01243 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
01244 {
01245    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01246       (cur->addr.sin_port == sin->sin_port)) {
01247       /* This is the main host */
01248       if ((cur->peercallno == callno) ||
01249          ((dcallno == cur->callno) && !cur->peercallno)) {
01250          /* That's us.  Be sure we keep track of the peer call number */
01251          return 1;
01252       }
01253    }
01254    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01255        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01256       /* We're transferring */
01257       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01258          return 1;
01259    }
01260    return 0;
01261 }
01262 
01263 static void update_max_trunk(void)
01264 {
01265    int max = TRUNK_CALL_START;
01266    int x;
01267    /* XXX Prolly don't need locks here XXX */
01268    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01269       if (iaxs[x])
01270          max = x + 1;
01271    }
01272    maxtrunkcall = max;
01273    if (option_debug && iaxdebug)
01274       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01275 }
01276 
01277 static void update_max_nontrunk(void)
01278 {
01279    int max = 1;
01280    int x;
01281    /* XXX Prolly don't need locks here XXX */
01282    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01283       if (iaxs[x])
01284          max = x + 1;
01285    }
01286    maxnontrunkcall = max;
01287    if (option_debug && iaxdebug)
01288       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01289 }
01290 
01291 static int make_trunk(unsigned short callno, int locked)
01292 {
01293    int x;
01294    int res= 0;
01295    struct timeval now;
01296    if (iaxs[callno]->oseqno) {
01297       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01298       return -1;
01299    }
01300    if (callno & TRUNK_CALL_START) {
01301       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01302       return -1;
01303    }
01304    gettimeofday(&now, NULL);
01305    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01306       ast_mutex_lock(&iaxsl[x]);
01307       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01308          iaxs[x] = iaxs[callno];
01309          iaxs[x]->callno = x;
01310          iaxs[callno] = NULL;
01311          /* Update the two timers that should have been started */
01312          if (iaxs[x]->pingid > -1)
01313             ast_sched_del(sched, iaxs[x]->pingid);
01314          if (iaxs[x]->lagid > -1)
01315             ast_sched_del(sched, iaxs[x]->lagid);
01316          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01317          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01318          if (locked)
01319             ast_mutex_unlock(&iaxsl[callno]);
01320          res = x;
01321          if (!locked)
01322             ast_mutex_unlock(&iaxsl[x]);
01323          break;
01324       }
01325       ast_mutex_unlock(&iaxsl[x]);
01326    }
01327    if (x >= IAX_MAX_CALLS - 1) {
01328       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01329       return -1;
01330    }
01331    if (option_debug)
01332       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01333    /* We move this call from a non-trunked to a trunked call */
01334    update_max_trunk();
01335    update_max_nontrunk();
01336    return res;
01337 }
01338 
01339 /*!
01340  * \note Calling this function while holding another pvt lock can cause a deadlock.
01341  */
01342 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd)
01343 {
01344    int res = 0;
01345    int x;
01346    struct timeval now;
01347    char host[80];
01348 
01349    if (new <= NEW_ALLOW) {
01350       /* Look for an existing connection first */
01351       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01352          ast_mutex_lock(&iaxsl[x]);
01353          if (iaxs[x]) {
01354             /* Look for an exact match */
01355             if (match(sin, callno, dcallno, iaxs[x])) {
01356                res = x;
01357             }
01358          }
01359          ast_mutex_unlock(&iaxsl[x]);
01360       }
01361       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01362          ast_mutex_lock(&iaxsl[x]);
01363          if (iaxs[x]) {
01364             /* Look for an exact match */
01365             if (match(sin, callno, dcallno, iaxs[x])) {
01366                res = x;
01367             }
01368          }
01369          ast_mutex_unlock(&iaxsl[x]);
01370       }
01371    }
01372    if ((res < 1) && (new >= NEW_ALLOW)) {
01373       /* It may seem odd that we look through the peer list for a name for
01374        * this *incoming* call.  Well, it is weird.  However, users don't
01375        * have an IP address/port number that we can match against.  So,
01376        * this is just checking for a peer that has that IP/port and
01377        * assuming that we have a user of the same name.  This isn't always
01378        * correct, but it will be changed if needed after authentication. */
01379       if (!iax2_getpeername(*sin, host, sizeof(host)))
01380          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01381       gettimeofday(&now, NULL);
01382       for (x=1;x<TRUNK_CALL_START;x++) {
01383          /* Find first unused call number that hasn't been used in a while */
01384          ast_mutex_lock(&iaxsl[x]);
01385          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01386          ast_mutex_unlock(&iaxsl[x]);
01387       }
01388       /* We've still got lock held if we found a spot */
01389       if (x >= TRUNK_CALL_START) {
01390          ast_log(LOG_WARNING, "No more space\n");
01391          return 0;
01392       }
01393       iaxs[x] = new_iax(sin, host);
01394       update_max_nontrunk();
01395       if (iaxs[x]) {
01396          if (option_debug && iaxdebug)
01397             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01398          iaxs[x]->sockfd = sockfd;
01399          iaxs[x]->addr.sin_port = sin->sin_port;
01400          iaxs[x]->addr.sin_family = sin->sin_family;
01401          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01402          iaxs[x]->peercallno = callno;
01403          iaxs[x]->callno = x;
01404          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01405          iaxs[x]->expiry = min_reg_expire;
01406          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01407          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01408          iaxs[x]->amaflags = amaflags;
01409          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01410          
01411          ast_string_field_set(iaxs[x], accountcode, accountcode);
01412          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01413          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01414       } else {
01415          ast_log(LOG_WARNING, "Out of resources\n");
01416          ast_mutex_unlock(&iaxsl[x]);
01417          return 0;
01418       }
01419       ast_mutex_unlock(&iaxsl[x]);
01420       res = x;
01421    }
01422    return res;
01423 }
01424 
01425 static void iax2_frame_free(struct iax_frame *fr)
01426 {
01427    if (fr->retrans > -1)
01428       ast_sched_del(sched, fr->retrans);
01429    iax_frame_free(fr);
01430 }
01431 
01432 /*!
01433  * \brief Queue a frame to a call's owning asterisk channel
01434  *
01435  * \pre This function assumes that iaxsl[callno] is locked when called.
01436  *
01437  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01438  * was valid before calling it, it may no longer be valid after calling it.
01439  * This function may unlock and lock the mutex associated with this callno,
01440  * meaning that another thread may grab it and destroy the call.
01441  */
01442 static int iax2_queue_frame(int callno, struct ast_frame *f)
01443 {
01444    for (;;) {
01445       if (iaxs[callno] && iaxs[callno]->owner) {
01446          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01447             /* Avoid deadlock by pausing and trying again */
01448             ast_mutex_unlock(&iaxsl[callno]);
01449             usleep(1);
01450             ast_mutex_lock(&iaxsl[callno]);
01451          } else {
01452             ast_queue_frame(iaxs[callno]->owner, f);
01453             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01454             break;
01455          }
01456       } else
01457          break;
01458    }
01459    return 0;
01460 }
01461 
01462 /*!
01463  * \brief Queue a hangup frame on the ast_channel owner
01464  *
01465  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01466  * is active for the given call number.
01467  *
01468  * \pre Assumes lock for callno is already held.
01469  *
01470  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01471  * was valid before calling it, it may no longer be valid after calling it.
01472  * This function may unlock and lock the mutex associated with this callno,
01473  * meaning that another thread may grab it and destroy the call.
01474  */
01475 static int iax2_queue_hangup(int callno)
01476 {
01477    for (;;) {
01478       if (iaxs[callno] && iaxs[callno]->owner) {
01479          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01480             /* Avoid deadlock by pausing and trying again */
01481             ast_mutex_unlock(&iaxsl[callno]);
01482             usleep(1);
01483             ast_mutex_lock(&iaxsl[callno]);
01484          } else {
01485             ast_queue_hangup(iaxs[callno]->owner);
01486             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01487             break;
01488          }
01489       } else
01490          break;
01491    }
01492    return 0;
01493 }
01494 
01495 /*!
01496  * \brief Queue a control frame on the ast_channel owner
01497  *
01498  * This function queues a control frame on the owner of the IAX2 pvt struct that
01499  * is active for the given call number.
01500  *
01501  * \pre Assumes lock for callno is already held.
01502  *
01503  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01504  * was valid before calling it, it may no longer be valid after calling it.
01505  * This function may unlock and lock the mutex associated with this callno,
01506  * meaning that another thread may grab it and destroy the call.
01507  */
01508 static int iax2_queue_control_data(int callno, 
01509    enum ast_control_frame_type control, const void *data, size_t datalen)
01510 {
01511    for (;;) {
01512       if (iaxs[callno] && iaxs[callno]->owner) {
01513          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01514             /* Avoid deadlock by pausing and trying again */
01515             ast_mutex_unlock(&iaxsl[callno]);
01516             usleep(1);
01517             ast_mutex_lock(&iaxsl[callno]);
01518          } else {
01519             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01520             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01521             break;
01522          }
01523       } else
01524          break;
01525    }
01526    return 0;
01527 }
01528 static void destroy_firmware(struct iax_firmware *cur)
01529 {
01530    /* Close firmware */
01531    if (cur->fwh) {
01532       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01533    }
01534    close(cur->fd);
01535    free(cur);
01536 }
01537 
01538 static int try_firmware(char *s)
01539 {
01540    struct stat stbuf;
01541    struct iax_firmware *cur;
01542    int ifd;
01543    int fd;
01544    int res;
01545    
01546    struct ast_iax2_firmware_header *fwh, fwh2;
01547    struct MD5Context md5;
01548    unsigned char sum[16];
01549    unsigned char buf[1024];
01550    int len, chunk;
01551    char *s2;
01552    char *last;
01553    s2 = alloca(strlen(s) + 100);
01554    if (!s2) {
01555       ast_log(LOG_WARNING, "Alloca failed!\n");
01556       return -1;
01557    }
01558    last = strrchr(s, '/');
01559    if (last)
01560       last++;
01561    else
01562       last = s;
01563    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01564    res = stat(s, &stbuf);
01565    if (res < 0) {
01566       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01567       return -1;
01568    }
01569    /* Make sure it's not a directory */
01570    if (S_ISDIR(stbuf.st_mode))
01571       return -1;
01572    ifd = open(s, O_RDONLY);
01573    if (ifd < 0) {
01574       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01575       return -1;
01576    }
01577    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01578    if (fd < 0) {
01579       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01580       close(ifd);
01581       return -1;
01582    }
01583    /* Unlink our newly created file */
01584    unlink(s2);
01585    
01586    /* Now copy the firmware into it */
01587    len = stbuf.st_size;
01588    while(len) {
01589       chunk = len;
01590       if (chunk > sizeof(buf))
01591          chunk = sizeof(buf);
01592       res = read(ifd, buf, chunk);
01593       if (res != chunk) {
01594          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01595          close(ifd);
01596          close(fd);
01597          return -1;
01598       }
01599       res = write(fd, buf, chunk);
01600       if (res != chunk) {
01601          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01602          close(ifd);
01603          close(fd);
01604          return -1;
01605       }
01606       len -= chunk;
01607    }
01608    close(ifd);
01609    /* Return to the beginning */
01610    lseek(fd, 0, SEEK_SET);
01611    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01612       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01613       close(fd);
01614       return -1;
01615    }
01616    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01617       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01618       close(fd);
01619       return -1;
01620    }
01621    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01622       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01623       close(fd);
01624       return -1;
01625    }
01626    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01627       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01628       close(fd);
01629       return -1;
01630    }
01631    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01632    if (fwh == (void *) -1) {
01633       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01634       close(fd);
01635       return -1;
01636    }
01637    MD5Init(&md5);
01638    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01639    MD5Final(sum, &md5);
01640    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01641       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01642       munmap((void*)fwh, stbuf.st_size);
01643       close(fd);
01644       return -1;
01645    }
01646    cur = waresl.wares;
01647    while(cur) {
01648       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01649          /* Found a candidate */
01650          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01651             /* The version we have on loaded is older, load this one instead */
01652             break;
01653          /* This version is no newer than what we have.  Don't worry about it.
01654             We'll consider it a proper load anyhow though */
01655          munmap((void*)fwh, stbuf.st_size);
01656          close(fd);
01657          return 0;
01658       }
01659       cur = cur->next;
01660    }
01661    if (!cur) {
01662       /* Allocate a new one and link it */
01663       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01664          cur->fd = -1;
01665          cur->next = waresl.wares;
01666          waresl.wares = cur;
01667       }
01668    }
01669    if (cur) {
01670       if (cur->fwh) {
01671          munmap((void*)cur->fwh, cur->mmaplen);
01672       }
01673       if (cur->fd > -1)
01674          close(cur->fd);
01675       cur->fwh = fwh;
01676       cur->fd = fd;
01677       cur->mmaplen = stbuf.st_size;
01678       cur->dead = 0;
01679    }
01680    return 0;
01681 }
01682 
01683 static int iax_check_version(char *dev)
01684 {
01685    int res = 0;
01686    struct iax_firmware *cur;
01687    if (!ast_strlen_zero(dev)) {
01688       ast_mutex_lock(&waresl.lock);
01689       cur = waresl.wares;
01690       while(cur) {
01691          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01692             res = ntohs(cur->fwh->version);
01693             break;
01694          }
01695          cur = cur->next;
01696       }
01697       ast_mutex_unlock(&waresl.lock);
01698    }
01699    return res;
01700 }
01701 
01702 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01703 {
01704    int res = -1;
01705    unsigned int bs = desc & 0xff;
01706    unsigned int start = (desc >> 8) & 0xffffff;
01707    unsigned int bytes;
01708    struct iax_firmware *cur;
01709    if (!ast_strlen_zero((char *)dev) && bs) {
01710       start *= bs;
01711       ast_mutex_lock(&waresl.lock);
01712       cur = waresl.wares;
01713       while(cur) {
01714          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01715             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01716             if (start < ntohl(cur->fwh->datalen)) {
01717                bytes = ntohl(cur->fwh->datalen) - start;
01718                if (bytes > bs)
01719                   bytes = bs;
01720                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01721             } else {
01722                bytes = 0;
01723                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01724             }
01725             if (bytes == bs)
01726                res = 0;
01727             else
01728                res = 1;
01729             break;
01730          }
01731          cur = cur->next;
01732       }
01733       ast_mutex_unlock(&waresl.lock);
01734    }
01735    return res;
01736 }
01737 
01738 
01739 static void reload_firmware(int unload)
01740 {
01741    struct iax_firmware *cur, *curl, *curp;
01742    DIR *fwd;
01743    struct dirent *de;
01744    char dir[256];
01745    char fn[256];
01746    /* Mark all as dead */
01747    ast_mutex_lock(&waresl.lock);
01748    cur = waresl.wares;
01749    while(cur) {
01750       cur->dead = 1;
01751       cur = cur->next;
01752    }
01753 
01754    /* Now that we've freed them, load the new ones */
01755    if (!unload) {
01756       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01757       fwd = opendir(dir);
01758       if (fwd) {
01759          while((de = readdir(fwd))) {
01760             if (de->d_name[0] != '.') {
01761                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01762                if (!try_firmware(fn)) {
01763                   if (option_verbose > 1)
01764                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01765                }
01766             }
01767          }
01768          closedir(fwd);
01769       } else 
01770          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01771    }
01772 
01773    /* Clean up leftovers */
01774    cur = waresl.wares;
01775    curp = NULL;
01776    while(cur) {
01777       curl = cur;
01778       cur = cur->next;
01779       if (curl->dead) {
01780          if (curp) {
01781             curp->next = cur;
01782          } else {
01783             waresl.wares = cur;
01784          }
01785          destroy_firmware(curl);
01786       } else {
01787          curp = cur;
01788       }
01789    }
01790    ast_mutex_unlock(&waresl.lock);
01791 }
01792 
01793 /*!
01794  * \note This function assumes that iaxsl[callno] is locked when called.
01795  *
01796  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01797  * was valid before calling it, it may no longer be valid after calling it.
01798  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
01799  * associated with this callno, meaning that another thread may grab it and destroy the call.
01800  */
01801 static int __do_deliver(void *data)
01802 {
01803    /* Just deliver the packet by using queueing.  This is called by
01804      the IAX thread with the iaxsl lock held. */
01805    struct iax_frame *fr = data;
01806    fr->retrans = -1;
01807    fr->af.has_timing_info = 0;
01808    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01809       iax2_queue_frame(fr->callno, &fr->af);
01810    /* Free our iax frame */
01811    iax2_frame_free(fr);
01812    /* And don't run again */
01813    return 0;
01814 }
01815 
01816 static int handle_error(void)
01817 {
01818    /* XXX Ideally we should figure out why an error occured and then abort those
01819       rather than continuing to try.  Unfortunately, the published interface does
01820       not seem to work XXX */
01821 #if 0
01822    struct sockaddr_in *sin;
01823    int res;
01824    struct msghdr m;
01825    struct sock_extended_err e;
01826    m.msg_name = NULL;
01827    m.msg_namelen = 0;
01828    m.msg_iov = NULL;
01829    m.msg_control = &e;
01830    m.msg_controllen = sizeof(e);
01831    m.msg_flags = 0;
01832    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01833    if (res < 0)
01834       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01835    else {
01836       if (m.msg_controllen) {
01837          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01838          if (sin) 
01839             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
01840          else
01841             ast_log(LOG_WARNING, "No address detected??\n");
01842       } else {
01843          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01844       }
01845    }
01846 #endif
01847    return 0;
01848 }
01849 
01850 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
01851 {
01852    int res;
01853    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01854                sizeof(*sin));
01855    if (res < 0) {
01856       if (option_debug)
01857          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01858       handle_error();
01859    } else
01860       res = 0;
01861    return res;
01862 }
01863 
01864 static int send_packet(struct iax_frame *f)
01865 {
01866    int res;
01867    int callno = f->callno;
01868 
01869    /* Don't send if there was an error, but return error instead */
01870    if (!callno || !iaxs[callno] || iaxs[callno]->error)
01871        return -1;
01872    
01873    /* Called with iaxsl held */
01874    if (option_debug > 2 && iaxdebug)
01875       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));
01876    if (f->transfer) {
01877       if (iaxdebug)
01878          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01879       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
01880                sizeof(iaxs[callno]->transfer));
01881    } else {
01882       if (iaxdebug)
01883          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01884       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
01885                sizeof(iaxs[callno]->addr));
01886    }
01887    if (res < 0) {
01888       if (option_debug && iaxdebug)
01889          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01890       handle_error();
01891    } else
01892       res = 0;
01893    return res;
01894 }
01895 
01896 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01897 {
01898    /* Decrement AUTHREQ count if needed */
01899    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01900       struct iax2_user *user;
01901       struct iax2_user tmp_user = {
01902          .name = pvt->username,
01903       };
01904 
01905       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01906       if (user) {
01907          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01908          user_unref(user); 
01909       }
01910 
01911       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01912    }
01913    /* No more pings or lagrq's */
01914    if (pvt->pingid > -1)
01915       ast_sched_del(sched, pvt->pingid);
01916    pvt->pingid = -1;
01917    if (pvt->lagid > -1)
01918       ast_sched_del(sched, pvt->lagid);
01919    pvt->lagid = -1;
01920    if (pvt->autoid > -1)
01921       ast_sched_del(sched, pvt->autoid);
01922    pvt->autoid = -1;
01923    if (pvt->authid > -1)
01924       ast_sched_del(sched, pvt->authid);
01925    pvt->authid = -1;
01926    if (pvt->initid > -1)
01927       ast_sched_del(sched, pvt->initid);
01928    pvt->initid = -1;
01929    if (pvt->jbid > -1)
01930       ast_sched_del(sched, pvt->jbid);
01931    pvt->jbid = -1;
01932 }
01933 
01934 /*!
01935  * \note Since this function calls iax2_queue_hangup(), the pvt struct
01936  *       for the given call number may disappear during its execution.
01937  */
01938 static int iax2_predestroy(int callno)
01939 {
01940    struct ast_channel *c;
01941    struct chan_iax2_pvt *pvt = iaxs[callno];
01942 
01943    if (!pvt)
01944       return -1;
01945    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01946       iax2_destroy_helper(pvt);
01947       ast_set_flag(pvt, IAX_ALREADYGONE); 
01948    }
01949    c = pvt->owner;
01950    if (c) {
01951       c->tech_pvt = NULL;
01952       iax2_queue_hangup(callno);
01953       pvt->owner = NULL;
01954       ast_module_unref(ast_module_info->self);
01955    }
01956    return 0;
01957 }
01958 
01959 static void iax2_destroy(int callno)
01960 {
01961    struct chan_iax2_pvt *pvt;
01962    struct iax_frame *cur;
01963    struct ast_channel *owner;
01964 
01965 retry:
01966    pvt = iaxs[callno];
01967    gettimeofday(&lastused[callno], NULL);
01968    
01969    owner = pvt ? pvt->owner : NULL;
01970 
01971    if (owner) {
01972       if (ast_mutex_trylock(&owner->lock)) {
01973          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01974          ast_mutex_unlock(&iaxsl[callno]);
01975          usleep(1);
01976          ast_mutex_lock(&iaxsl[callno]);
01977          goto retry;
01978       }
01979    }
01980    if (!owner)
01981       iaxs[callno] = NULL;
01982    if (pvt) {
01983       if (!owner)
01984          pvt->owner = NULL;
01985       iax2_destroy_helper(pvt);
01986 
01987       /* Already gone */
01988       ast_set_flag(pvt, IAX_ALREADYGONE); 
01989 
01990       if (owner) {
01991          /* If there's an owner, prod it to give up */
01992          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01993           * because we already hold the owner channel lock. */
01994          ast_queue_hangup(owner);
01995       }
01996 
01997       AST_LIST_LOCK(&iaxq.queue);
01998       AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01999          /* Cancel any pending transmissions */
02000          if (cur->callno == pvt->callno) 
02001             cur->retries = -1;
02002       }
02003       AST_LIST_UNLOCK(&iaxq.queue);
02004 
02005       if (pvt->reg)
02006          pvt->reg->callno = 0;
02007       if (!owner) {
02008          jb_frame frame;
02009          if (pvt->vars) {
02010              ast_variables_destroy(pvt->vars);
02011              pvt->vars = NULL;
02012          }
02013 
02014          while (jb_getall(pvt->jb, &frame) == JB_OK)
02015             iax2_frame_free(frame.data);
02016          jb_destroy(pvt->jb);
02017          /* gotta free up the stringfields */
02018          ast_string_field_free_memory(pvt);
02019          free(pvt);
02020       }
02021    }
02022    if (owner) {
02023       ast_mutex_unlock(&owner->lock);
02024    }
02025    if (callno & 0x4000)
02026       update_max_trunk();
02027 }
02028 
02029 static int update_packet(struct iax_frame *f)
02030 {
02031    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02032    struct ast_iax2_full_hdr *fh = f->data;
02033    /* Mark this as a retransmission */
02034    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02035    /* Update iseqno */
02036    f->iseqno = iaxs[f->callno]->iseqno;
02037    fh->iseqno = f->iseqno;
02038    return 0;
02039 }
02040 
02041 static int attempt_transmit(const void *data);
02042 static void __attempt_transmit(const void *data)
02043 {
02044    /* Attempt to transmit the frame to the remote peer...
02045       Called without iaxsl held. */
02046    struct iax_frame *f = (struct iax_frame *)data;
02047    int freeme=0;
02048    int callno = f->callno;
02049    /* Make sure this call is still active */
02050    if (callno) 
02051       ast_mutex_lock(&iaxsl[callno]);
02052    if (callno && iaxs[callno]) {
02053       if ((f->retries < 0) /* Already ACK'd */ ||
02054           (f->retries >= max_retries) /* Too many attempts */) {
02055             /* Record an error if we've transmitted too many times */
02056             if (f->retries >= max_retries) {
02057                if (f->transfer) {
02058                   /* Transfer timeout */
02059                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02060                } else if (f->final) {
02061                   if (f->final) 
02062                      iax2_destroy(callno);
02063                } else {
02064                   if (iaxs[callno]->owner)
02065                      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);
02066                   iaxs[callno]->error = ETIMEDOUT;
02067                   if (iaxs[callno]->owner) {
02068                      struct ast_frame fr = { 0, };
02069                      /* Hangup the fd */
02070                      fr.frametype = AST_FRAME_CONTROL;
02071                      fr.subclass = AST_CONTROL_HANGUP;
02072                      iax2_queue_frame(callno, &fr); // XXX
02073                      /* Remember, owner could disappear */
02074                      if (iaxs[callno] && iaxs[callno]->owner)
02075                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02076                   } else {
02077                      if (iaxs[callno]->reg) {
02078                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02079                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02080                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02081                      }
02082                      iax2_destroy(callno);
02083                   }
02084                }
02085 
02086             }
02087             freeme++;
02088       } else {
02089          /* Update it if it needs it */
02090          update_packet(f);
02091          /* Attempt transmission */
02092          send_packet(f);
02093          f->retries++;
02094          /* Try again later after 10 times as long */
02095          f->retrytime *= 10;
02096          if (f->retrytime > MAX_RETRY_TIME)
02097             f->retrytime = MAX_RETRY_TIME;
02098          /* Transfer messages max out at one second */
02099          if (f->transfer && (f->retrytime > 1000))
02100             f->retrytime = 1000;
02101          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02102       }
02103    } else {
02104       /* Make sure it gets freed */
02105       f->retries = -1;
02106       freeme++;
02107    }
02108    if (callno)
02109       ast_mutex_unlock(&iaxsl[callno]);
02110    /* Do not try again */
02111    if (freeme) {
02112       /* Don't attempt delivery, just remove it from the queue */
02113       AST_LIST_LOCK(&iaxq.queue);
02114       AST_LIST_REMOVE(&iaxq.queue, f, list);
02115       iaxq.count--;
02116       AST_LIST_UNLOCK(&iaxq.queue);
02117       f->retrans = -1;
02118       /* Free the IAX frame */
02119       iax2_frame_free(f);
02120    }
02121 }
02122 
02123 static int attempt_transmit(const void *data)
02124 {
02125 #ifdef SCHED_MULTITHREADED
02126    if (schedule_action(__attempt_transmit, data))
02127 #endif      
02128       __attempt_transmit(data);
02129    return 0;
02130 }
02131 
02132 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02133 {
02134    struct iax2_peer *peer;
02135 
02136    if (argc != 4)
02137         return RESULT_SHOWUSAGE;
02138    if (!strcmp(argv[3],"all")) {
02139       reload_config();
02140       ast_cli(fd, "OK cache is flushed.\n");
02141    } else if ((peer = find_peer(argv[3], 0))) {
02142       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02143          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02144          expire_registry(peer_ref(peer));
02145          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02146       } else {
02147          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02148       }
02149       peer_unref(peer);
02150    } else {
02151       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02152    }
02153    
02154    return RESULT_SUCCESS;
02155 }
02156 
02157 static int iax2_test_losspct(int fd, int argc, char *argv[])
02158 {
02159        if (argc != 4)
02160                return RESULT_SHOWUSAGE;
02161 
02162        test_losspct = atoi(argv[3]);
02163 
02164        return RESULT_SUCCESS;
02165 }
02166 
02167 #ifdef IAXTESTS
02168 static int iax2_test_late(int fd, int argc, char *argv[])
02169 {
02170    if (argc != 4)
02171       return RESULT_SHOWUSAGE;
02172 
02173    test_late = atoi(argv[3]);
02174 
02175    return RESULT_SUCCESS;
02176 }
02177 
02178 static int iax2_test_resync(int fd, int argc, char *argv[])
02179 {
02180    if (argc != 4)
02181       return RESULT_SHOWUSAGE;
02182 
02183    test_resync = atoi(argv[3]);
02184 
02185    return RESULT_SUCCESS;
02186 }
02187 
02188 static int iax2_test_jitter(int fd, int argc, char *argv[])
02189 {
02190    if (argc < 4 || argc > 5)
02191       return RESULT_SHOWUSAGE;
02192 
02193    test_jit = atoi(argv[3]);
02194    if (argc == 5) 
02195       test_jitpct = atoi(argv[4]);
02196 
02197    return RESULT_SUCCESS;
02198 }
02199 #endif /* IAXTESTS */
02200 
02201 /*! \brief  peer_status: Report Peer status in character string */
02202 /*    returns 1 if peer is online, -1 if unmonitored */
02203 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02204 {
02205    int res = 0;
02206    if (peer->maxms) {
02207       if (peer->lastms < 0) {
02208          ast_copy_string(status, "UNREACHABLE", statuslen);
02209       } else if (peer->lastms > peer->maxms) {
02210          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02211          res = 1;
02212       } else if (peer->lastms) {
02213          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02214          res = 1;
02215       } else {
02216          ast_copy_string(status, "UNKNOWN", statuslen);
02217       }
02218    } else { 
02219       ast_copy_string(status, "Unmonitored", statuslen);
02220       res = -1;
02221    }
02222    return res;
02223 }
02224 
02225 /*! \brief Show one peer in detail */
02226 static int iax2_show_peer(int fd, int argc, char *argv[])
02227 {
02228    char status[30];
02229    char cbuf[256];
02230    struct iax2_peer *peer;
02231    char codec_buf[512];
02232    int x = 0, codec = 0, load_realtime = 0;
02233 
02234    if (argc < 4)
02235       return RESULT_SHOWUSAGE;
02236 
02237    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02238 
02239    peer = find_peer(argv[3], load_realtime);
02240    if (peer) {
02241       ast_cli(fd,"\n\n");
02242       ast_cli(fd, "  * Name       : %s\n", peer->name);
02243       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02244       ast_cli(fd, "  Context      : %s\n", peer->context);
02245       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02246       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02247       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02248       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02249       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02250       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));
02251       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02252       ast_cli(fd, "  Username     : %s\n", peer->username);
02253       ast_cli(fd, "  Codecs       : ");
02254       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02255       ast_cli(fd, "%s\n", codec_buf);
02256 
02257       ast_cli(fd, "  Codec Order  : (");
02258       for(x = 0; x < 32 ; x++) {
02259          codec = ast_codec_pref_index(&peer->prefs,x);
02260          if(!codec)
02261             break;
02262          ast_cli(fd, "%s", ast_getformatname(codec));
02263          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02264             ast_cli(fd, "|");
02265       }
02266 
02267       if (!x)
02268          ast_cli(fd, "none");
02269       ast_cli(fd, ")\n");
02270 
02271       ast_cli(fd, "  Status       : ");
02272       peer_status(peer, status, sizeof(status));   
02273       ast_cli(fd, "%s\n",status);
02274       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02275       ast_cli(fd,"\n");
02276       peer_unref(peer);
02277    } else {
02278       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02279       ast_cli(fd,"\n");
02280    }
02281 
02282    return RESULT_SUCCESS;
02283 }
02284 
02285 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02286 {
02287    int which = 0;
02288    struct iax2_peer *peer;
02289    char *res = NULL;
02290    int wordlen = strlen(word);
02291    struct ao2_iterator i;
02292 
02293    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02294    if (pos != 3)
02295       return NULL;
02296 
02297    i = ao2_iterator_init(peers, 0);
02298    while ((peer = ao2_iterator_next(&i))) {
02299       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02300          res = ast_strdup(peer->name);
02301          peer_unref(peer);
02302          break;
02303       }
02304       peer_unref(peer);
02305    }
02306 
02307    return res;
02308 }
02309 
02310 static int iax2_show_stats(int fd, int argc, char *argv[])
02311 {
02312    struct iax_frame *cur;
02313    int cnt = 0, dead=0, final=0;
02314 
02315    if (argc != 3)
02316       return RESULT_SHOWUSAGE;
02317 
02318    AST_LIST_LOCK(&iaxq.queue);
02319    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02320       if (cur->retries < 0)
02321          dead++;
02322       if (cur->final)
02323          final++;
02324       cnt++;
02325    }
02326    AST_LIST_UNLOCK(&iaxq.queue);
02327 
02328    ast_cli(fd, "    IAX Statistics\n");
02329    ast_cli(fd, "---------------------\n");
02330    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02331    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02332    
02333    return RESULT_SUCCESS;
02334 }
02335 
02336 static int iax2_show_cache(int fd, int argc, char *argv[])
02337 {
02338    struct iax2_dpcache *dp;
02339    char tmp[1024], *pc;
02340    int s;
02341    int x,y;
02342    struct timeval tv;
02343    gettimeofday(&tv, NULL);
02344    ast_mutex_lock(&dpcache_lock);
02345    dp = dpcache;
02346    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02347    while(dp) {
02348       s = dp->expiry.tv_sec - tv.tv_sec;
02349       tmp[0] = '\0';
02350       if (dp->flags & CACHE_FLAG_EXISTS)
02351          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02352       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02353          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02354       if (dp->flags & CACHE_FLAG_CANEXIST)
02355          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02356       if (dp->flags & CACHE_FLAG_PENDING)
02357          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02358       if (dp->flags & CACHE_FLAG_TIMEOUT)
02359          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02360       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02361          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02362       if (dp->flags & CACHE_FLAG_MATCHMORE)
02363          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02364       if (dp->flags & CACHE_FLAG_UNKNOWN)
02365          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02366       /* Trim trailing pipe */
02367       if (!ast_strlen_zero(tmp))
02368          tmp[strlen(tmp) - 1] = '\0';
02369       else
02370          ast_copy_string(tmp, "(none)", sizeof(tmp));
02371       y=0;
02372       pc = strchr(dp->peercontext, '@');
02373       if (!pc)
02374          pc = dp->peercontext;
02375       else
02376          pc++;
02377       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02378          if (dp->waiters[x] > -1)
02379             y++;
02380       if (s > 0)
02381          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02382       else
02383          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02384       dp = dp->next;
02385    }
02386    ast_mutex_unlock(&dpcache_lock);
02387    return RESULT_SUCCESS;
02388 }
02389 
02390 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02391 
02392 static void unwrap_timestamp(struct iax_frame *fr)
02393 {
02394    int x;
02395 
02396    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02397       x = fr->ts - iaxs[fr->callno]->last;
02398       if (x < -50000) {
02399          /* Sudden big jump backwards in timestamp:
02400             What likely happened here is that miniframe timestamp has circled but we haven't
02401             gotten the update from the main packet.  We'll just pretend that we did, and
02402             update the timestamp appropriately. */
02403          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02404          if (option_debug && iaxdebug)
02405             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02406       }
02407       if (x > 50000) {
02408          /* Sudden apparent big jump forwards in timestamp:
02409             What's likely happened is this is an old miniframe belonging to the previous
02410             top-16-bit timestamp that has turned up out of order.
02411             Adjust the timestamp appropriately. */
02412          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02413          if (option_debug && iaxdebug)
02414             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02415       }
02416    }
02417 }
02418 
02419 static int get_from_jb(const void *p);
02420 
02421 static void update_jbsched(struct chan_iax2_pvt *pvt)
02422 {
02423    int when;
02424    
02425    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02426    
02427    when = jb_next(pvt->jb) - when;
02428    
02429    if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02430    
02431    if(when <= 0) {
02432       /* XXX should really just empty until when > 0.. */
02433       when = 1;
02434    }
02435    
02436    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02437 }
02438 
02439 static void __get_from_jb(const void *p) 
02440 {
02441    int callno = PTR_TO_CALLNO(p);
02442    struct chan_iax2_pvt *pvt = NULL;
02443    struct iax_frame *fr;
02444    jb_frame frame;
02445    int ret;
02446    long now;
02447    long next;
02448    struct timeval tv;
02449    
02450    /* Make sure we have a valid private structure before going on */
02451    ast_mutex_lock(&iaxsl[callno]);
02452    pvt = iaxs[callno];
02453    if (!pvt) {
02454       /* No go! */
02455       ast_mutex_unlock(&iaxsl[callno]);
02456       return;
02457    }
02458 
02459    pvt->jbid = -1;
02460    
02461    gettimeofday(&tv,NULL);
02462    /* round up a millisecond since ast_sched_runq does; */
02463    /* prevents us from spinning while waiting for our now */
02464    /* to catch up with runq's now */
02465    tv.tv_usec += 1000;
02466    
02467    now = ast_tvdiff_ms(tv, pvt->rxcore);
02468    
02469    if(now >= (next = jb_next(pvt->jb))) {
02470       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02471       switch(ret) {
02472       case JB_OK:
02473          fr = frame.data;
02474          __do_deliver(fr);
02475          /* __do_deliver() can cause the call to disappear */
02476          pvt = iaxs[callno];
02477          break;
02478       case JB_INTERP:
02479       {
02480          struct ast_frame af = { 0, };
02481          
02482          /* create an interpolation frame */
02483          af.frametype = AST_FRAME_VOICE;
02484          af.subclass = pvt->voiceformat;
02485          af.samples  = frame.ms * 8;
02486          af.src  = "IAX2 JB interpolation";
02487          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02488          af.offset = AST_FRIENDLY_OFFSET;
02489          
02490          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02491           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02492          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02493             iax2_queue_frame(callno, &af);
02494             /* iax2_queue_frame() could cause the call to disappear */
02495             pvt = iaxs[callno];
02496          }
02497       }
02498          break;
02499       case JB_DROP:
02500          iax2_frame_free(frame.data);
02501          break;
02502       case JB_NOFRAME:
02503       case JB_EMPTY:
02504          /* do nothing */
02505          break;
02506       default:
02507          /* shouldn't happen */
02508          break;
02509       }
02510    }
02511    if (pvt)
02512       update_jbsched(pvt);
02513    ast_mutex_unlock(&iaxsl[callno]);
02514 }
02515 
02516 static int get_from_jb(const void *data)
02517 {
02518 #ifdef SCHED_MULTITHREADED
02519    if (schedule_action(__get_from_jb, data))
02520 #endif      
02521       __get_from_jb(data);
02522    return 0;
02523 }
02524 
02525 /*!
02526  * \note This function assumes fr->callno is locked
02527  *
02528  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02529  * was valid before calling it, it may no longer be valid after calling it.
02530  */
02531 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02532 {
02533    int type, len;
02534    int ret;
02535    int needfree = 0;
02536 
02537    /* Attempt to recover wrapped timestamps */
02538    unwrap_timestamp(fr);
02539 
02540    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02541    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02542       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02543    else {
02544 #if 0
02545       if (option_debug)
02546          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02547 #endif
02548       fr->af.delivery = ast_tv(0,0);
02549    }
02550 
02551    type = JB_TYPE_CONTROL;
02552    len = 0;
02553 
02554    if(fr->af.frametype == AST_FRAME_VOICE) {
02555       type = JB_TYPE_VOICE;
02556       len = ast_codec_get_samples(&fr->af) / 8;
02557    } else if(fr->af.frametype == AST_FRAME_CNG) {
02558       type = JB_TYPE_SILENCE;
02559    }
02560 
02561    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02562       if (tsout)
02563          *tsout = fr->ts;
02564       __do_deliver(fr);
02565       return -1;
02566    }
02567 
02568    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02569     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02570    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
02571        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
02572        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
02573       jb_frame frame;
02574 
02575       /* deliver any frames in the jb */
02576       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02577          __do_deliver(frame.data);
02578          /* __do_deliver() can make the call disappear */
02579          if (!iaxs[fr->callno])
02580             return -1;
02581       }
02582 
02583       jb_reset(iaxs[fr->callno]->jb);
02584 
02585       if (iaxs[fr->callno]->jbid > -1)
02586          ast_sched_del(sched, iaxs[fr->callno]->jbid);
02587 
02588       iaxs[fr->callno]->jbid = -1;
02589 
02590       /* deliver this frame now */
02591       if (tsout)
02592          *tsout = fr->ts;
02593       __do_deliver(fr);
02594       return -1;
02595    }
02596 
02597    /* insert into jitterbuffer */
02598    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02599    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02600          calc_rxstamp(iaxs[fr->callno],fr->ts));
02601    if (ret == JB_DROP) {
02602       needfree++;
02603    } else if (ret == JB_SCHED) {
02604       update_jbsched(iaxs[fr->callno]);
02605    }
02606    if (tsout)
02607       *tsout = fr->ts;
02608    if (needfree) {
02609       /* Free our iax frame */
02610       iax2_frame_free(fr);
02611       return -1;
02612    }
02613    return 0;
02614 }
02615 
02616 static int iax2_transmit(struct iax_frame *fr)
02617 {
02618    /* Lock the queue and place this packet at the end */
02619    /* By setting this to 0, the network thread will send it for us, and
02620       queue retransmission if necessary */
02621    fr->sentyet = 0;
02622    AST_LIST_LOCK(&iaxq.queue);
02623    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02624    iaxq.count++;
02625    AST_LIST_UNLOCK(&iaxq.queue);
02626    /* Wake up the network and scheduler thread */
02627    if (netthreadid != AST_PTHREADT_NULL)
02628       pthread_kill(netthreadid, SIGURG);
02629    signal_condition(&sched_lock, &sched_cond);
02630    return 0;
02631 }
02632 
02633 
02634 
02635 static int iax2_digit_begin(struct ast_channel *c, char digit)
02636 {
02637    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02638 }
02639 
02640 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02641 {
02642    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02643 }
02644 
02645 static int iax2_sendtext(struct ast_channel *c, const char *dest, const char *text, int ispdu)
02646 {
02647    
02648    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02649       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02650 }
02651 
02652 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02653 {
02654    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02655 }
02656 
02657 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02658 {
02659    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02660 }
02661 
02662 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02663 {
02664    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02665    ast_mutex_lock(&iaxsl[callno]);
02666    if (iaxs[callno])
02667       iaxs[callno]->owner = newchan;
02668    else
02669       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02670    ast_mutex_unlock(&iaxsl[callno]);
02671    return 0;
02672 }
02673 
02674 /*!
02675  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02676  *       so do not call this with a pvt lock held.
02677  */
02678 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02679 {
02680    struct ast_variable *var = NULL;
02681    struct ast_variable *tmp;
02682    struct iax2_peer *peer=NULL;
02683    time_t regseconds = 0, nowtime;
02684    int dynamic=0;
02685 
02686    if (peername) {
02687       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02688       if (!var && sin)
02689          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr));
02690    } else if (sin) {
02691       char porta[25];
02692       sprintf(porta, "%d", ntohs(sin->sin_port));
02693       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02694       if (var) {
02695          /* We'll need the peer name in order to build the structure! */
02696          for (tmp = var; tmp; tmp = tmp->next) {
02697             if (!strcasecmp(tmp->name, "name"))
02698                peername = tmp->value;
02699          }
02700       }
02701    }
02702    if (!var && peername) { /* Last ditch effort */
02703       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02704       /*!\note
02705        * If this one loaded something, then we need to ensure that the host
02706        * field matched.  The only reason why we can't have this as a criteria
02707        * is because we only have the IP address and the host field might be
02708        * set as a name (and the reverse PTR might not match).
02709        */
02710       if (var && sin) {
02711          for (tmp = var; tmp; tmp = tmp->next) {
02712             if (!strcasecmp(tmp->name, "host")) {
02713                struct in_addr sin2 = { 0, };
02714                struct ast_dnsmgr_entry *dnsmgr = NULL;
02715                if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
02716                   /* No match */
02717                   ast_variables_destroy(var);
02718                   var = NULL;
02719                }
02720                break;
02721             }
02722          }
02723       }
02724    }
02725    if (!var)
02726       return NULL;
02727 
02728    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02729    
02730    if (!peer) {
02731       ast_variables_destroy(var);
02732       return NULL;
02733    }
02734 
02735    for (tmp = var; tmp; tmp = tmp->next) {
02736       /* Make sure it's not a user only... */
02737       if (!strcasecmp(tmp->name, "type")) {
02738          if (strcasecmp(tmp->value, "friend") &&
02739              strcasecmp(tmp->value, "peer")) {
02740             /* Whoops, we weren't supposed to exist! */
02741             peer = peer_unref(peer);
02742             break;
02743          } 
02744       } else if (!strcasecmp(tmp->name, "regseconds")) {
02745          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02746       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02747          inet_aton(tmp->value, &(peer->addr.sin_addr));
02748       } else if (!strcasecmp(tmp->name, "port")) {
02749          peer->addr.sin_port = htons(atoi(tmp->value));
02750       } else if (!strcasecmp(tmp->name, "host")) {
02751          if (!strcasecmp(tmp->value, "dynamic"))
02752             dynamic = 1;
02753       }
02754    }
02755 
02756    ast_variables_destroy(var);
02757 
02758    if (!peer)
02759       return NULL;
02760 
02761    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02762       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02763       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02764          if (peer->expire > -1) {
02765             if (!ast_sched_del(sched, peer->expire)) {
02766                peer->expire = -1;
02767                peer_unref(peer);
02768             }
02769          }
02770          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02771          if (peer->expire == -1)
02772             peer_unref(peer);
02773       }
02774       ao2_link(peers, peer);
02775       if (ast_test_flag(peer, IAX_DYNAMIC))
02776          reg_source_db(peer);
02777    } else {
02778       ast_set_flag(peer, IAX_TEMPONLY);   
02779    }
02780 
02781    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02782       time(&nowtime);
02783       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02784          memset(&peer->addr, 0, sizeof(peer->addr));
02785          realtime_update_peer(peer->name, &peer->addr, 0);
02786          if (option_debug)
02787             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02788                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02789       }
02790       else {
02791          if (option_debug)
02792             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02793                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02794       }
02795    }
02796 
02797    return peer;
02798 }
02799 
02800 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02801 {
02802    struct ast_variable *var;
02803    struct ast_variable *tmp;
02804    struct iax2_user *user=NULL;
02805 
02806    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02807    if (!var)
02808       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr));
02809    if (!var && sin) {
02810       char porta[6];
02811       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02812       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02813       if (!var)
02814          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02815    }
02816    if (!var) { /* Last ditch effort */
02817       var = ast_load_realtime("iaxusers", "name", username, NULL);
02818       /*!\note
02819        * If this one loaded something, then we need to ensure that the host
02820        * field matched.  The only reason why we can't have this as a criteria
02821        * is because we only have the IP address and the host field might be
02822        * set as a name (and the reverse PTR might not match).
02823        */
02824       if (var) {
02825          for (tmp = var; tmp; tmp = tmp->next) {
02826             if (!strcasecmp(tmp->name, "host")) {
02827                struct in_addr sin2 = { 0, };
02828                struct ast_dnsmgr_entry *dnsmgr = NULL;
02829                if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
02830                   /* No match */
02831                   ast_variables_destroy(var);
02832                   var = NULL;
02833                }
02834                break;
02835             }
02836          }
02837       }
02838    }
02839    if (!var)
02840       return NULL;
02841 
02842    tmp = var;
02843    while(tmp) {
02844       /* Make sure it's not a peer only... */
02845       if (!strcasecmp(tmp->name, "type")) {
02846          if (strcasecmp(tmp->value, "friend") &&
02847              strcasecmp(tmp->value, "user")) {
02848             return NULL;
02849          } 
02850       }
02851       tmp = tmp->next;
02852    }
02853 
02854    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02855 
02856    ast_variables_destroy(var);
02857 
02858    if (!user)
02859       return NULL;
02860 
02861    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02862       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02863       ao2_link(users, user);
02864    } else {
02865       ast_set_flag(user, IAX_TEMPONLY);   
02866    }
02867 
02868    return user;
02869 }
02870 
02871 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02872 {
02873    char port[10];
02874    char regseconds[20];
02875    
02876    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02877    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02878    ast_update_realtime("iaxpeers", "name", peername, 
02879       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02880       "regseconds", regseconds, NULL);
02881 }
02882 
02883 struct create_addr_info {
02884    int capability;
02885    unsigned int flags;
02886    int maxtime;
02887    int encmethods;
02888    int found;
02889    int sockfd;
02890    int adsi;
02891    char username[80];
02892    char secret[80];
02893    char outkey[80];
02894    char timezone[80];
02895    char prefs[32];
02896    char context[AST_MAX_CONTEXT];
02897    char peercontext[AST_MAX_CONTEXT];
02898    char mohinterpret[MAX_MUSICCLASS];
02899    char mohsuggest[MAX_MUSICCLASS];
02900 };
02901 
02902 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02903 {
02904    struct ast_hostent ahp;
02905    struct hostent *hp;
02906    struct iax2_peer *peer;
02907    int res = -1;
02908 
02909    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02910    cai->sockfd = defaultsockfd;
02911    cai->maxtime = 0;
02912    sin->sin_family = AF_INET;
02913 
02914    if (!(peer = find_peer(peername, 1))) {
02915       cai->found = 0;
02916 
02917       hp = ast_gethostbyname(peername, &ahp);
02918       if (hp) {
02919          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02920          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02921          /* use global iax prefs for unknown peer/user */
02922          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02923          return 0;
02924       } else {
02925          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02926          return -1;
02927       }
02928    }
02929 
02930    cai->found = 1;
02931    
02932    /* if the peer has no address (current or default), return failure */
02933    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
02934       goto return_unref;
02935 
02936    /* if the peer is being monitored and is currently unreachable, return failure */
02937    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
02938       goto return_unref;
02939 
02940    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02941    cai->maxtime = peer->maxms;
02942    cai->capability = peer->capability;
02943    cai->encmethods = peer->encmethods;
02944    cai->sockfd = peer->sockfd;
02945    cai->adsi = peer->adsi;
02946    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02947    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02948    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02949    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02950    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02951    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02952    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02953    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02954    if (ast_strlen_zero(peer->dbsecret)) {
02955       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02956    } else {
02957       char *family;
02958       char *key = NULL;
02959 
02960       family = ast_strdupa(peer->dbsecret);
02961       key = strchr(family, '/');
02962       if (key)
02963          *key++ = '\0';
02964       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02965          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02966          goto return_unref;
02967       }
02968    }
02969 
02970    if (peer->addr.sin_addr.s_addr) {
02971       sin->sin_addr = peer->addr.sin_addr;
02972       sin->sin_port = peer->addr.sin_port;
02973    } else {
02974       sin->sin_addr = peer->defaddr.sin_addr;
02975       sin->sin_port = peer->defaddr.sin_port;
02976    }
02977 
02978    res = 0;
02979 
02980 return_unref:
02981    peer_unref(peer);
02982 
02983    return res;
02984 }
02985 
02986 static void __auto_congest(const void *nothing)
02987 {
02988    int callno = PTR_TO_CALLNO(nothing);
02989    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02990    ast_mutex_lock(&iaxsl[callno]);
02991    if (iaxs[callno]) {
02992       iaxs[callno]->initid = -1;
02993       iax2_queue_frame(callno, &f);
02994       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02995    }
02996    ast_mutex_unlock(&iaxsl[callno]);
02997 }
02998 
02999 static int auto_congest(const void *data)
03000 {
03001 #ifdef SCHED_MULTITHREADED
03002    if (schedule_action(__auto_congest, data))
03003 #endif      
03004       __auto_congest(data);
03005    return 0;
03006 }
03007 
03008 static unsigned int iax2_datetime(const char *tz)
03009 {
03010    time_t t;
03011    struct tm tm;
03012    unsigned int tmp;
03013    time(&t);
03014    if (!ast_strlen_zero(tz))
03015       ast_localtime(&t, &tm, tz);
03016    else
03017       ast_localtime(&t, &tm, NULL);
03018    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03019    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03020    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03021    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03022    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03023    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03024    return tmp;
03025 }
03026 
03027 struct parsed_dial_string {
03028    char *username;
03029    char *password;
03030    char *key;
03031    char *peer;
03032    char *port;
03033    char *exten;
03034    char *context;
03035    char *options;
03036 };
03037 
03038 /*!
03039  * \brief Parses an IAX dial string into its component parts.
03040  * \param data the string to be parsed
03041  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03042  * \return nothing
03043  *
03044  * This function parses the string and fills the structure
03045  * with pointers to its component parts. The input string
03046  * will be modified.
03047  *
03048  * \note This function supports both plaintext passwords and RSA
03049  * key names; if the password string is formatted as '[keyname]',
03050  * then the keyname will be placed into the key field, and the
03051  * password field will be set to NULL.
03052  *
03053  * \note The dial string format is:
03054  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03055  */
03056 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03057 {
03058    if (ast_strlen_zero(data))
03059       return;
03060 
03061    pds->peer = strsep(&data, "/");
03062    pds->exten = strsep(&data, "/");
03063    pds->options = data;
03064 
03065    if (pds->exten) {
03066       data = pds->exten;
03067       pds->exten = strsep(&data, "@");
03068       pds->context = data;
03069    }
03070 
03071    if (strchr(pds->peer, '@')) {
03072       data = pds->peer;
03073       pds->username = strsep(&data, "@");
03074       pds->peer = data;
03075    }
03076 
03077    if (pds->username) {
03078       data = pds->username;
03079       pds->username = strsep(&data, ":");
03080       pds->password = data;
03081    }
03082 
03083    data = pds->peer;
03084    pds->peer = strsep(&data, ":");
03085    pds->port = data;
03086 
03087    /* check for a key name wrapped in [] in the secret position, if found,
03088       move it to the key field instead
03089    */
03090    if (pds->password && (pds->password[0] == '[')) {
03091       pds->key = ast_strip_quoted(pds->password, "[", "]");
03092       pds->password = NULL;
03093    }
03094 }
03095 
03096 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03097 {
03098    struct sockaddr_in sin;
03099    char *l=NULL, *n=NULL, *tmpstr;
03100    struct iax_ie_data ied;
03101    char *defaultrdest = "s";
03102    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03103    struct parsed_dial_string pds;
03104    struct create_addr_info cai;
03105 
03106    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03107       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03108       return -1;
03109    }
03110 
03111    memset(&cai, 0, sizeof(cai));
03112    cai.encmethods = iax2_encryption;
03113 
03114    memset(&pds, 0, sizeof(pds));
03115    tmpstr = ast_strdupa(dest);
03116    parse_dial_string(tmpstr, &pds);
03117 
03118    if (!pds.exten)
03119       pds.exten = defaultrdest;
03120 
03121    if (create_addr(pds.peer, &sin, &cai)) {
03122       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03123       return -1;
03124    }
03125 
03126    if (!pds.username && !ast_strlen_zero(cai.username))
03127       pds.username = cai.username;
03128    if (!pds.password && !ast_strlen_zero(cai.secret))
03129       pds.password = cai.secret;
03130    if (!pds.key && !ast_strlen_zero(cai.outkey))
03131       pds.key = cai.outkey;
03132    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03133       pds.context = cai.peercontext;
03134 
03135    /* Keep track of the context for outgoing calls too */
03136    ast_copy_string(c->context, cai.context, sizeof(c->context));
03137 
03138    if (pds.port)
03139       sin.sin_port = htons(atoi(pds.port));
03140 
03141    l = c->cid.cid_num;
03142    n = c->cid.cid_name;
03143 
03144    /* Now build request */ 
03145    memset(&ied, 0, sizeof(ied));
03146 
03147    /* On new call, first IE MUST be IAX version of caller */
03148    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03149    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03150    if (pds.options && strchr(pds.options, 'a')) {
03151       /* Request auto answer */
03152       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03153    }
03154 
03155    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03156 
03157    if (l) {
03158       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03159       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03160    } else {
03161       if (n)
03162          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03163       else
03164          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03165    }
03166 
03167    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03168    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03169 
03170    if (n)
03171       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03172    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03173       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03174 
03175    if (!ast_strlen_zero(c->language))
03176       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03177    if (!ast_strlen_zero(c->cid.cid_dnid))
03178       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03179    if (!ast_strlen_zero(c->cid.cid_rdnis))
03180       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03181 
03182    if (pds.context)
03183       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03184 
03185    if (pds.username)
03186       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03187 
03188    if (cai.encmethods)
03189       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03190 
03191    ast_mutex_lock(&iaxsl[callno]);
03192 
03193    if (!ast_strlen_zero(c->context))
03194       ast_string_field_set(iaxs[callno], context, c->context);
03195 
03196    if (pds.username)
03197       ast_string_field_set(iaxs[callno], username, pds.username);
03198 
03199    iaxs[callno]->encmethods = cai.encmethods;
03200 
03201    iaxs[callno]->adsi = cai.adsi;
03202    
03203    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03204    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03205 
03206    if (pds.key)
03207       ast_string_field_set(iaxs[callno], outkey, pds.key);
03208    if (pds.password)
03209       ast_string_field_set(iaxs[callno], secret, pds.password);
03210 
03211    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03212    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03213    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03214    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03215 
03216    if (iaxs[callno]->maxtime) {
03217       /* Initialize pingtime and auto-congest time */
03218       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03219       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03220    } else if (autokill) {
03221       iaxs[callno]->pingtime = autokill / 2;
03222       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03223    }
03224 
03225    /* send the command using the appropriate socket for this peer */
03226    iaxs[callno]->sockfd = cai.sockfd;
03227 
03228    /* Transmit the string in a "NEW" request */
03229    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03230 
03231    ast_mutex_unlock(&iaxsl[callno]);
03232    ast_setstate(c, AST_STATE_RINGING);
03233    
03234    return 0;
03235 }
03236 
03237 static int iax2_hangup(struct ast_channel *c) 
03238 {
03239    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03240    int alreadygone;
03241    struct iax_ie_data ied;
03242    memset(&ied, 0, sizeof(ied));
03243    ast_mutex_lock(&iaxsl[callno]);
03244    if (callno && iaxs[callno]) {
03245       if (option_debug)
03246          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03247       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03248       /* Send the hangup unless we have had a transmission error or are already gone */
03249       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03250       if (!iaxs[callno]->error && !alreadygone) {
03251          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03252          if (!iaxs[callno]) {
03253             ast_mutex_unlock(&iaxsl[callno]);
03254             return 0;
03255          }
03256       }
03257       /* Explicitly predestroy it */
03258       iax2_predestroy(callno);
03259       /* If we were already gone to begin with, destroy us now */
03260       if (alreadygone && iaxs[callno]) {
03261          if (option_debug)
03262             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03263          iax2_destroy(callno);
03264       }
03265    }
03266    ast_mutex_unlock(&iaxsl[callno]);
03267    if (option_verbose > 2) 
03268       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03269    return 0;
03270 }
03271 
03272 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03273 {
03274    struct ast_option_header *h;
03275    int res;
03276 
03277    switch (option) {
03278    case AST_OPTION_TXGAIN:
03279    case AST_OPTION_RXGAIN:
03280       /* these two cannot be sent, because they require a result */
03281       errno = ENOSYS;
03282       return -1;
03283    default:
03284       if (!(h = ast_malloc(datalen + sizeof(*h))))
03285          return -1;
03286 
03287       h->flag = AST_OPTION_FLAG_REQUEST;
03288       h->option = htons(option);
03289       memcpy(h->data, data, datalen);
03290       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03291                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03292                  datalen + sizeof(*h), -1);
03293       free(h);
03294       return res;
03295    }
03296 }
03297 
03298 static struct ast_frame *iax2_read(struct ast_channel *c) 
03299 {
03300    if (option_verbose > 3)
03301        ast_log(LOG_NOTICE, "I should never be called!\n");
03302    return &ast_null_frame;
03303 }
03304 
03305 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03306 {
03307    int res;
03308    struct iax_ie_data ied0;
03309    struct iax_ie_data ied1;
03310    unsigned int transferid = (unsigned int)ast_random();
03311    memset(&ied0, 0, sizeof(ied0));
03312    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03313    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03314    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03315 
03316    memset(&ied1, 0, sizeof(ied1));
03317    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03318    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03319    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03320    
03321    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03322    if (res)
03323       return -1;
03324    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03325    if (res)
03326       return -1;
03327    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03328    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03329    return 0;
03330 }
03331 
03332 static void lock_both(unsigned short callno0, unsigned short callno1)
03333 {
03334    ast_mutex_lock(&iaxsl[callno0]);
03335    while (ast_mutex_trylock(&iaxsl[callno1])) {
03336       ast_mutex_unlock(&iaxsl[callno0]);
03337       usleep(10);
03338       ast_mutex_lock(&iaxsl[callno0]);
03339    }
03340 }
03341 
03342 static void unlock_both(unsigned short callno0, unsigned short callno1)
03343 {
03344    ast_mutex_unlock(&iaxsl[callno1]);
03345    ast_mutex_unlock(&iaxsl[callno0]);
03346 }
03347 
03348 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)
03349 {
03350    struct ast_channel *cs[3];
03351    struct ast_channel *who, *other;
03352    int to = -1;
03353    int res = -1;
03354    int transferstarted=0;
03355    struct ast_frame *f;
03356    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03357    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03358    struct timeval waittimer = {0, 0}, tv;
03359 
03360    lock_both(callno0, callno1);
03361    if (!iaxs[callno0] || !iaxs[callno1]) {
03362       unlock_both(callno0, callno1);
03363       return AST_BRIDGE_FAILED;
03364    }
03365    /* Put them in native bridge mode */
03366    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03367       iaxs[callno0]->bridgecallno = callno1;
03368       iaxs[callno1]->bridgecallno = callno0;
03369    }
03370    unlock_both(callno0, callno1);
03371 
03372    /* If not, try to bridge until we can execute a transfer, if we can */
03373    cs[0] = c0;
03374    cs[1] = c1;
03375    for (/* ever */;;) {
03376       /* Check in case we got masqueraded into */
03377       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03378          if (option_verbose > 2)
03379             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03380          /* Remove from native mode */
03381          if (c0->tech == &iax2_tech) {
03382             ast_mutex_lock(&iaxsl[callno0]);
03383             iaxs[callno0]->bridgecallno = 0;
03384             ast_mutex_unlock(&iaxsl[callno0]);
03385          }
03386          if (c1->tech == &iax2_tech) {
03387             ast_mutex_lock(&iaxsl[callno1]);
03388             iaxs[callno1]->bridgecallno = 0;
03389             ast_mutex_unlock(&iaxsl[callno1]);
03390          }
03391          return AST_BRIDGE_FAILED_NOWARN;
03392       }
03393       if (c0->nativeformats != c1->nativeformats) {
03394          if (option_verbose > 2) {
03395             char buf0[255];
03396             char buf1[255];
03397             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03398             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03399             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03400          }
03401          /* Remove from native mode */
03402          lock_both(callno0, callno1);
03403          if (iaxs[callno0])
03404             iaxs[callno0]->bridgecallno = 0;
03405          if (iaxs[callno1])
03406             iaxs[callno1]->bridgecallno = 0;
03407          unlock_both(callno0, callno1);
03408          return AST_BRIDGE_FAILED_NOWARN;
03409       }
03410       /* check if transfered and if we really want native bridging */
03411       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03412          /* Try the transfer */
03413          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03414                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03415             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03416          transferstarted = 1;
03417       }
03418       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03419          /* Call has been transferred.  We're no longer involved */
03420          gettimeofday(&tv, NULL);
03421          if (ast_tvzero(waittimer)) {
03422             waittimer = tv;
03423          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03424             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03425             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03426             *fo = NULL;
03427             *rc = c0;
03428             res = AST_BRIDGE_COMPLETE;
03429             break;
03430          }
03431       }
03432       to = 1000;
03433       who = ast_waitfor_n(cs, 2, &to);
03434       if (timeoutms > -1) {
03435          timeoutms -= (1000 - to);
03436          if (timeoutms < 0)
03437             timeoutms = 0;
03438       }
03439       if (!who) {
03440          if (!timeoutms) {
03441             res = AST_BRIDGE_RETRY;
03442             break;
03443          }
03444          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03445             res = AST_BRIDGE_FAILED;
03446             break;
03447          }
03448          continue;
03449       }
03450       f = ast_read(who);
03451       if (!f) {
03452          *fo = NULL;
03453          *rc = who;
03454          res = AST_BRIDGE_COMPLETE;
03455          break;
03456       }
03457       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03458          *fo = f;
03459          *rc = who;
03460          res =  AST_BRIDGE_COMPLETE;
03461          break;
03462       }
03463       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03464       if ((f->frametype == AST_FRAME_VOICE) ||
03465           (f->frametype == AST_FRAME_TEXT) ||
03466           (f->frametype == AST_FRAME_VIDEO) || 
03467           (f->frametype == AST_FRAME_IMAGE) ||
03468           (f->frametype == AST_FRAME_DTMF)) {
03469          /* monitored dtmf take out of the bridge.
03470           * check if we monitor the specific source.
03471           */
03472          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03473          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03474             *rc = who;
03475             *fo = f;
03476             res = AST_BRIDGE_COMPLETE;
03477             /* Remove from native mode */
03478             break;
03479          }
03480          /* everything else goes to the other side */
03481          ast_write(other, f);
03482       }
03483       ast_frfree(f);
03484       /* Swap who gets priority */
03485       cs[2] = cs[0];
03486       cs[0] = cs[1];
03487       cs[1] = cs[2];
03488    }
03489    lock_both(callno0, callno1);
03490    if(iaxs[callno0])
03491       iaxs[callno0]->bridgecallno = 0;
03492    if(iaxs[callno1])
03493       iaxs[callno1]->bridgecallno = 0;
03494    unlock_both(callno0, callno1);
03495    return res;
03496 }
03497 
03498 static int iax2_answer(struct ast_channel *c)
03499 {
03500    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03501    if (option_debug)
03502       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03503    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03504 }
03505 
03506 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03507 {
03508    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03509    struct chan_iax2_pvt *pvt;
03510    int res = 0;
03511 
03512    if (option_debug && iaxdebug)
03513       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03514 
03515    ast_mutex_lock(&iaxsl[callno]);
03516    pvt = iaxs[callno];
03517 
03518    switch (condition) {
03519    case AST_CONTROL_HOLD:
03520       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03521          ast_moh_start(c, data, pvt->mohinterpret);
03522          goto done;
03523       }
03524       break;
03525    case AST_CONTROL_UNHOLD:
03526       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03527          ast_moh_stop(c);
03528          goto done;
03529       }
03530    }
03531 
03532    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03533 
03534 done:
03535    ast_mutex_unlock(&iaxsl[callno]);
03536 
03537    return res;
03538 }
03539    
03540 static int iax2_transfer(struct ast_channel *c, const char *dest)
03541 {
03542    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03543    struct iax_ie_data ied;
03544    char tmp[256], *context;
03545    ast_copy_string(tmp, dest, sizeof(tmp));
03546    context = strchr(tmp, '@');
03547    if (context) {
03548       *context = '\0';
03549       context++;
03550    }
03551    memset(&ied, 0, sizeof(ied));
03552    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03553    if (context)
03554       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03555    if (option_debug)
03556       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03557    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03558 }
03559    
03560 static int iax2_getpeertrunk(struct sockaddr_in sin)
03561 {
03562    struct iax2_peer *peer;
03563    int res = 0;
03564    struct ao2_iterator i;
03565 
03566    i = ao2_iterator_init(peers, 0);
03567    while ((peer = ao2_iterator_next(&i))) {
03568       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03569           (peer->addr.sin_port == sin.sin_port)) {
03570          res = ast_test_flag(peer, IAX_TRUNK);
03571          peer_unref(peer);
03572          break;
03573       }
03574       peer_unref(peer);
03575    }
03576 
03577    return res;
03578 }
03579 
03580 /*! \brief  Create new call, interface with the PBX core */
03581 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03582 {
03583    struct ast_channel *tmp;
03584    struct chan_iax2_pvt *i;
03585    struct ast_variable *v = NULL;
03586 
03587    if (!(i = iaxs[callno])) {
03588       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03589       return NULL;
03590    }
03591 
03592    /* Don't hold call lock */
03593    ast_mutex_unlock(&iaxsl[callno]);
03594    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);
03595    ast_mutex_lock(&iaxsl[callno]);
03596    if (!tmp)
03597       return NULL;
03598    tmp->tech = &iax2_tech;
03599    /* We can support any format by default, until we get restricted */
03600    tmp->nativeformats = capability;
03601    tmp->readformat = ast_best_codec(capability);
03602    tmp->writeformat = ast_best_codec(capability);
03603    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03604 
03605    /* Don't use ast_set_callerid() here because it will
03606     * generate a NewCallerID event before the NewChannel event */
03607    if (!ast_strlen_zero(i->ani))
03608       tmp->cid.cid_ani = ast_strdup(i->ani);
03609    else
03610       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03611    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03612    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03613    tmp->cid.cid_pres = i->calling_pres;
03614    tmp->cid.cid_ton = i->calling_ton;
03615    tmp->cid.cid_tns = i->calling_tns;
03616    if (!ast_strlen_zero(i->language))
03617       ast_string_field_set(tmp, language, i->language);
03618    if (!ast_strlen_zero(i->accountcode))
03619       ast_string_field_set(tmp, accountcode, i->accountcode);
03620    if (i->amaflags)
03621       tmp->amaflags = i->amaflags;
03622    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03623    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03624    if (i->adsi)
03625       tmp->adsicpe = i->peeradsicpe;
03626    else
03627       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03628    i->owner = tmp;
03629    i->capability = capability;
03630 
03631    for (v = i->vars ; v ; v = v->next)
03632       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03633 
03634    if (state != AST_STATE_DOWN) {
03635       if (ast_pbx_start(tmp)) {
03636          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03637          ast_hangup(tmp);
03638          i->owner = NULL;
03639          return NULL;
03640       }
03641    }
03642 
03643    ast_module_ref(ast_module_info->self);
03644    
03645    return tmp;
03646 }
03647 
03648 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03649 {
03650    unsigned long int mssincetx; /* unsigned to handle overflows */
03651    long int ms, pred;
03652 
03653    tpeer->trunkact = *tv;
03654    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03655    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03656       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03657       tpeer->txtrunktime = *tv;
03658       tpeer->lastsent = 999999;
03659    }
03660    /* Update last transmit time now */
03661    tpeer->lasttxtime = *tv;
03662    
03663    /* Calculate ms offset */
03664    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03665    /* Predict from last value */
03666    pred = tpeer->lastsent + sampms;
03667    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03668       ms = pred;
03669    
03670    /* We never send the same timestamp twice, so fudge a little if we must */
03671    if (ms == tpeer->lastsent)
03672       ms = tpeer->lastsent + 1;
03673    tpeer->lastsent = ms;
03674    return ms;
03675 }
03676 
03677 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03678 {
03679    long ms; /* NOT unsigned */
03680    if (ast_tvzero(iaxs[callno]->rxcore)) {
03681       /* Initialize rxcore time if appropriate */
03682       gettimeofday(&iaxs[callno]->rxcore, NULL);
03683       /* Round to nearest 20ms so traces look pretty */
03684       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03685    }
03686    /* Calculate difference between trunk and channel */
03687    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03688    /* Return as the sum of trunk time and the difference between trunk and real time */
03689    return ms + ts;
03690 }
03691 
03692 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03693 {
03694    int ms;
03695    int voice = 0;
03696    int genuine = 0;
03697    int adjust;
03698    struct timeval *delivery = NULL;
03699 
03700 
03701    /* What sort of frame do we have?: voice is self-explanatory
03702       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03703       non-genuine frames are CONTROL frames [ringing etc], DTMF
03704       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03705       the others need a timestamp slaved to the voice frames so that they go in sequence
03706    */
03707    if (f) {
03708       if (f->frametype == AST_FRAME_VOICE) {
03709          voice = 1;
03710          delivery = &f->delivery;
03711       } else if (f->frametype == AST_FRAME_IAX) {
03712          genuine = 1;
03713       } else if (f->frametype == AST_FRAME_CNG) {
03714          p->notsilenttx = 0;  
03715       }
03716    }
03717    if (ast_tvzero(p->offset)) {
03718       gettimeofday(&p->offset, NULL);
03719       /* Round to nearest 20ms for nice looking traces */
03720       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03721    }
03722    /* If the timestamp is specified, just send it as is */
03723    if (ts)
03724       return ts;
03725    /* If we have a time that the frame arrived, always use it to make our timestamp */
03726    if (delivery && !ast_tvzero(*delivery)) {
03727       ms = ast_tvdiff_ms(*delivery, p->offset);
03728       if (option_debug > 2 && iaxdebug)
03729          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03730    } else {
03731       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03732       if (ms < 0)
03733          ms = 0;
03734       if (voice) {
03735          /* On a voice frame, use predicted values if appropriate */
03736          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03737             /* Adjust our txcore, keeping voice and non-voice synchronized */
03738             /* AN EXPLANATION:
03739                When we send voice, we usually send "calculated" timestamps worked out
03740                on the basis of the number of samples sent. When we send other frames,
03741                we usually send timestamps worked out from the real clock.
03742                The problem is that they can tend to drift out of step because the 
03743                   source channel's clock and our clock may not be exactly at the same rate.
03744                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03745                for this call.  Moving it adjusts timestamps for non-voice frames.
03746                We make the adjustment in the style of a moving average.  Each time we
03747                adjust p->offset by 10% of the difference between our clock-derived
03748                timestamp and the predicted timestamp.  That's why you see "10000"
03749                below even though IAX2 timestamps are in milliseconds.
03750                The use of a moving average avoids offset moving too radically.
03751                Generally, "adjust" roams back and forth around 0, with offset hardly
03752                changing at all.  But if a consistent different starts to develop it
03753                will be eliminated over the course of 10 frames (200-300msecs) 
03754             */
03755             adjust = (ms - p->nextpred);
03756             if (adjust < 0)
03757                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03758             else if (adjust > 0)
03759                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03760 
03761             if (!p->nextpred) {
03762                p->nextpred = ms; /*f->samples / 8;*/
03763                if (p->nextpred <= p->lastsent)
03764                   p->nextpred = p->lastsent + 3;
03765             }
03766             ms = p->nextpred;
03767          } else {
03768                 /* in this case, just use the actual
03769             * time, since we're either way off
03770             * (shouldn't happen), or we're  ending a
03771             * silent period -- and seed the next
03772             * predicted time.  Also, round ms to the
03773             * next multiple of frame size (so our
03774             * silent periods are multiples of
03775             * frame size too) */
03776 
03777             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03778                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03779                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03780 
03781             if (f->samples >= 8) /* check to make sure we dont core dump */
03782             {
03783                int diff = ms % (f->samples / 8);
03784                if (diff)
03785                    ms += f->samples/8 - diff;
03786             }
03787 
03788             p->nextpred = ms;
03789             p->notsilenttx = 1;
03790          }
03791       } else {
03792          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03793             it's a genuine frame */
03794          if (genuine) {
03795             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03796             if (ms <= p->lastsent)
03797                ms = p->lastsent + 3;
03798          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03799             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03800             ms = p->lastsent + 3;
03801          }
03802       }
03803    }
03804    p->lastsent = ms;
03805    if (voice)
03806       p->nextpred = p->nextpred + f->samples / 8;
03807    return ms;
03808 }
03809 
03810 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03811 {
03812    /* Returns where in "receive time" we are.  That is, how many ms
03813       since we received (or would have received) the frame with timestamp 0 */
03814    int ms;
03815 #ifdef IAXTESTS
03816    int jit;
03817 #endif /* IAXTESTS */
03818    /* Setup rxcore if necessary */
03819    if (ast_tvzero(p->rxcore)) {
03820       p->rxcore = ast_tvnow();
03821       if (option_debug && iaxdebug)
03822          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03823                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03824       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03825 #if 1
03826       if (option_debug && iaxdebug)
03827          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03828                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03829 #endif
03830    }
03831 
03832    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03833 #ifdef IAXTESTS
03834    if (test_jit) {
03835       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03836          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03837          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03838             jit = -jit;
03839          ms += jit;
03840       }
03841    }
03842    if (test_late) {
03843       ms += test_late;
03844       test_late = 0;
03845    }
03846 #endif /* IAXTESTS */
03847    return ms;
03848 }
03849 
03850 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03851 {
03852    struct iax2_trunk_peer *tpeer;
03853    
03854    /* Finds and locks trunk peer */
03855    ast_mutex_lock(&tpeerlock);
03856    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03857       /* We don't lock here because tpeer->addr *never* changes */
03858       if (!inaddrcmp(&tpeer->addr, sin)) {
03859          ast_mutex_lock(&tpeer->lock);
03860          break;
03861       }
03862    }
03863    if (!tpeer) {
03864       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03865          ast_mutex_init(&tpeer->lock);
03866          tpeer->lastsent = 9999;
03867          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03868          tpeer->trunkact = ast_tvnow();
03869          ast_mutex_lock(&tpeer->lock);
03870          tpeer->next = tpeers;
03871          tpeer->sockfd = fd;
03872          tpeers = tpeer;
03873 #ifdef SO_NO_CHECK
03874          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03875 #endif
03876          if (option_debug)
03877             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03878       }
03879    }
03880    ast_mutex_unlock(&tpeerlock);
03881    return tpeer;
03882 }
03883 
03884 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03885 {
03886    struct ast_frame *f;
03887    struct iax2_trunk_peer *tpeer;
03888    void *tmp, *ptr;
03889    struct ast_iax2_meta_trunk_entry *met;
03890    struct ast_iax2_meta_trunk_mini *mtm;
03891 
03892    f = &fr->af;
03893    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03894    if (tpeer) {
03895       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03896          /* Need to reallocate space */
03897          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03898             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03899                ast_mutex_unlock(&tpeer->lock);
03900                return -1;
03901             }
03902             
03903             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03904             tpeer->trunkdata = tmp;
03905             if (option_debug)
03906                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);
03907          } else {
03908             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));
03909             ast_mutex_unlock(&tpeer->lock);
03910             return -1;
03911          }
03912       }
03913 
03914       /* Append to meta frame */
03915       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03916       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03917          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03918          mtm->len = htons(f->datalen);
03919          mtm->mini.callno = htons(pvt->callno);
03920          mtm->mini.ts = htons(0xffff & fr->ts);
03921          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03922          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03923       } else {
03924          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03925          /* Store call number and length in meta header */
03926          met->callno = htons(pvt->callno);
03927          met->len = htons(f->datalen);
03928          /* Advance pointers/decrease length past trunk entry header */
03929          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03930          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03931       }
03932       /* Copy actual trunk data */
03933       memcpy(ptr, f->data, f->datalen);
03934       tpeer->trunkdatalen += f->datalen;
03935 
03936       tpeer->calls++;
03937       ast_mutex_unlock(&tpeer->lock);
03938    }
03939    return 0;
03940 }
03941 
03942 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03943 {
03944    aes_encrypt_key128(digest, ecx);
03945    aes_decrypt_key128(digest, dcx);
03946 }
03947 
03948 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03949 {
03950 #if 0
03951    /* Debug with "fake encryption" */
03952    int x;
03953    if (len % 16)
03954       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03955    for (x=0;x<len;x++)
03956       dst[x] = src[x] ^ 0xff;
03957 #else 
03958    unsigned char lastblock[16] = { 0 };
03959    int x;
03960    while(len > 0) {
03961       aes_decrypt(src, dst, dcx);
03962       for (x=0;x<16;x++)
03963          dst[x] ^= lastblock[x];
03964       memcpy(lastblock, src, sizeof(lastblock));
03965       dst += 16;
03966       src += 16;
03967       len -= 16;
03968    }
03969 #endif
03970 }
03971 
03972 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03973 {
03974 #if 0
03975    /* Debug with "fake encryption" */
03976    int x;
03977    if (len % 16)
03978       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03979    for (x=0;x<len;x++)
03980       dst[x] = src[x] ^ 0xff;
03981 #else
03982    unsigned char curblock[16] = { 0 };
03983    int x;
03984    while(len > 0) {
03985       for (x=0;x<16;x++)
03986          curblock[x] ^= src[x];
03987       aes_encrypt(curblock, dst, ecx);
03988       memcpy(curblock, dst, sizeof(curblock)); 
03989       dst += 16;
03990       src += 16;
03991       len -= 16;
03992    }
03993 #endif
03994 }
03995 
03996 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03997 {
03998    int padding;
03999    unsigned char *workspace;
04000 
04001    workspace = alloca(*datalen);
04002    memset(f, 0, sizeof(*f));
04003    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04004       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04005       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04006          return -1;
04007       /* Decrypt */
04008       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04009 
04010       padding = 16 + (workspace[15] & 0xf);
04011       if (option_debug && iaxdebug)
04012          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04013       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04014          return -1;
04015 
04016       *datalen -= padding;
04017       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04018       f->frametype = fh->type;
04019       if (f->frametype == AST_FRAME_VIDEO) {
04020          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04021       } else {
04022          f->subclass = uncompress_subclass(fh->csub);
04023       }
04024    } else {
04025       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04026       if (option_debug && iaxdebug)
04027          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04028       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04029          return -1;
04030       /* Decrypt */
04031       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04032       padding = 16 + (workspace[15] & 0x0f);
04033       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04034          return -1;
04035       *datalen -= padding;
04036       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04037    }
04038    return 0;
04039 }
04040 
04041 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04042 {
04043    int padding;
04044    unsigned char *workspace;
04045    workspace = alloca(*datalen + 32);
04046    if (!workspace)
04047       return -1;
04048    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04049       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04050       if (option_debug && iaxdebug)
04051          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04052       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04053       padding = 16 + (padding & 0xf);
04054       memcpy(workspace, poo, padding);
04055       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04056       workspace[15] &= 0xf0;
04057       workspace[15] |= (padding & 0xf);
04058       if (option_debug && iaxdebug)
04059          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]);
04060       *datalen += padding;
04061       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04062       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04063          memcpy(poo, workspace + *datalen - 32, 32);
04064    } else {
04065       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04066       if (option_debug && iaxdebug)
04067          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04068       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04069       padding = 16 + (padding & 0xf);
04070       memcpy(workspace, poo, padding);
04071       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04072       workspace[15] &= 0xf0;
04073       workspace[15] |= (padding & 0x0f);
04074       *datalen += padding;
04075       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04076       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04077          memcpy(poo, workspace + *datalen - 32, 32);
04078    }
04079    return 0;
04080 }
04081 
04082 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04083 {
04084    int res=-1;
04085    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04086       /* Search for possible keys, given secrets */
04087       struct MD5Context md5;
04088       unsigned char digest[16];
04089       char *tmppw, *stringp;
04090       
04091       tmppw = ast_strdupa(iaxs[callno]->secret);
04092       stringp = tmppw;
04093       while ((tmppw = strsep(&stringp, ";"))) {
04094          MD5Init(&md5);
04095          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04096          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04097          MD5Final(digest, &md5);
04098          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04099          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04100          if (!res) {
04101             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04102             break;
04103          }
04104       }
04105    } else 
04106       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04107    return res;
04108 }
04109 
04110 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04111 {
04112    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04113       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04114       or delayed, with retransmission */
04115    struct ast_iax2_full_hdr *fh;
04116    struct ast_iax2_mini_hdr *mh;
04117    struct ast_iax2_video_hdr *vh;
04118    struct {
04119       struct iax_frame fr2;
04120       unsigned char buffer[4096];
04121    } frb;
04122    struct iax_frame *fr;
04123    int res;
04124    int sendmini=0;
04125    unsigned int lastsent;
04126    unsigned int fts;
04127 
04128    frb.fr2.afdatalen = sizeof(frb.buffer);
04129 
04130    if (!pvt) {
04131       ast_log(LOG_WARNING, "No private structure for packet?\n");
04132       return -1;
04133    }
04134    
04135    lastsent = pvt->lastsent;
04136 
04137    /* Calculate actual timestamp */
04138    fts = calc_timestamp(pvt, ts, f);
04139 
04140    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04141     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04142     * increment the "predicted timestamps" for voice, if we're predecting */
04143    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04144        return 0;
04145 
04146 
04147    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04148          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04149          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04150       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04151        (f->frametype == AST_FRAME_VOICE) 
04152       /* is a voice frame */ &&
04153       (f->subclass == pvt->svoiceformat) 
04154       /* is the same type */ ) {
04155          /* Force immediate rather than delayed transmission */
04156          now = 1;
04157          /* Mark that mini-style frame is appropriate */
04158          sendmini = 1;
04159    }
04160    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
04161       (f->frametype == AST_FRAME_VIDEO) &&
04162       ((f->subclass & ~0x1) == pvt->svideoformat)) {
04163          now = 1;
04164          sendmini = 1;
04165    }
04166    /* Allocate an iax_frame */
04167    if (now) {
04168       fr = &frb.fr2;
04169    } else
04170       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));
04171    if (!fr) {
04172       ast_log(LOG_WARNING, "Out of memory\n");
04173       return -1;
04174    }
04175    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04176    iax_frame_wrap(fr, f);
04177 
04178    fr->ts = fts;
04179    fr->callno = pvt->callno;
04180    fr->transfer = transfer;
04181    fr->final = final;
04182    if (!sendmini) {
04183       /* We need a full frame */
04184       if (seqno > -1)
04185          fr->oseqno = seqno;
04186       else
04187          fr->oseqno = pvt->oseqno++;
04188       fr->iseqno = pvt->iseqno;
04189       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04190       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04191       fh->ts = htonl(fr->ts);
04192       fh->oseqno = fr->oseqno;
04193       if (transfer) {
04194          fh->iseqno = 0;
04195       } else
04196          fh->iseqno = fr->iseqno;
04197       /* Keep track of the last thing we've acknowledged */
04198       if (!transfer)
04199          pvt->aseqno = fr->iseqno;
04200       fh->type = fr->af.frametype & 0xFF;
04201       if (fr->af.frametype == AST_FRAME_VIDEO)
04202          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04203       else
04204          fh->csub = compress_subclass(fr->af.subclass);
04205       if (transfer) {
04206          fr->dcallno = pvt->transfercallno;
04207       } else
04208          fr->dcallno = pvt->peercallno;
04209       fh->dcallno = htons(fr->dcallno);
04210       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04211       fr->data = fh;
04212       fr->retries = 0;
04213       /* Retry after 2x the ping time has passed */
04214       fr->retrytime = pvt->pingtime * 2;
04215       if (fr->retrytime < MIN_RETRY_TIME)
04216          fr->retrytime = MIN_RETRY_TIME;
04217       if (fr->retrytime > MAX_RETRY_TIME)
04218          fr->retrytime = MAX_RETRY_TIME;
04219       /* Acks' don't get retried */
04220       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04221          fr->retries = -1;
04222       else if (f->frametype == AST_FRAME_VOICE)
04223          pvt->svoiceformat = f->subclass;
04224       else if (f->frametype == AST_FRAME_VIDEO)
04225          pvt->svideoformat = f->subclass & ~0x1;
04226       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04227          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04228             if (iaxdebug) {
04229                if (fr->transfer)
04230                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04231                else
04232                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04233             }
04234             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04235          } else
04236             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04237       }
04238    
04239       if (now) {
04240          res = send_packet(fr);
04241       } else
04242          res = iax2_transmit(fr);
04243    } else {
04244       if (ast_test_flag(pvt, IAX_TRUNK)) {
04245          iax2_trunk_queue(pvt, fr);
04246          res = 0;
04247       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04248          /* Video frame have no sequence number */
04249          fr->oseqno = -1;
04250          fr->iseqno = -1;
04251          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04252          vh->zeros = 0;
04253          vh->callno = htons(0x8000 | fr->callno);
04254          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04255          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04256          fr->data = vh;
04257          fr->retries = -1;
04258          res = send_packet(fr);        
04259       } else {
04260          /* Mini-frames have no sequence number */
04261          fr->oseqno = -1;
04262          fr->iseqno = -1;
04263          /* Mini frame will do */
04264          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04265          mh->callno = htons(fr->callno);
04266          mh->ts = htons(fr->ts & 0xFFFF);
04267          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04268          fr->data = mh;
04269          fr->retries = -1;
04270          if (pvt->transferring == TRANSFER_MEDIAPASS)
04271             fr->transfer = 1;
04272          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04273             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04274                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04275             } else
04276                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04277          }
04278          res = send_packet(fr);
04279       }
04280    }
04281    return res;
04282 }
04283 
04284 static int iax2_show_users(int fd, int argc, char *argv[])
04285 {
04286    regex_t regexbuf;
04287    int havepattern = 0;
04288 
04289 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04290 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04291 
04292    struct iax2_user *user = NULL;
04293    char auth[90];
04294    char *pstr = "";
04295    struct ao2_iterator i;
04296 
04297    switch (argc) {
04298    case 5:
04299       if (!strcasecmp(argv[3], "like")) {
04300          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04301             return RESULT_SHOWUSAGE;
04302          havepattern = 1;
04303       } else
04304          return RESULT_SHOWUSAGE;
04305    case 3:
04306       break;
04307    default:
04308       return RESULT_SHOWUSAGE;
04309    }
04310 
04311    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04312    i = ao2_iterator_init(users, 0);
04313    for (user = ao2_iterator_next(&i); user; 
04314       user_unref(user), user = ao2_iterator_next(&i)) {
04315       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04316          continue;
04317       
04318       if (!ast_strlen_zero(user->secret)) {
04319          ast_copy_string(auth,user->secret,sizeof(auth));
04320       } else if (!ast_strlen_zero(user->inkeys)) {
04321          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04322       } else
04323          ast_copy_string(auth, "-no secret-", sizeof(auth));
04324       
04325       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04326          pstr = "REQ Only";
04327       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04328          pstr = "Disabled";
04329       else
04330          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04331       
04332       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04333          user->contexts ? user->contexts->context : context,
04334          user->ha ? "Yes" : "No", pstr);
04335    }
04336 
04337    if (havepattern)
04338       regfree(&regexbuf);
04339 
04340    return RESULT_SUCCESS;
04341 #undef FORMAT
04342 #undef FORMAT2
04343 }
04344 
04345 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04346 {
04347    regex_t regexbuf;
04348    int havepattern = 0;
04349    int total_peers = 0;
04350    int online_peers = 0;
04351    int offline_peers = 0;
04352    int unmonitored_peers = 0;
04353    struct ao2_iterator i;
04354 
04355 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04356 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04357 
04358    struct iax2_peer *peer = NULL;
04359    char name[256];
04360    int registeredonly=0;
04361    char *term = manager ? "\r\n" : "\n";
04362 
04363    switch (argc) {
04364    case 6:
04365       if (!strcasecmp(argv[3], "registered"))
04366          registeredonly = 1;
04367       else
04368          return RESULT_SHOWUSAGE;
04369       if (!strcasecmp(argv[4], "like")) {
04370          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04371             return RESULT_SHOWUSAGE;
04372          havepattern = 1;
04373       } else
04374          return RESULT_SHOWUSAGE;
04375       break;
04376    case 5:
04377       if (!strcasecmp(argv[3], "like")) {
04378          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04379             return RESULT_SHOWUSAGE;
04380          havepattern = 1;
04381       } else
04382          return RESULT_SHOWUSAGE;
04383       break;
04384    case 4:
04385       if (!strcasecmp(argv[3], "registered"))
04386          registeredonly = 1;
04387       else
04388          return RESULT_SHOWUSAGE;
04389       break;
04390    case 3:
04391       break;
04392    default:
04393       return RESULT_SHOWUSAGE;
04394    }
04395 
04396 
04397    if (s)
04398       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04399    else
04400       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04401 
04402    i = ao2_iterator_init(peers, 0);
04403    for (peer = ao2_iterator_next(&i); peer; 
04404       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04405       char nm[20];
04406       char status[20];
04407       char srch[2000];
04408       int retstatus;
04409 
04410       if (registeredonly && !peer->addr.sin_addr.s_addr)
04411          continue;
04412       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04413          continue;
04414 
04415       if (!ast_strlen_zero(peer->username))
04416          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04417       else
04418          ast_copy_string(name, peer->name, sizeof(name));
04419       
04420       retstatus = peer_status(peer, status, sizeof(status));
04421       if (retstatus > 0)
04422          online_peers++;
04423       else if (!retstatus)
04424          offline_peers++;
04425       else
04426          unmonitored_peers++;
04427       
04428       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04429       
04430       snprintf(srch, sizeof(srch), FORMAT, name, 
04431           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04432           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04433           nm,
04434           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04435           peer->encmethods ? "(E)" : "   ", status, term);
04436       
04437       if (s)
04438          astman_append(s, FORMAT, name, 
04439                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04440                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04441                   nm,
04442                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04443                   peer->encmethods ? "(E)" : "   ", status, term);
04444       else
04445          ast_cli(fd, FORMAT, name, 
04446             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04447             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04448             nm,
04449             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04450             peer->encmethods ? "(E)" : "   ", status, term);
04451       total_peers++;
04452    }
04453 
04454    if (s)
04455       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04456    else
04457       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04458 
04459    if (havepattern)
04460       regfree(&regexbuf);
04461 
04462    return RESULT_SUCCESS;
04463 #undef FORMAT
04464 #undef FORMAT2
04465 }
04466 
04467 static int iax2_show_threads(int fd, int argc, char *argv[])
04468 {
04469    struct iax2_thread *thread = NULL;
04470    time_t t;
04471    int threadcount = 0, dynamiccount = 0;
04472    char type;
04473 
04474    if (argc != 3)
04475       return RESULT_SHOWUSAGE;
04476       
04477    ast_cli(fd, "IAX2 Thread Information\n");
04478    time(&t);
04479    ast_cli(fd, "Idle Threads:\n");
04480    AST_LIST_LOCK(&idle_list);
04481    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04482 #ifdef DEBUG_SCHED_MULTITHREAD
04483       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04484          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04485 #else
04486       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04487          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04488 #endif
04489       threadcount++;
04490    }
04491    AST_LIST_UNLOCK(&idle_list);
04492    ast_cli(fd, "Active Threads:\n");
04493    AST_LIST_LOCK(&active_list);
04494    AST_LIST_TRAVERSE(&active_list, thread, list) {
04495       if (thread->type == IAX_TYPE_DYNAMIC)
04496          type = 'D';
04497       else
04498          type = 'P';
04499 #ifdef DEBUG_SCHED_MULTITHREAD
04500       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04501          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04502 #else
04503       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04504          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04505 #endif
04506       threadcount++;
04507    }
04508    AST_LIST_UNLOCK(&active_list);
04509    ast_cli(fd, "Dynamic Threads:\n");
04510         AST_LIST_LOCK(&dynamic_list);
04511         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04512 #ifdef DEBUG_SCHED_MULTITHREAD
04513                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04514                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04515 #else
04516                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04517                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04518 #endif
04519       dynamiccount++;
04520         }
04521         AST_LIST_UNLOCK(&dynamic_list);
04522    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04523    return RESULT_SUCCESS;
04524 }
04525 
04526 static int iax2_show_peers(int fd, int argc, char *argv[])
04527 {
04528    return __iax2_show_peers(0, fd, NULL, argc, argv);
04529 }
04530 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04531 {
04532    ast_cli_netstats(s, -1, 0);
04533    astman_append(s, "\r\n");
04534    return RESULT_SUCCESS;
04535 }
04536 
04537 static int iax2_show_firmware(int fd, int argc, char *argv[])
04538 {
04539 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04540 #if !defined(__FreeBSD__)
04541 #define FORMAT "%-15.15s  %-15d %-15d\n"
04542 #else /* __FreeBSD__ */
04543 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04544 #endif /* __FreeBSD__ */
04545    struct iax_firmware *cur;
04546    if ((argc != 3) && (argc != 4))
04547       return RESULT_SHOWUSAGE;
04548    ast_mutex_lock(&waresl.lock);
04549    
04550    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04551    for (cur = waresl.wares;cur;cur = cur->next) {
04552       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04553          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04554             (int)ntohl(cur->fwh->datalen));
04555    }
04556    ast_mutex_unlock(&waresl.lock);
04557    return RESULT_SUCCESS;
04558 #undef FORMAT
04559 #undef FORMAT2
04560 }
04561 
04562 /* JDG: callback to display iax peers in manager */
04563 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04564 {
04565    char *a[] = { "iax2", "show", "users" };
04566    int ret;
04567    const char *id = astman_get_header(m,"ActionID");
04568 
04569    if (!ast_strlen_zero(id))
04570       astman_append(s, "ActionID: %s\r\n",id);
04571    ret = __iax2_show_peers(1, -1, s, 3, a );
04572    astman_append(s, "\r\n\r\n" );
04573    return ret;
04574 } /* /JDG */
04575 
04576 static char *regstate2str(int regstate)
04577 {
04578    switch(regstate) {
04579    case REG_STATE_UNREGISTERED:
04580       return "Unregistered";
04581    case REG_STATE_REGSENT:
04582       return "Request Sent";
04583    case REG_STATE_AUTHSENT:
04584       return "Auth. Sent";
04585    case REG_STATE_REGISTERED:
04586       return "Registered";
04587    case REG_STATE_REJECTED:
04588       return "Rejected";
04589    case REG_STATE_TIMEOUT:
04590       return "Timeout";
04591    case REG_STATE_NOAUTH:
04592       return "No Authentication";
04593    default:
04594       return "Unknown";
04595    }
04596 }
04597 
04598 static int iax2_show_registry(int fd, int argc, char *argv[])
04599 {
04600 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04601 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04602    struct iax2_registry *reg = NULL;
04603 
04604    char host[80];
04605    char perceived[80];
04606    if (argc != 3)
04607       return RESULT_SHOWUSAGE;
04608    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04609    AST_LIST_LOCK(&registrations);
04610    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04611       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04612       if (reg->us.sin_addr.s_addr) 
04613          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04614       else
04615          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04616       ast_cli(fd, FORMAT, host, 
04617                (reg->dnsmgr) ? "Y" : "N", 
04618                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04619    }
04620    AST_LIST_UNLOCK(&registrations);
04621    return RESULT_SUCCESS;
04622 #undef FORMAT
04623 #undef FORMAT2
04624 }
04625 
04626 static int iax2_show_channels(int fd, int argc, char *argv[])
04627 {
04628 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04629 #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"
04630 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04631    int x;
04632    int numchans = 0;
04633 
04634    if (argc != 3)
04635       return RESULT_SHOWUSAGE;
04636    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04637    for (x=0;x<IAX_MAX_CALLS;x++) {
04638       ast_mutex_lock(&iaxsl[x]);
04639       if (iaxs[x]) {
04640          int lag, jitter, localdelay;
04641          jb_info jbinfo;
04642          
04643          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04644             jb_getinfo(iaxs[x]->jb, &jbinfo);
04645             jitter = jbinfo.jitter;
04646             localdelay = jbinfo.current - jbinfo.min;
04647          } else {
04648             jitter = -1;
04649             localdelay = 0;
04650          }
04651          lag = iaxs[x]->remote_rr.delay;
04652          ast_cli(fd, FORMAT,
04653             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04654             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04655             S_OR(iaxs[x]->username, "(None)"),
04656             iaxs[x]->callno, iaxs[x]->peercallno,
04657             iaxs[x]->oseqno, iaxs[x]->iseqno,
04658             lag,
04659             jitter,
04660             localdelay,
04661             ast_getformatname(iaxs[x]->voiceformat) );
04662          numchans++;
04663       }
04664       ast_mutex_unlock(&iaxsl[x]);
04665    }
04666    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04667    return RESULT_SUCCESS;
04668 #undef FORMAT
04669 #undef FORMAT2
04670 #undef FORMATB
04671 }
04672 
04673 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04674 {
04675    int x;
04676    int numchans = 0;
04677    for (x=0;x<IAX_MAX_CALLS;x++) {
04678       ast_mutex_lock(&iaxsl[x]);
04679       if (iaxs[x]) {
04680          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04681          char *fmt;
04682          jb_info jbinfo;
04683          
04684          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04685             jb_getinfo(iaxs[x]->jb, &jbinfo);
04686             localjitter = jbinfo.jitter;
04687             localdelay = jbinfo.current - jbinfo.min;
04688             locallost = jbinfo.frames_lost;
04689             locallosspct = jbinfo.losspct/1000;
04690             localdropped = jbinfo.frames_dropped;
04691             localooo = jbinfo.frames_ooo;
04692          } else {
04693             localjitter = -1;
04694             localdelay = 0;
04695             locallost = -1;
04696             locallosspct = -1;
04697             localdropped = 0;
04698             localooo = -1;
04699          }
04700          if (limit_fmt)
04701             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04702          else
04703             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04704          if (s)
04705             
04706             astman_append(s, fmt,
04707                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04708                      iaxs[x]->pingtime,
04709                      localjitter, 
04710                      localdelay,
04711                      locallost,
04712                      locallosspct,
04713                      localdropped,
04714                      localooo,
04715                      iaxs[x]->frames_received/1000,
04716                      iaxs[x]->remote_rr.jitter,
04717                      iaxs[x]->remote_rr.delay,
04718                      iaxs[x]->remote_rr.losscnt,
04719                      iaxs[x]->remote_rr.losspct,
04720                      iaxs[x]->remote_rr.dropped,
04721                      iaxs[x]->remote_rr.ooo,
04722                      iaxs[x]->remote_rr.packets/1000);
04723          else
04724             ast_cli(fd, fmt,
04725                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04726                iaxs[x]->pingtime,
04727                localjitter, 
04728                localdelay,
04729                locallost,
04730                locallosspct,
04731                localdropped,
04732                localooo,
04733                iaxs[x]->frames_received/1000,
04734                iaxs[x]->remote_rr.jitter,
04735                iaxs[x]->remote_rr.delay,
04736                iaxs[x]->remote_rr.losscnt,
04737                iaxs[x]->remote_rr.losspct,
04738                iaxs[x]->remote_rr.dropped,
04739                iaxs[x]->remote_rr.ooo,
04740                iaxs[x]->remote_rr.packets/1000
04741                );
04742          numchans++;
04743       }
04744       ast_mutex_unlock(&iaxsl[x]);
04745    }
04746    return numchans;
04747 }
04748 
04749 static int iax2_show_netstats(int fd, int argc, char *argv[])
04750 {
04751    int numchans = 0;
04752    if (argc != 3)
04753       return RESULT_SHOWUSAGE;
04754    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04755    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04756    numchans = ast_cli_netstats(NULL, fd, 1);
04757    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04758    return RESULT_SUCCESS;
04759 }
04760 
04761 static int iax2_do_debug(int fd, int argc, char *argv[])
04762 {
04763    if (argc < 2 || argc > 3)
04764       return RESULT_SHOWUSAGE;
04765    iaxdebug = 1;
04766    ast_cli(fd, "IAX2 Debugging Enabled\n");
04767    return RESULT_SUCCESS;
04768 }
04769 
04770 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04771 {
04772    if (argc < 3 || argc > 4)
04773       return RESULT_SHOWUSAGE;
04774    iaxtrunkdebug = 1;
04775    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04776    return RESULT_SUCCESS;
04777 }
04778 
04779 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04780 {
04781    if (argc < 3 || argc > 4)
04782       return RESULT_SHOWUSAGE;
04783    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04784    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04785    return RESULT_SUCCESS;
04786 }
04787 
04788 static int iax2_no_debug(int fd, int argc, char *argv[])
04789 {
04790    if (argc < 3 || argc > 4)
04791       return RESULT_SHOWUSAGE;
04792    iaxdebug = 0;
04793    ast_cli(fd, "IAX2 Debugging Disabled\n");
04794    return RESULT_SUCCESS;
04795 }
04796 
04797 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04798 {
04799    if (argc < 4 || argc > 5)
04800       return RESULT_SHOWUSAGE;
04801    iaxtrunkdebug = 0;
04802    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04803    return RESULT_SUCCESS;
04804 }
04805 
04806 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04807 {
04808    if (argc < 4 || argc > 5)
04809       return RESULT_SHOWUSAGE;
04810    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04811    jb_debug_output("\n");
04812    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04813    return RESULT_SUCCESS;
04814 }
04815 
04816 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04817 {
04818    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04819    int res = -1;
04820    ast_mutex_lock(&iaxsl[callno]);
04821    if (iaxs[callno]) {
04822    /* If there's an outstanding error, return failure now */
04823       if (!iaxs[callno]->error) {
04824          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04825             res = 0;
04826             /* Don't waste bandwidth sending null frames */
04827          else if (f->frametype == AST_FRAME_NULL)
04828             res = 0;
04829          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04830             res = 0;
04831          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04832             res = 0;
04833          else
04834          /* Simple, just queue for transmission */
04835             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04836       } else {
04837          if (option_debug)
04838             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04839       }
04840    }
04841    /* If it's already gone, just return */
04842    ast_mutex_unlock(&iaxsl[callno]);
04843    return res;
04844 }
04845 
04846 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04847       int now, int transfer, int final)
04848 {
04849    struct ast_frame f = { 0, };
04850 
04851    f.frametype = type;
04852    f.subclass = command;
04853    f.datalen = datalen;
04854    f.src = __FUNCTION__;
04855    f.data = (void *) data;
04856 
04857    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04858 }
04859 
04860 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04861 {
04862    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04863 }
04864 
04865 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04866 {
04867    int res;
04868    ast_mutex_lock(&iaxsl[callno]);
04869    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04870    ast_mutex_unlock(&iaxsl[callno]);
04871    return res;
04872 }
04873 
04874 /*!
04875  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
04876  *       the pvt struct for the given call number may disappear during its 
04877  *       execution.
04878  */
04879 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)
04880 {
04881    int call_num = i->callno;
04882    /* It is assumed that the callno has already been locked */
04883    iax2_predestroy(i->callno);
04884    if (!iaxs[call_num])
04885       return -1;
04886    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04887 }
04888 
04889 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)
04890 {
04891    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04892 }
04893 
04894 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04895 {
04896    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04897 }
04898 
04899 static int apply_context(struct iax2_context *con, const char *context)
04900 {
04901    while(con) {
04902       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04903          return -1;
04904       con = con->next;
04905    }
04906    return 0;
04907 }
04908 
04909 
04910 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04911 {
04912    /* Start pessimistic */
04913    int res = -1;
04914    int version = 2;
04915    struct iax2_user *user = NULL, *best = NULL;
04916    int bestscore = 0;
04917    int gotcapability = 0;
04918    struct ast_variable *v = NULL, *tmpvar = NULL;
04919    struct ao2_iterator i;
04920 
04921    if (!iaxs[callno])
04922       return res;
04923    if (ies->called_number)
04924       ast_string_field_set(iaxs[callno], exten, ies->called_number);
04925    if (ies->calling_number) {
04926       ast_shrink_phone_number(ies->calling_number);
04927       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04928    }
04929    if (ies->calling_name)
04930       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04931    if (ies->calling_ani)
04932       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04933    if (ies->dnid)
04934       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04935    if (ies->rdnis)
04936       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04937    if (ies->called_context)
04938       ast_string_field_set(iaxs[callno], context, ies->called_context);
04939    if (ies->language)
04940       ast_string_field_set(iaxs[callno], language, ies->language);
04941    if (ies->username)
04942       ast_string_field_set(iaxs[callno], username, ies->username);
04943    if (ies->calling_ton > -1)
04944       iaxs[callno]->calling_ton = ies->calling_ton;
04945    if (ies->calling_tns > -1)
04946       iaxs[callno]->calling_tns = ies->calling_tns;
04947    if (ies->calling_pres > -1)
04948       iaxs[callno]->calling_pres = ies->calling_pres;
04949    if (ies->format)
04950       iaxs[callno]->peerformat = ies->format;
04951    if (ies->adsicpe)
04952       iaxs[callno]->peeradsicpe = ies->adsicpe;
04953    if (ies->capability) {
04954       gotcapability = 1;
04955       iaxs[callno]->peercapability = ies->capability;
04956    } 
04957    if (ies->version)
04958       version = ies->version;
04959 
04960    /* Use provided preferences until told otherwise for actual preferences */
04961    if(ies->codec_prefs) {
04962       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04963       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04964    }
04965 
04966    if (!gotcapability) 
04967       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04968    if (version > IAX_PROTO_VERSION) {
04969       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04970          ast_inet_ntoa(sin->sin_addr), version);
04971       return res;
04972    }
04973    /* Search the userlist for a compatible entry, and fill in the rest */
04974    i = ao2_iterator_init(users, 0);
04975    while ((user = ao2_iterator_next(&i))) {
04976       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04977          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04978          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04979          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04980               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04981          if (!ast_strlen_zero(iaxs[callno]->username)) {
04982             /* Exact match, stop right now. */
04983             if (best)
04984                user_unref(best);
04985             best = user;
04986             break;
04987          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04988             /* No required authentication */
04989             if (user->ha) {
04990                /* There was host authentication and we passed, bonus! */
04991                if (bestscore < 4) {
04992                   bestscore = 4;
04993                   if (best)
04994                      user_unref(best);
04995                   best = user;
04996                   continue;
04997                }
04998             } else {
04999                /* No host access, but no secret, either, not bad */
05000                if (bestscore < 3) {
05001                   bestscore = 3;
05002                   if (best)
05003                      user_unref(best);
05004                   best = user;
05005                   continue;
05006                }
05007             }
05008          } else {
05009             if (user->ha) {
05010                /* Authentication, but host access too, eh, it's something.. */
05011                if (bestscore < 2) {
05012                   bestscore = 2;
05013                   if (best)
05014                      user_unref(best);
05015                   best = user;
05016                   continue;
05017                }
05018             } else {
05019                /* Authentication and no host access...  This is our baseline */
05020                if (bestscore < 1) {
05021                   bestscore = 1;
05022                   if (best)
05023                      user_unref(best);
05024                   best = user;
05025                   continue;
05026                }
05027             }
05028          }
05029       }
05030       user_unref(user);
05031    }
05032    user = best;
05033    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05034       user = realtime_user(iaxs[callno]->username, sin);
05035       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05036           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05037          user = user_unref(user);
05038       }
05039    }
05040    if (user) {
05041       /* We found our match (use the first) */
05042       /* copy vars */
05043       for (v = user->vars ; v ; v = v->next) {
05044          if((tmpvar = ast_variable_new(v->name, v->value))) {
05045             tmpvar->next = iaxs[callno]->vars; 
05046             iaxs[callno]->vars = tmpvar;
05047          }
05048       }
05049       /* If a max AUTHREQ restriction is in place, activate it */
05050       if (user->maxauthreq > 0)
05051          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05052       iaxs[callno]->prefs = user->prefs;
05053       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05054       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05055       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05056       iaxs[callno]->encmethods = user->encmethods;
05057       /* Store the requested username if not specified */
05058       if (ast_strlen_zero(iaxs[callno]->username))
05059          ast_string_field_set(iaxs[callno], username, user->name);
05060       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05061       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05062       iaxs[callno]->capability = user->capability;
05063       /* And use the default context */
05064       if (ast_strlen_zero(iaxs[callno]->context)) {
05065          if (user->contexts)
05066             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05067          else
05068             ast_string_field_set(iaxs[callno], context, context);
05069       }
05070       /* And any input keys */
05071       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05072       /* And the permitted authentication methods */
05073       iaxs[callno]->authmethods = user->authmethods;
05074       iaxs[callno]->adsi = user->adsi;
05075       /* If they have callerid, override the given caller id.  Always store the ANI */
05076       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05077          if (ast_test_flag(user, IAX_HASCALLERID)) {
05078             iaxs[callno]->calling_tns = 0;
05079             iaxs[callno]->calling_ton = 0;
05080             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05081             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05082             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05083          }
05084          if (ast_strlen_zero(iaxs[callno]->ani))
05085             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05086       } else {
05087          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05088       }
05089       if (!ast_strlen_zero(user->accountcode))
05090          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05091       if (!ast_strlen_zero(user->mohinterpret))
05092          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05093       if (!ast_strlen_zero(user->mohsuggest))
05094          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05095       if (user->amaflags)
05096          iaxs[callno]->amaflags = user->amaflags;
05097       if (!ast_strlen_zero(user->language))
05098          ast_string_field_set(iaxs[callno], language, user->language);
05099       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05100       /* Keep this check last */
05101       if (!ast_strlen_zero(user->dbsecret)) {
05102          char *family, *key=NULL;
05103          char buf[80];
05104          family = ast_strdupa(user->dbsecret);
05105          key = strchr(family, '/');
05106          if (key) {
05107             *key = '\0';
05108             key++;
05109          }
05110          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05111             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05112          else
05113             ast_string_field_set(iaxs[callno], secret, buf);
05114       } else
05115          ast_string_field_set(iaxs[callno], secret, user->secret);
05116       res = 0;
05117       user = user_unref(user);
05118    }
05119    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05120    return res;
05121 }
05122 
05123 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05124 {
05125    struct ast_iax2_full_hdr fh;
05126    fh.scallno = htons(src | IAX_FLAG_FULL);
05127    fh.dcallno = htons(dst);
05128    fh.ts = 0;
05129    fh.oseqno = 0;
05130    fh.iseqno = 0;
05131    fh.type = AST_FRAME_IAX;
05132    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05133    if (iaxdebug)
05134        iax_showframe(NULL, &fh, 0, sin, 0);
05135    if (option_debug)
05136       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05137          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05138    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05139 }
05140 
05141 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05142 {
05143    /* Select exactly one common encryption if there are any */
05144    p->encmethods &= enc;
05145    if (p->encmethods) {
05146       if (p->encmethods & IAX_ENCRYPT_AES128)
05147          p->encmethods = IAX_ENCRYPT_AES128;
05148       else
05149          p->encmethods = 0;
05150    }
05151 }
05152 
05153 /*!
05154  * \pre iaxsl[call_num] is locked
05155  *
05156  * \note Since this function calls send_command_final(), the pvt struct for the given
05157  *       call number may disappear while executing this function.
05158  */
05159 static int authenticate_request(int call_num)
05160 {
05161    struct iax_ie_data ied;
05162    int res = -1, authreq_restrict = 0;
05163    char challenge[10];
05164    struct chan_iax2_pvt *p = iaxs[call_num];
05165 
05166    memset(&ied, 0, sizeof(ied));
05167 
05168    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05169    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05170       struct iax2_user *user, tmp_user = {
05171          .name = p->username, 
05172       };
05173 
05174       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05175       if (user) {
05176          if (user->curauthreq == user->maxauthreq)
05177             authreq_restrict = 1;
05178          else
05179             user->curauthreq++;
05180          user = user_unref(user);
05181       }
05182    }
05183 
05184    /* If the AUTHREQ limit test failed, send back an error */
05185    if (authreq_restrict) {
05186       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05187       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05188       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05189       return 0;
05190    }
05191 
05192    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05193    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05194       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05195       ast_string_field_set(p, challenge, challenge);
05196       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05197       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05198    }
05199    if (p->encmethods)
05200       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05201 
05202    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05203 
05204    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05205 
05206    if (p->encmethods)
05207       ast_set_flag(p, IAX_ENCRYPTED);
05208 
05209    return res;
05210 }
05211 
05212 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05213 {
05214    char requeststr[256];
05215    char md5secret[256] = "";
05216    char secret[256] = "";
05217    char rsasecret[256] = "";
05218    int res = -1; 
05219    int x;
05220    struct iax2_user *user, tmp_user = {
05221       .name = p->username, 
05222    };
05223 
05224    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05225    if (user) {
05226       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05227          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05228          ast_clear_flag(p, IAX_MAXAUTHREQ);
05229       }
05230       ast_string_field_set(p, host, user->name);
05231       user = user_unref(user);
05232    }
05233 
05234    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05235       return res;
05236    if (ies->password)
05237       ast_copy_string(secret, ies->password, sizeof(secret));
05238    if (ies->md5_result)
05239       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05240    if (ies->rsa_result)
05241       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05242    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05243       struct ast_key *key;
05244       char *keyn;
05245       char tmpkey[256];
05246       char *stringp=NULL;
05247       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05248       stringp=tmpkey;
05249       keyn = strsep(&stringp, ":");
05250       while(keyn) {
05251          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05252          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05253             res = 0;
05254             break;
05255          } else if (!key)
05256             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05257          keyn = strsep(&stringp, ":");
05258       }
05259    } else if (p->authmethods & IAX_AUTH_MD5) {
05260       struct MD5Context md5;
05261       unsigned char digest[16];
05262       char *tmppw, *stringp;
05263       
05264       tmppw = ast_strdupa(p->secret);
05265       stringp = tmppw;
05266       while((tmppw = strsep(&stringp, ";"))) {
05267          MD5Init(&md5);
05268          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05269          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05270          MD5Final(digest, &md5);
05271          /* If they support md5, authenticate with it.  */
05272          for (x=0;x<16;x++)
05273             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05274          if (!strcasecmp(requeststr, md5secret)) {
05275             res = 0;
05276             break;
05277          }
05278       }
05279    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05280       if (!strcmp(secret, p->secret))
05281          res = 0;
05282    }
05283    return res;
05284 }
05285 
05286 /*! \brief Verify inbound registration */
05287 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05288 {
05289    char requeststr[256] = "";
05290    char peer[256] = "";
05291    char md5secret[256] = "";
05292    char rsasecret[256] = "";
05293    char secret[256] = "";
05294    struct iax2_peer *p = NULL;
05295    struct ast_key *key;
05296    char *keyn;
05297    int x;
05298    int expire = 0;
05299    int res = -1;
05300 
05301    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05302    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05303    if (ies->username)
05304       ast_copy_string(peer, ies->username, sizeof(peer));
05305    if (ies->password)
05306       ast_copy_string(secret, ies->password, sizeof(secret));
05307    if (ies->md5_result)
05308       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05309    if (ies->rsa_result)
05310       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05311    if (ies->refresh)
05312       expire = ies->refresh;
05313 
05314    if (ast_strlen_zero(peer)) {
05315       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05316       return -1;
05317    }
05318 
05319    /* SLD: first call to lookup peer during registration */
05320    ast_mutex_unlock(&iaxsl[callno]);
05321    p = find_peer(peer, 1);
05322    ast_mutex_lock(&iaxsl[callno]);
05323    if (!p || !iaxs[callno]) {
05324       if (authdebug && !p)
05325          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05326       goto return_unref;
05327    }
05328 
05329    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05330       if (authdebug)
05331          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05332       goto return_unref;
05333    }
05334 
05335    if (!ast_apply_ha(p->ha, sin)) {
05336       if (authdebug)
05337          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05338       goto return_unref;
05339    }
05340    if (!inaddrcmp(&p->addr, sin))
05341       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05342    ast_string_field_set(iaxs[callno], secret, p->secret);
05343    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05344    /* Check secret against what we have on file */
05345    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05346       if (!ast_strlen_zero(p->inkeys)) {
05347          char tmpkeys[256];
05348          char *stringp=NULL;
05349          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05350          stringp=tmpkeys;
05351          keyn = strsep(&stringp, ":");
05352          while(keyn) {
05353             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05354             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05355                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05356                break;
05357             } else if (!key) 
05358                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05359             keyn = strsep(&stringp, ":");
05360          }
05361          if (!keyn) {
05362             if (authdebug)
05363                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05364             goto return_unref;
05365          }
05366       } else {
05367          if (authdebug)
05368             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05369          goto return_unref;
05370       }
05371    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05372       struct MD5Context md5;
05373       unsigned char digest[16];
05374       char *tmppw, *stringp;
05375       
05376       tmppw = ast_strdupa(p->secret);
05377       stringp = tmppw;
05378       while((tmppw = strsep(&stringp, ";"))) {
05379          MD5Init(&md5);
05380          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05381          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05382          MD5Final(digest, &md5);
05383          for (x=0;x<16;x++)
05384             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05385          if (!strcasecmp(requeststr, md5secret)) 
05386             break;
05387       }
05388       if (tmppw) {
05389          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05390       } else {
05391          if (authdebug)
05392             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05393          goto return_unref;
05394       }
05395    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05396       /* They've provided a plain text password and we support that */
05397       if (strcmp(secret, p->secret)) {
05398          if (authdebug)
05399             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05400          goto return_unref;
05401       } else
05402          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05403    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05404       if (authdebug)
05405          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05406       goto return_unref;
05407    }
05408    ast_string_field_set(iaxs[callno], peer, peer);
05409    /* Choose lowest expiry number */
05410    if (expire && (expire < iaxs[callno]->expiry)) 
05411       iaxs[callno]->expiry = expire;
05412 
05413    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05414 
05415    res = 0;
05416 
05417 return_unref:
05418    if (p)
05419       peer_unref(p);
05420 
05421    return res;
05422 }
05423 
05424 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)
05425 {
05426    int res = -1;
05427    int x;
05428    if (!ast_strlen_zero(keyn)) {
05429       if (!(authmethods & IAX_AUTH_RSA)) {
05430          if (ast_strlen_zero(secret)) 
05431             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));
05432       } else if (ast_strlen_zero(challenge)) {
05433          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05434       } else {
05435          char sig[256];
05436          struct ast_key *key;
05437          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05438          if (!key) {
05439             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05440          } else {
05441             if (ast_sign(key, (char*)challenge, sig)) {
05442                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05443                res = -1;
05444             } else {
05445                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05446                res = 0;
05447             }
05448          }
05449       }
05450    } 
05451    /* Fall back */
05452    if (res && !ast_strlen_zero(secret)) {
05453       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05454          struct MD5Context md5;
05455          unsigned char digest[16];
05456          char digres[128];
05457          MD5Init(&md5);
05458          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05459          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05460          MD5Final(digest, &md5);
05461          /* If they support md5, authenticate with it.  */
05462          for (x=0;x<16;x++)
05463             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05464          if (ecx && dcx)
05465             build_enc_keys(digest, ecx, dcx);
05466          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05467          res = 0;
05468       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05469          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05470          res = 0;
05471       } else
05472          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05473    }
05474    return res;
05475 }
05476 
05477 /*!
05478  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05479  *       so do not call this function with a pvt lock held.
05480  */
05481 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05482 {
05483    struct iax2_peer *peer = NULL;
05484    /* Start pessimistic */
05485    int res = -1;
05486    int authmethods = 0;
05487    struct iax_ie_data ied;
05488    uint16_t callno = p->callno;
05489 
05490    memset(&ied, 0, sizeof(ied));
05491    
05492    if (ies->username)
05493       ast_string_field_set(p, username, ies->username);
05494    if (ies->challenge)
05495       ast_string_field_set(p, challenge, ies->challenge);
05496    if (ies->authmethods)
05497       authmethods = ies->authmethods;
05498    if (authmethods & IAX_AUTH_MD5)
05499       merge_encryption(p, ies->encmethods);
05500    else
05501       p->encmethods = 0;
05502 
05503    /* Check for override RSA authentication first */
05504    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05505       /* Normal password authentication */
05506       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05507    } else {
05508       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05509       while ((peer = ao2_iterator_next(&i))) {
05510          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05511              /* No peer specified at our end, or this is the peer */
05512              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05513              /* No username specified in peer rule, or this is the right username */
05514              && (!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)))
05515              /* No specified host, or this is our host */
05516             ) {
05517             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05518             if (!res) {
05519                peer_unref(peer);
05520                break;
05521             }
05522          }
05523          peer_unref(peer);
05524       }
05525       if (!peer) {
05526          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05527             that we're trying to authenticate *to* a realtime peer */
05528          const char *peer_name = ast_strdupa(p->peer);
05529          ast_mutex_unlock(&iaxsl[callno]);
05530          if ((peer = realtime_peer(peer_name, NULL))) {
05531             ast_mutex_lock(&iaxsl[callno]);
05532             if (!(p = iaxs[callno])) {
05533                peer_unref(peer);
05534                return -1;
05535             }
05536             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05537             peer_unref(peer);
05538          }
05539          if (!peer) {
05540             ast_mutex_lock(&iaxsl[callno]);
05541             if (!(p = iaxs[callno]))
05542                return -1;
05543          }
05544       }
05545    }
05546    if (ies->encmethods)
05547       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05548    if (!res)
05549       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05550    return res;
05551 }
05552 
05553 static int iax2_do_register(struct iax2_registry *reg);
05554 
05555 static void __iax2_do_register_s(const void *data)
05556 {
05557    struct iax2_registry *reg = (struct iax2_registry *)data;
05558    reg->expire = -1;
05559    iax2_do_register(reg);
05560 }
05561 
05562 static int iax2_do_register_s(const void *data)
05563 {
05564 #ifdef SCHED_MULTITHREADED
05565    if (schedule_action(__iax2_do_register_s, data))
05566 #endif      
05567       __iax2_do_register_s(data);
05568    return 0;
05569 }
05570 
05571 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05572 {
05573    int newcall = 0;
05574    char newip[256];
05575    struct iax_ie_data ied;
05576    struct sockaddr_in new;
05577    
05578    
05579    memset(&ied, 0, sizeof(ied));
05580    if (ies->apparent_addr)
05581       bcopy(ies->apparent_addr, &new, sizeof(new));
05582    if (ies->callno)
05583       newcall = ies->callno;
05584    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05585       ast_log(LOG_WARNING, "Invalid transfer request\n");
05586       return -1;
05587    }
05588    pvt->transfercallno = newcall;
05589    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05590    inet_aton(newip, &pvt->transfer.sin_addr);
05591    pvt->transfer.sin_family = AF_INET;
05592    pvt->transferring = TRANSFER_BEGIN;
05593    pvt->transferid = ies->transferid;
05594    if (ies->transferid)
05595       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05596    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05597    return 0; 
05598 }
05599 
05600 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05601 {
05602    char exten[256] = "";
05603    int status = CACHE_FLAG_UNKNOWN;
05604    int expiry = iaxdefaultdpcache;
05605    int x;
05606    int matchmore = 0;
05607    struct iax2_dpcache *dp, *prev;
05608    
05609    if (ies->called_number)
05610       ast_copy_string(exten, ies->called_number, sizeof(exten));
05611 
05612    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05613       status = CACHE_FLAG_EXISTS;
05614    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05615       status = CACHE_FLAG_CANEXIST;
05616    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05617       status = CACHE_FLAG_NONEXISTENT;
05618 
05619    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05620       /* Don't really do anything with this */
05621    }
05622    if (ies->refresh)
05623       expiry = ies->refresh;
05624    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05625       matchmore = CACHE_FLAG_MATCHMORE;
05626    ast_mutex_lock(&dpcache_lock);
05627    prev = NULL;
05628    dp = pvt->dpentries;
05629    while(dp) {
05630       if (!strcmp(dp->exten, exten)) {
05631          /* Let them go */
05632          if (prev)
05633             prev->peer = dp->peer;
05634          else
05635             pvt->dpentries = dp->peer;
05636          dp->peer = NULL;
05637          dp->callno = 0;
05638          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05639          if (dp->flags & CACHE_FLAG_PENDING) {
05640             dp->flags &= ~CACHE_FLAG_PENDING;
05641             dp->flags |= status;
05642             dp->flags |= matchmore;
05643          }
05644          /* Wake up waiters */
05645          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05646             if (dp->waiters[x] > -1)
05647                write(dp->waiters[x], "asdf", 4);
05648       }
05649       prev = dp;
05650       dp = dp->peer;
05651    }
05652    ast_mutex_unlock(&dpcache_lock);
05653    return 0;
05654 }
05655 
05656 static int complete_transfer(int callno, struct iax_ies *ies)
05657 {
05658    int peercallno = 0;
05659    struct chan_iax2_pvt *pvt = iaxs[callno];
05660    struct iax_frame *cur;
05661    jb_frame frame;
05662 
05663    if (ies->callno)
05664       peercallno = ies->callno;
05665 
05666    if (peercallno < 1) {
05667       ast_log(LOG_WARNING, "Invalid transfer request\n");
05668       return -1;
05669    }
05670    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05671    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05672    /* Reset sequence numbers */
05673    pvt->oseqno = 0;
05674    pvt->rseqno = 0;
05675    pvt->iseqno = 0;
05676    pvt->aseqno = 0;
05677    pvt->peercallno = peercallno;
05678    pvt->transferring = TRANSFER_NONE;
05679    pvt->svoiceformat = -1;
05680    pvt->voiceformat = 0;
05681    pvt->svideoformat = -1;
05682    pvt->videoformat = 0;
05683    pvt->transfercallno = -1;
05684    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05685    memset(&pvt->offset, 0, sizeof(pvt->offset));
05686    /* reset jitterbuffer */
05687    while(jb_getall(pvt->jb,&frame) == JB_OK)
05688       iax2_frame_free(frame.data);
05689    jb_reset(pvt->jb);
05690    pvt->lag = 0;
05691    pvt->last = 0;
05692    pvt->lastsent = 0;
05693    pvt->nextpred = 0;
05694    pvt->pingtime = DEFAULT_RETRY_TIME;
05695    AST_LIST_LOCK(&iaxq.queue);
05696    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05697       /* We must cancel any packets that would have been transmitted
05698          because now we're talking to someone new.  It's okay, they
05699          were transmitted to someone that didn't care anyway. */
05700       if (callno == cur->callno) 
05701          cur->retries = -1;
05702    }
05703    AST_LIST_UNLOCK(&iaxq.queue);
05704    return 0; 
05705 }
05706 
05707 /*! \brief Acknowledgment received for OUR registration */
05708 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05709 {
05710    struct iax2_registry *reg;
05711    /* Start pessimistic */
05712    char peer[256] = "";
05713    char msgstatus[60];
05714    int refresh = 60;
05715    char ourip[256] = "<Unspecified>";
05716    struct sockaddr_in oldus;
05717    struct sockaddr_in us;
05718    int oldmsgs;
05719 
05720    memset(&us, 0, sizeof(us));
05721    if (ies->apparent_addr)
05722       bcopy(ies->apparent_addr, &us, sizeof(us));
05723    if (ies->username)
05724       ast_copy_string(peer, ies->username, sizeof(peer));
05725    if (ies->refresh)
05726       refresh = ies->refresh;
05727    if (ies->calling_number) {
05728       /* We don't do anything with it really, but maybe we should */
05729    }
05730    reg = iaxs[callno]->reg;
05731    if (!reg) {
05732       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05733       return -1;
05734    }
05735    memcpy(&oldus, &reg->us, sizeof(oldus));
05736    oldmsgs = reg->messages;
05737    if (inaddrcmp(&reg->addr, sin)) {
05738       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05739       return -1;
05740    }
05741    memcpy(&reg->us, &us, sizeof(reg->us));
05742    if (ies->msgcount >= 0)
05743       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05744    /* always refresh the registration at the interval requested by the server
05745       we are registering to
05746    */
05747    reg->refresh = refresh;
05748    if (reg->expire > -1)
05749       ast_sched_del(sched, reg->expire);
05750    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05751    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05752       if (option_verbose > 2) {
05753          if (reg->messages > 255)
05754             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05755          else if (reg->messages > 1)
05756             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05757          else if (reg->messages > 0)
05758             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05759          else
05760             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05761          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05762          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05763       }
05764       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05765    }
05766    reg->regstate = REG_STATE_REGISTERED;
05767    return 0;
05768 }
05769 
05770 static int iax2_register(char *value, int lineno)
05771 {
05772    struct iax2_registry *reg;
05773    char copy[256];
05774    char *username, *hostname, *secret;
05775    char *porta;
05776    char *stringp=NULL;
05777    
05778    if (!value)
05779       return -1;
05780    ast_copy_string(copy, value, sizeof(copy));
05781    stringp=copy;
05782    username = strsep(&stringp, "@");
05783    hostname = strsep(&stringp, "@");
05784    if (!hostname) {
05785       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05786       return -1;
05787    }
05788    stringp=username;
05789    username = strsep(&stringp, ":");
05790    secret = strsep(&stringp, ":");
05791    stringp=hostname;
05792    hostname = strsep(&stringp, ":");
05793    porta = strsep(&stringp, ":");
05794    
05795    if (porta && !atoi(porta)) {
05796       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05797       return -1;
05798    }
05799    if (!(reg = ast_calloc(1, sizeof(*reg))))
05800       return -1;
05801    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05802       free(reg);
05803       return -1;
05804    }
05805    ast_copy_string(reg->username, username, sizeof(reg->username));
05806    if (secret)
05807       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05808    reg->expire = -1;
05809    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05810    reg->addr.sin_family = AF_INET;
05811    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05812    AST_LIST_LOCK(&registrations);
05813    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05814    AST_LIST_UNLOCK(&registrations);
05815    
05816    return 0;
05817 }
05818 
05819 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05820 {
05821    char multi[256];
05822    char *stringp, *ext;
05823    if (!ast_strlen_zero(regcontext)) {
05824       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05825       stringp = multi;
05826       while((ext = strsep(&stringp, "&"))) {
05827          if (onoff) {
05828             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05829                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05830                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05831          } else
05832             ast_context_remove_extension(regcontext, ext, 1, NULL);
05833       }
05834    }
05835 }
05836 static void prune_peers(void);
05837 
05838 static void unlink_peer(struct iax2_peer *peer)
05839 {
05840    if (peer->expire > -1) {
05841       if (!ast_sched_del(sched, peer->expire)) {
05842          peer->expire = -1;
05843          peer_unref(peer);
05844       }
05845    }
05846 
05847    if (peer->pokeexpire > -1) {
05848       if (!ast_sched_del(sched, peer->pokeexpire)) {
05849          peer->pokeexpire = -1;
05850          peer_unref(peer);
05851       }
05852    }
05853 
05854    ao2_unlink(peers, peer);
05855 }
05856 
05857 static void __expire_registry(const void *data)
05858 {
05859    struct iax2_peer *peer = (struct iax2_peer *) data;
05860 
05861    if (!peer)
05862       return;
05863 
05864    peer->expire = -1;
05865 
05866    if (option_debug)
05867       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
05868    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05869       realtime_update_peer(peer->name, &peer->addr, 0);
05870    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05871    /* Reset the address */
05872    memset(&peer->addr, 0, sizeof(peer->addr));
05873    /* Reset expiry value */
05874    peer->expiry = min_reg_expire;
05875    if (!ast_test_flag(peer, IAX_TEMPONLY))
05876       ast_db_del("IAX/Registry", peer->name);
05877    register_peer_exten(peer, 0);
05878    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
05879    if (iax2_regfunk)
05880       iax2_regfunk(peer->name, 0);
05881 
05882    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
05883       unlink_peer(peer);
05884 
05885    peer_unref(peer);
05886 }
05887 
05888 static int expire_registry(const void *data)
05889 {
05890 #ifdef SCHED_MULTITHREADED
05891    if (schedule_action(__expire_registry, data))
05892 #endif      
05893       __expire_registry(data);
05894    return 0;
05895 }
05896 
05897 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05898 
05899 static void reg_source_db(struct iax2_peer *p)
05900 {
05901    char data[80];
05902    struct in_addr in;
05903    char *c, *d;
05904    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05905       c = strchr(data, ':');
05906       if (c) {
05907          *c = '\0';
05908          c++;
05909          if (inet_aton(data, &in)) {
05910             d = strchr(c, ':');
05911             if (d) {
05912                *d = '\0';
05913                d++;
05914                if (option_verbose > 2)
05915                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05916                   ast_inet_ntoa(in), atoi(c), atoi(d));
05917                iax2_poke_peer(p, 0);
05918                p->expiry = atoi(d);
05919                memset(&p->addr, 0, sizeof(p->addr));
05920                p->addr.sin_family = AF_INET;
05921                p->addr.sin_addr = in;
05922                p->addr.sin_port = htons(atoi(c));
05923                if (p->expire > -1) {
05924                   if (!ast_sched_del(sched, p->expire)) {
05925                      p->expire = -1;
05926                      peer_unref(p);
05927                   }
05928                }
05929                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05930                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
05931                if (p->expire == -1)
05932                   peer_unref(p);
05933                if (iax2_regfunk)
05934                   iax2_regfunk(p->name, 1);
05935                register_peer_exten(p, 1);
05936             }              
05937                
05938          }
05939       }
05940    }
05941 }
05942 
05943 /*!
05944  * \pre iaxsl[callno] is locked
05945  *
05946  * \note Since this function calls send_command_final(), the pvt struct for
05947  *       the given call number may disappear while executing this function.
05948  */
05949 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05950 {
05951    /* Called from IAX thread only, with proper iaxsl lock */
05952    struct iax_ie_data ied;
05953    struct iax2_peer *p;
05954    int msgcount;
05955    char data[80];
05956    int version;
05957    const char *peer_name;
05958    int res = -1;
05959 
05960    memset(&ied, 0, sizeof(ied));
05961 
05962    peer_name = ast_strdupa(iaxs[callno]->peer);
05963 
05964    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05965    ast_mutex_unlock(&iaxsl[callno]);
05966    if (!(p = find_peer(peer_name, 1))) {
05967       ast_mutex_lock(&iaxsl[callno]);
05968       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
05969       return -1;
05970    }
05971    ast_mutex_lock(&iaxsl[callno]);
05972    if (!iaxs[callno])
05973       goto return_unref;
05974 
05975    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05976       if (sin->sin_addr.s_addr) {
05977          time_t nowtime;
05978          time(&nowtime);
05979          realtime_update_peer(peer_name, sin, nowtime);
05980       } else {
05981          realtime_update_peer(peer_name, sin, 0);
05982       }
05983    }
05984    if (inaddrcmp(&p->addr, sin)) {
05985       if (iax2_regfunk)
05986          iax2_regfunk(p->name, 1);
05987       /* Stash the IP address from which they registered */
05988       memcpy(&p->addr, sin, sizeof(p->addr));
05989       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05990       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05991          ast_db_put("IAX/Registry", p->name, data);
05992          if  (option_verbose > 2)
05993             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05994                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
05995          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05996          register_peer_exten(p, 1);
05997          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05998       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05999          if  (option_verbose > 2)
06000             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06001                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06002          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06003          register_peer_exten(p, 0);
06004          ast_db_del("IAX/Registry", p->name);
06005          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06006       }
06007       /* Update the host */
06008       /* Verify that the host is really there */
06009       iax2_poke_peer(p, callno);
06010    }     
06011 
06012    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06013    if (!iaxs[callno]) {
06014       res = 0;
06015       goto return_unref;
06016    }
06017 
06018    /* Store socket fd */
06019    p->sockfd = fd;
06020    /* Setup the expiry */
06021    if (p->expire > -1) {
06022       if (!ast_sched_del(sched, p->expire)) {
06023          p->expire = -1;
06024          peer_unref(p);
06025       }
06026    }
06027    /* treat an unspecified refresh interval as the minimum */
06028    if (!refresh)
06029       refresh = min_reg_expire;
06030    if (refresh > max_reg_expire) {
06031       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06032          p->name, max_reg_expire, refresh);
06033       p->expiry = max_reg_expire;
06034    } else if (refresh < min_reg_expire) {
06035       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06036          p->name, min_reg_expire, refresh);
06037       p->expiry = min_reg_expire;
06038    } else {
06039       p->expiry = refresh;
06040    }
06041    if (p->expiry && sin->sin_addr.s_addr) {
06042       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06043       if (p->expire == -1)
06044          peer_unref(p);
06045    }
06046    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06047    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06048    if (sin->sin_addr.s_addr) {
06049       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06050       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06051       if (!ast_strlen_zero(p->mailbox)) {
06052          int new, old;
06053          ast_app_inboxcount(p->mailbox, &new, &old);
06054          if (new > 255)
06055             new = 255;
06056          if (old > 255)
06057             old = 255;
06058          msgcount = (old << 8) | new;
06059          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06060       }
06061       if (ast_test_flag(p, IAX_HASCALLERID)) {
06062          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06063          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06064       }
06065    }
06066    version = iax_check_version(devtype);
06067    if (version) 
06068       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06069 
06070    res = 0;
06071 
06072 return_unref:
06073    peer_unref(p);
06074 
06075    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06076 }
06077 
06078 static int registry_authrequest(int callno)
06079 {
06080    struct iax_ie_data ied;
06081    struct iax2_peer *p;
06082    char challenge[10];
06083    const char *peer_name;
06084    int res = -1;
06085 
06086    peer_name = ast_strdupa(iaxs[callno]->peer);
06087 
06088    /* SLD: third call to find_peer in registration */
06089    ast_mutex_unlock(&iaxsl[callno]);
06090    p = find_peer(peer_name, 1);
06091    ast_mutex_lock(&iaxsl[callno]);
06092    if (!iaxs[callno])
06093       goto return_unref;
06094    if (!p) {
06095       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06096       goto return_unref;
06097    }
06098    
06099    memset(&ied, 0, sizeof(ied));
06100    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06101    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06102       /* Build the challenge */
06103       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06104       ast_string_field_set(iaxs[callno], challenge, challenge);
06105       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06106    }
06107    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06108 
06109    res = 0;
06110 
06111 return_unref:
06112    peer_unref(p);
06113 
06114    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06115 }
06116 
06117 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06118 {
06119    struct iax2_registry *reg;
06120    /* Start pessimistic */
06121    struct iax_ie_data ied;
06122    char peer[256] = "";
06123    char challenge[256] = "";
06124    int res;
06125    int authmethods = 0;
06126    if (ies->authmethods)
06127       authmethods = ies->authmethods;
06128    if (ies->username)
06129       ast_copy_string(peer, ies->username, sizeof(peer));
06130    if (ies->challenge)
06131       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06132    memset(&ied, 0, sizeof(ied));
06133    reg = iaxs[callno]->reg;
06134    if (reg) {
06135          if (inaddrcmp(&reg->addr, sin)) {
06136             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06137             return -1;
06138          }
06139          if (ast_strlen_zero(reg->secret)) {
06140             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06141             reg->regstate = REG_STATE_NOAUTH;
06142             return -1;
06143          }
06144          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06145          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06146          if (reg->secret[0] == '[') {
06147             char tmpkey[256];
06148             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06149             tmpkey[strlen(tmpkey) - 1] = '\0';
06150             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06151          } else
06152             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06153          if (!res) {
06154             reg->regstate = REG_STATE_AUTHSENT;
06155             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06156          } else
06157             return -1;
06158          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06159    } else   
06160       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06161    return -1;
06162 }
06163 
06164 static void stop_stuff(int callno)
06165 {
06166    iax2_destroy_helper(iaxs[callno]);
06167 }
06168 
06169 static void __auth_reject(const void *nothing)
06170 {
06171    /* Called from IAX thread only, without iaxs lock */
06172    int callno = (int)(long)(nothing);
06173    struct iax_ie_data ied;
06174    ast_mutex_lock(&iaxsl[callno]);
06175    if (iaxs[callno]) {
06176       memset(&ied, 0, sizeof(ied));
06177       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06178          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06179          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06180       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06181          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06182          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06183       }
06184       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06185    }
06186    ast_mutex_unlock(&iaxsl[callno]);
06187 }
06188 
06189 static int auth_reject(const void *data)
06190 {
06191    int callno = (int)(long)(data);
06192    ast_mutex_lock(&iaxsl[callno]);
06193    if (iaxs[callno])
06194       iaxs[callno]->authid = -1;
06195    ast_mutex_unlock(&iaxsl[callno]);
06196 #ifdef SCHED_MULTITHREADED
06197    if (schedule_action(__auth_reject, data))
06198 #endif      
06199       __auth_reject(data);
06200    return 0;
06201 }
06202 
06203 static int auth_fail(int callno, int failcode)
06204 {
06205    /* Schedule sending the authentication failure in one second, to prevent
06206       guessing */
06207    if (iaxs[callno]) {
06208       iaxs[callno]->authfail = failcode;
06209       if (delayreject) {
06210          if (iaxs[callno]->authid > -1)
06211             ast_sched_del(sched, iaxs[callno]->authid);
06212          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06213       } else
06214          auth_reject((void *)(long)callno);
06215    }
06216    return 0;
06217 }
06218 
06219 static void __auto_hangup(const void *nothing)
06220 {
06221    /* Called from IAX thread only, without iaxs lock */
06222    int callno = (int)(long)(nothing);
06223    struct iax_ie_data ied;
06224    ast_mutex_lock(&iaxsl[callno]);
06225    if (iaxs[callno]) {
06226       memset(&ied, 0, sizeof(ied));
06227       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06228       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06229       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06230    }
06231    ast_mutex_unlock(&iaxsl[callno]);
06232 }
06233 
06234 static int auto_hangup(const void *data)
06235 {
06236    int callno = (int)(long)(data);
06237    ast_mutex_lock(&iaxsl[callno]);
06238    if (iaxs[callno]) {
06239       iaxs[callno]->autoid = -1;
06240    }
06241    ast_mutex_unlock(&iaxsl[callno]);
06242 #ifdef SCHED_MULTITHREADED
06243    if (schedule_action(__auto_hangup, data))
06244 #endif      
06245       __auto_hangup(data);
06246    return 0;
06247 }
06248 
06249 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06250 {
06251    struct iax_ie_data ied;
06252    /* Auto-hangup with 30 seconds of inactivity */
06253    if (iaxs[callno]->autoid > -1)
06254       ast_sched_del(sched, iaxs[callno]->autoid);
06255    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06256    memset(&ied, 0, sizeof(ied));
06257    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06258    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06259    dp->flags |= CACHE_FLAG_TRANSMITTED;
06260 }
06261 
06262 static int iax2_vnak(int callno)
06263 {
06264    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06265 }
06266 
06267 static void vnak_retransmit(int callno, int last)
06268 {
06269    struct iax_frame *f;
06270 
06271    AST_LIST_LOCK(&iaxq.queue);
06272    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06273       /* Send a copy immediately */
06274       if ((f->callno == callno) && iaxs[f->callno] &&
06275          ((unsigned char ) (f->oseqno - last) < 128) &&
06276          (f->retries >= 0)) {
06277          send_packet(f);
06278       }
06279    }
06280    AST_LIST_UNLOCK(&iaxq.queue);
06281 }
06282 
06283 static void __iax2_poke_peer_s(const void *data)
06284 {
06285    struct iax2_peer *peer = (struct iax2_peer *)data;
06286    iax2_poke_peer(peer, 0);
06287    peer_unref(peer);
06288 }
06289 
06290 static int iax2_poke_peer_s(const void *data)
06291 {
06292    struct iax2_peer *peer = (struct iax2_peer *)data;
06293    peer->pokeexpire = -1;
06294 #ifdef SCHED_MULTITHREADED
06295    if (schedule_action(__iax2_poke_peer_s, data))
06296 #endif      
06297       __iax2_poke_peer_s(data);
06298    return 0;
06299 }
06300 
06301 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06302 {
06303    int res = 0;
06304    struct iax_frame *fr;
06305    struct ast_iax2_meta_hdr *meta;
06306    struct ast_iax2_meta_trunk_hdr *mth;
06307    int calls = 0;
06308    
06309    /* Point to frame */
06310    fr = (struct iax_frame *)tpeer->trunkdata;
06311    /* Point to meta data */
06312    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06313    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06314    if (tpeer->trunkdatalen) {
06315       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06316       meta->zeros = 0;
06317       meta->metacmd = IAX_META_TRUNK;
06318       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06319          meta->cmddata = IAX_META_TRUNK_MINI;
06320       else
06321          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06322       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06323       /* And the rest of the ast_iax2 header */
06324       fr->direction = DIRECTION_OUTGRESS;
06325       fr->retrans = -1;
06326       fr->transfer = 0;
06327       /* Any appropriate call will do */
06328       fr->data = fr->afdata;
06329       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06330       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06331       calls = tpeer->calls;
06332 #if 0
06333       if (option_debug)
06334          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));
06335 #endif      
06336       /* Reset transmit trunk side data */
06337       tpeer->trunkdatalen = 0;
06338       tpeer->calls = 0;
06339    }
06340    if (res < 0)
06341       return res;
06342    return calls;
06343 }
06344 
06345 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06346 {
06347    /* Drop when trunk is about 5 seconds idle */
06348    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06349       return 1;
06350    return 0;
06351 }
06352 
06353 static int timing_read(int *id, int fd, short events, void *cbdata)
06354 {
06355    char buf[1024];
06356    int res;
06357    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06358    int processed = 0;
06359    int totalcalls = 0;
06360 #ifdef ZT_TIMERACK
06361    int x = 1;
06362 #endif
06363    struct timeval now;
06364    if (iaxtrunkdebug)
06365       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06366    gettimeofday(&now, NULL);
06367    if (events & AST_IO_PRI) {
06368 #ifdef ZT_TIMERACK
06369       /* Great, this is a timing interface, just call the ioctl */
06370       if (ioctl(fd, ZT_TIMERACK, &x)) 
06371          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06372       res = 0;
06373 #endif      
06374    } else {
06375       /* Read and ignore from the pseudo channel for timing */
06376       res = read(fd, buf, sizeof(buf));
06377       if (res < 1) {
06378          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06379          return 1;
06380       }
06381    }
06382    /* For each peer that supports trunking... */
06383    ast_mutex_lock(&tpeerlock);
06384    tpeer = tpeers;
06385    while(tpeer) {
06386       processed++;
06387       res = 0;
06388       ast_mutex_lock(&tpeer->lock);
06389       /* We can drop a single tpeer per pass.  That makes all this logic
06390          substantially easier */
06391       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06392          /* Take it out of the list, but don't free it yet, because it
06393             could be in use */
06394          if (prev)
06395             prev->next = tpeer->next;
06396          else
06397             tpeers = tpeer->next;
06398          drop = tpeer;
06399       } else {
06400          res = send_trunk(tpeer, &now);
06401          if (iaxtrunkdebug)
06402             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);
06403       }     
06404       totalcalls += res;   
06405       res = 0;
06406       ast_mutex_unlock(&tpeer->lock);
06407       prev = tpeer;
06408       tpeer = tpeer->next;
06409    }
06410    ast_mutex_unlock(&tpeerlock);
06411    if (drop) {
06412       ast_mutex_lock(&drop->lock);
06413       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06414          because by the time they could get tpeerlock, we've already grabbed it */
06415       if (option_debug)
06416          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06417       free(drop->trunkdata);
06418       ast_mutex_unlock(&drop->lock);
06419       ast_mutex_destroy(&drop->lock);
06420       free(drop);
06421       
06422    }
06423    if (iaxtrunkdebug)
06424       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06425    iaxtrunkdebug =0;
06426    return 1;
06427 }
06428 
06429 struct dpreq_data {
06430    int callno;
06431    char context[AST_MAX_EXTENSION];
06432    char callednum[AST_MAX_EXTENSION];
06433    char *callerid;
06434 };
06435 
06436 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06437 {
06438    unsigned short dpstatus = 0;
06439    struct iax_ie_data ied1;
06440    int mm;
06441 
06442    memset(&ied1, 0, sizeof(ied1));
06443    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06444    /* Must be started */
06445    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06446       dpstatus = IAX_DPSTATUS_EXISTS;
06447    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06448       dpstatus = IAX_DPSTATUS_CANEXIST;
06449    } else {
06450       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06451    }
06452    if (ast_ignore_pattern(context, callednum))
06453       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06454    if (mm)
06455       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06456    if (!skiplock)
06457       ast_mutex_lock(&iaxsl[callno]);
06458    if (iaxs[callno]) {
06459       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06460       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06461       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06462       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06463    }
06464    if (!skiplock)
06465       ast_mutex_unlock(&iaxsl[callno]);
06466 }
06467 
06468 static void *dp_lookup_thread(void *data)
06469 {
06470    /* Look up for dpreq */
06471    struct dpreq_data *dpr = data;
06472    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06473    if (dpr->callerid)
06474       free(dpr->callerid);
06475    free(dpr);
06476    return NULL;
06477 }
06478 
06479 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06480 {
06481    pthread_t newthread;
06482    struct dpreq_data *dpr;
06483    pthread_attr_t attr;
06484    
06485    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06486       return;
06487 
06488    pthread_attr_init(&attr);
06489    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06490 
06491    dpr->callno = callno;
06492    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06493    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06494    if (callerid)
06495       dpr->callerid = ast_strdup(callerid);
06496    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06497       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06498    }
06499 
06500    pthread_attr_destroy(&attr);
06501 }
06502 
06503 struct iax_dual {
06504    struct ast_channel *chan1;
06505    struct ast_channel *chan2;
06506 };
06507 
06508 static void *iax_park_thread(void *stuff)
06509 {
06510    struct ast_channel *chan1, *chan2;
06511    struct iax_dual *d;
06512    struct ast_frame *f;
06513    int ext;
06514    int res;
06515    d = stuff;
06516    chan1 = d->chan1;
06517    chan2 = d->chan2;
06518    free(d);
06519    f = ast_read(chan1);
06520    if (f)
06521       ast_frfree(f);
06522    res = ast_park_call(chan1, chan2, 0, &ext);
06523    ast_hangup(chan2);
06524    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06525    return NULL;
06526 }
06527 
06528 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06529 {
06530    struct iax_dual *d;
06531    struct ast_channel *chan1m, *chan2m;
06532    pthread_t th;
06533    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06534    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06535    if (chan2m && chan1m) {
06536       /* Make formats okay */
06537       chan1m->readformat = chan1->readformat;
06538       chan1m->writeformat = chan1->writeformat;
06539       ast_channel_masquerade(chan1m, chan1);
06540       /* Setup the extensions and such */
06541       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06542       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06543       chan1m->priority = chan1->priority;
06544       
06545       /* We make a clone of the peer channel too, so we can play
06546          back the announcement */
06547       /* Make formats okay */
06548       chan2m->readformat = chan2->readformat;
06549       chan2m->writeformat = chan2->writeformat;
06550       ast_channel_masquerade(chan2m, chan2);
06551       /* Setup the extensions and such */
06552       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06553       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06554       chan2m->priority = chan2->priority;
06555       if (ast_do_masquerade(chan2m)) {
06556          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06557          ast_hangup(chan2m);
06558          return -1;
06559       }
06560    } else {
06561       if (chan1m)
06562          ast_hangup(chan1m);
06563       if (chan2m)
06564          ast_hangup(chan2m);
06565       return -1;
06566    }
06567    if ((d = ast_calloc(1, sizeof(*d)))) {
06568       pthread_attr_t attr;
06569 
06570       pthread_attr_init(&attr);
06571       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06572 
06573       d->chan1 = chan1m;
06574       d->chan2 = chan2m;
06575       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06576          pthread_attr_destroy(&attr);
06577          return 0;
06578       }
06579       pthread_attr_destroy(&attr);
06580       free(d);
06581    }
06582    return -1;
06583 }
06584 
06585 
06586 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06587 
06588 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06589 {
06590    unsigned int ourver;
06591    char rsi[80];
06592    snprintf(rsi, sizeof(rsi), "si-%s", si);
06593    if (iax_provision_version(&ourver, rsi, 1))
06594       return 0;
06595    if (option_debug)
06596       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06597    if (ourver != ver) 
06598       iax2_provision(sin, sockfd, NULL, rsi, 1);
06599    return 0;
06600 }
06601 
06602 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06603 {
06604    jb_info stats;
06605    jb_getinfo(pvt->jb, &stats);
06606    
06607    memset(iep, 0, sizeof(*iep));
06608 
06609    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06610    if(stats.frames_in == 0) stats.frames_in = 1;
06611    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06612    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06613    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06614    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06615    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06616 }
06617 
06618 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06619 {
06620    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06621    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06622    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06623    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06624    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06625    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06626    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06627 }
06628 
06629 static int socket_process(struct iax2_thread *thread);
06630 
06631 /*!
06632  * \brief Handle any deferred full frames for this thread
06633  */
06634 static void handle_deferred_full_frames(struct iax2_thread *thread)
06635 {
06636    struct iax2_pkt_buf *pkt_buf;
06637 
06638    ast_mutex_lock(&thread->lock);
06639 
06640    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06641       ast_mutex_unlock(&thread->lock);
06642 
06643       thread->buf = pkt_buf->buf;
06644       thread->buf_len = pkt_buf->len;
06645       thread->buf_size = pkt_buf->len + 1;
06646       
06647       socket_process(thread);
06648 
06649       thread->buf = NULL;
06650       ast_free(pkt_buf);
06651 
06652       ast_mutex_lock(&thread->lock);
06653    }
06654 
06655    ast_mutex_unlock(&thread->lock);
06656 }
06657 
06658 /*!
06659  * \brief Queue the last read full frame for processing by a certain thread
06660  *
06661  * If there are already any full frames queued, they are sorted
06662  * by sequence number.
06663  */
06664 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06665 {
06666    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06667    struct ast_iax2_full_hdr *fh, *cur_fh;
06668 
06669    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06670       return;
06671 
06672    pkt_buf->len = from_here->buf_len;
06673    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06674 
06675    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06676    ast_mutex_lock(&to_here->lock);
06677    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06678       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06679       if (fh->oseqno < cur_fh->oseqno) {
06680          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06681          break;
06682       }
06683    }
06684    AST_LIST_TRAVERSE_SAFE_END
06685 
06686    if (!cur_pkt_buf)
06687       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06688    
06689    ast_mutex_unlock(&to_here->lock);
06690 }
06691 
06692 static int socket_read(int *id, int fd, short events, void *cbdata)
06693 {
06694    struct iax2_thread *thread;
06695    socklen_t len;
06696    time_t t;
06697    static time_t last_errtime = 0;
06698    struct ast_iax2_full_hdr *fh;
06699 
06700    if (!(thread = find_idle_thread())) {
06701       time(&t);
06702       if (t != last_errtime)
06703          ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
06704       last_errtime = t;
06705       usleep(1);
06706       return 1;
06707    }
06708 
06709    len = sizeof(thread->iosin);
06710    thread->iofd = fd;
06711    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06712    thread->buf_size = sizeof(thread->readbuf);
06713    thread->buf = thread->readbuf;
06714    if (thread->buf_len < 0) {
06715       if (errno != ECONNREFUSED && errno != EAGAIN)
06716          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06717       handle_error();
06718       thread->iostate = IAX_IOSTATE_IDLE;
06719       signal_condition(&thread->lock, &thread->cond);
06720       return 1;
06721    }
06722    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06723       thread->iostate = IAX_IOSTATE_IDLE;
06724       signal_condition(&thread->lock, &thread->cond);
06725       return 1;
06726    }
06727    
06728    /* Determine if this frame is a full frame; if so, and any thread is currently
06729       processing a full frame for the same callno from this peer, then drop this
06730       frame (and the peer will retransmit it) */
06731    fh = (struct ast_iax2_full_hdr *) thread->buf;
06732    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06733       struct iax2_thread *cur = NULL;
06734       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06735       
06736       AST_LIST_LOCK(&active_list);
06737       AST_LIST_TRAVERSE(&active_list, cur, list) {
06738          if ((cur->ffinfo.callno == callno) &&
06739              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06740             break;
06741       }
06742       if (cur) {
06743          /* we found another thread processing a full frame for this call,
06744             so queue it up for processing later. */
06745          defer_full_frame(thread, cur);
06746          AST_LIST_UNLOCK(&active_list);
06747          thread->iostate = IAX_IOSTATE_IDLE;
06748          signal_condition(&thread->lock, &thread->cond);
06749          return 1;
06750       } else {
06751          /* this thread is going to process this frame, so mark it */
06752          thread->ffinfo.callno = callno;
06753          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06754          thread->ffinfo.type = fh->type;
06755          thread->ffinfo.csub = fh->csub;
06756       }
06757       AST_LIST_UNLOCK(&active_list);
06758    }
06759    
06760    /* Mark as ready and send on its way */
06761    thread->iostate = IAX_IOSTATE_READY;
06762 #ifdef DEBUG_SCHED_MULTITHREAD
06763    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06764 #endif
06765    signal_condition(&thread->lock, &thread->cond);
06766 
06767    return 1;
06768 }
06769 
06770 static int socket_process(struct iax2_thread *thread)
06771 {
06772    struct sockaddr_in sin;
06773    int res;
06774    int updatehistory=1;
06775    int new = NEW_PREVENT;
06776    void *ptr;
06777    int dcallno = 0;
06778    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06779    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06780    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06781    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06782    struct ast_iax2_meta_trunk_hdr *mth;
06783    struct ast_iax2_meta_trunk_entry *mte;
06784    struct ast_iax2_meta_trunk_mini *mtm;
06785    struct iax_frame *fr;
06786    struct iax_frame *cur;
06787    struct ast_frame f = { 0, };
06788    struct ast_channel *c;
06789    struct iax2_dpcache *dp;
06790    struct iax2_peer *peer;
06791    struct iax2_trunk_peer *tpeer;
06792    struct timeval rxtrunktime;
06793    struct iax_ies ies;
06794    struct iax_ie_data ied0, ied1;
06795    int format;
06796    int fd;
06797    int exists;
06798    int minivid = 0;
06799    unsigned int ts;
06800    char empty[32]="";      /* Safety measure */
06801    struct iax_frame *duped_fr;
06802    char host_pref_buf[128];
06803    char caller_pref_buf[128];
06804    struct ast_codec_pref pref;
06805    char *using_prefs = "mine";
06806 
06807    /* allocate an iax_frame with 4096 bytes of data buffer */
06808    fr = alloca(sizeof(*fr) + 4096);
06809    fr->callno = 0;
06810    fr->afdatalen = 4096; /* From alloca() above */
06811 
06812    /* Copy frequently used parameters to the stack */
06813    res = thread->buf_len;
06814    fd = thread->iofd;
06815    memcpy(&sin, &thread->iosin, sizeof(sin));
06816 
06817    if (res < sizeof(*mh)) {
06818       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06819       return 1;
06820    }
06821    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06822       if (res < sizeof(*vh)) {
06823          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));
06824          return 1;
06825       }
06826 
06827       /* This is a video frame, get call number */
06828       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd);
06829       minivid = 1;
06830    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06831       unsigned char metatype;
06832 
06833       if (res < sizeof(*meta)) {
06834          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));
06835          return 1;
06836       }
06837 
06838       /* This is a meta header */
06839       switch(meta->metacmd) {
06840       case IAX_META_TRUNK:
06841          if (res < (sizeof(*meta) + sizeof(*mth))) {
06842             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06843                sizeof(*meta) + sizeof(*mth));
06844             return 1;
06845          }
06846          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06847          ts = ntohl(mth->ts);
06848          metatype = meta->cmddata;
06849          res -= (sizeof(*meta) + sizeof(*mth));
06850          ptr = mth->data;
06851          tpeer = find_tpeer(&sin, fd);
06852          if (!tpeer) {
06853             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));
06854             return 1;
06855          }
06856          tpeer->trunkact = ast_tvnow();
06857          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06858             tpeer->rxtrunktime = tpeer->trunkact;
06859          rxtrunktime = tpeer->rxtrunktime;
06860          ast_mutex_unlock(&tpeer->lock);
06861          while(res >= sizeof(*mte)) {
06862             /* Process channels */
06863             unsigned short callno, trunked_ts, len;
06864 
06865             if (metatype == IAX_META_TRUNK_MINI) {
06866                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06867                ptr += sizeof(*mtm);
06868                res -= sizeof(*mtm);
06869                len = ntohs(mtm->len);
06870                callno = ntohs(mtm->mini.callno);
06871                trunked_ts = ntohs(mtm->mini.ts);
06872             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06873                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06874                ptr += sizeof(*mte);
06875                res -= sizeof(*mte);
06876                len = ntohs(mte->len);
06877                callno = ntohs(mte->callno);
06878                trunked_ts = 0;
06879             } else {
06880                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06881                break;
06882             }
06883             /* Stop if we don't have enough data */
06884             if (len > res)
06885                break;
06886             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd);
06887             if (fr->callno) {
06888                ast_mutex_lock(&iaxsl[fr->callno]);
06889                /* If it's a valid call, deliver the contents.  If not, we
06890                   drop it, since we don't have a scallno to use for an INVAL */
06891                /* Process as a mini frame */
06892                memset(&f, 0, sizeof(f));
06893                f.frametype = AST_FRAME_VOICE;
06894                if (iaxs[fr->callno]) {
06895                   if (iaxs[fr->callno]->voiceformat > 0) {
06896                      f.subclass = iaxs[fr->callno]->voiceformat;
06897                      f.datalen = len;
06898                      if (f.datalen >= 0) {
06899                         if (f.datalen)
06900                            f.data = ptr;
06901                         if(trunked_ts) {
06902                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06903                         } else
06904                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06905                         /* Don't pass any packets until we're started */
06906                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06907                            /* Common things */
06908                            f.src = "IAX2";
06909                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06910                               f.samples = ast_codec_get_samples(&f);
06911                            iax_frame_wrap(fr, &f);
06912                            duped_fr = iaxfrdup2(fr);
06913                            if (duped_fr) {
06914                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06915                            }
06916                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
06917                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06918                               iaxs[fr->callno]->last = fr->ts;
06919 #if 1
06920                               if (option_debug && iaxdebug)
06921                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06922 #endif
06923                            }
06924                         }
06925                      } else {
06926                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06927                      }
06928                   } else {
06929                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06930                      iax2_vnak(fr->callno);
06931                   }
06932                }
06933                ast_mutex_unlock(&iaxsl[fr->callno]);
06934             }
06935             ptr += len;
06936             res -= len;
06937          }
06938          
06939       }
06940       return 1;
06941    }
06942 
06943 #ifdef DEBUG_SUPPORT
06944    if (iaxdebug && (res >= sizeof(*fh)))
06945       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06946 #endif
06947    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06948       if (res < sizeof(*fh)) {
06949          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));
06950          return 1;
06951       }
06952 
06953       /* Get the destination call number */
06954       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06955       /* Retrieve the type and subclass */
06956       f.frametype = fh->type;
06957       if (f.frametype == AST_FRAME_VIDEO) {
06958          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06959       } else {
06960          f.subclass = uncompress_subclass(fh->csub);
06961       }
06962       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06963                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06964                          (f.subclass == IAX_COMMAND_REGREL)))
06965          new = NEW_ALLOW;
06966    } else {
06967       /* Don't know anything about it yet */
06968       f.frametype = AST_FRAME_NULL;
06969       f.subclass = 0;
06970    }
06971 
06972    if (!fr->callno)
06973       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd);
06974 
06975    if (fr->callno > 0)
06976       ast_mutex_lock(&iaxsl[fr->callno]);
06977 
06978    if (!fr->callno || !iaxs[fr->callno]) {
06979       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06980          frame, reply with an inval */
06981       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06982          /* We can only raw hangup control frames */
06983          if (((f.subclass != IAX_COMMAND_INVAL) &&
06984              (f.subclass != IAX_COMMAND_TXCNT) &&
06985              (f.subclass != IAX_COMMAND_TXACC) &&
06986              (f.subclass != IAX_COMMAND_FWDOWNL))||
06987              (f.frametype != AST_FRAME_IAX))
06988             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06989             fd);
06990       }
06991       if (fr->callno > 0) 
06992          ast_mutex_unlock(&iaxsl[fr->callno]);
06993       return 1;
06994    }
06995    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06996       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06997          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06998          ast_mutex_unlock(&iaxsl[fr->callno]);
06999          return 1;
07000       }
07001 #ifdef DEBUG_SUPPORT
07002       else if (iaxdebug)
07003          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07004 #endif
07005    }
07006 
07007    /* count this frame */
07008    iaxs[fr->callno]->frames_received++;
07009 
07010    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07011       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07012       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
07013       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
07014    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07015       if (option_debug  && iaxdebug)
07016          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07017       /* Check if it's out of order (and not an ACK or INVAL) */
07018       fr->oseqno = fh->oseqno;
07019       fr->iseqno = fh->iseqno;
07020       fr->ts = ntohl(fh->ts);
07021 #ifdef IAXTESTS
07022       if (test_resync) {
07023          if (option_debug)
07024             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07025          fr->ts += test_resync;
07026       }
07027 #endif /* IAXTESTS */
07028 #if 0
07029       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07030            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07031                         (f.subclass == IAX_COMMAND_NEW ||
07032                          f.subclass == IAX_COMMAND_AUTHREQ ||
07033                          f.subclass == IAX_COMMAND_ACCEPT ||
07034                          f.subclass == IAX_COMMAND_REJECT))      ) )
07035 #endif
07036       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07037          updatehistory = 0;
07038       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07039          (iaxs[fr->callno]->iseqno ||
07040             ((f.subclass != IAX_COMMAND_TXCNT) &&
07041             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07042             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07043             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07044             (f.subclass != IAX_COMMAND_TXACC)) ||
07045             (f.frametype != AST_FRAME_IAX))) {
07046          if (
07047           ((f.subclass != IAX_COMMAND_ACK) &&
07048            (f.subclass != IAX_COMMAND_INVAL) &&
07049            (f.subclass != IAX_COMMAND_TXCNT) &&
07050            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07051            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07052            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07053            (f.subclass != IAX_COMMAND_TXACC) &&
07054            (f.subclass != IAX_COMMAND_VNAK)) ||
07055            (f.frametype != AST_FRAME_IAX)) {
07056             /* If it's not an ACK packet, it's out of order. */
07057             if (option_debug)
07058                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07059                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07060             /* Check to see if we need to request retransmission,
07061              * and take sequence number wraparound into account */
07062             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07063                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07064                if ((f.frametype != AST_FRAME_IAX) || 
07065                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07066                   if (option_debug)
07067                      ast_log(LOG_DEBUG, "Acking anyway\n");
07068                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07069                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07070                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07071                }
07072             } else {
07073                /* Send a VNAK requesting retransmission */
07074                iax2_vnak(fr->callno);
07075             }
07076             ast_mutex_unlock(&iaxsl[fr->callno]);
07077             return 1;
07078          }
07079       } else {
07080          /* Increment unless it's an ACK or VNAK */
07081          if (((f.subclass != IAX_COMMAND_ACK) &&
07082              (f.subclass != IAX_COMMAND_INVAL) &&
07083              (f.subclass != IAX_COMMAND_TXCNT) &&
07084              (f.subclass != IAX_COMMAND_TXACC) &&
07085             (f.subclass != IAX_COMMAND_VNAK)) ||
07086              (f.frametype != AST_FRAME_IAX))
07087             iaxs[fr->callno]->iseqno++;
07088       }
07089       /* A full frame */
07090       if (res < sizeof(*fh)) {
07091          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07092          ast_mutex_unlock(&iaxsl[fr->callno]);
07093          return 1;
07094       }
07095       /* Ensure text frames are NULL-terminated */
07096       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07097          if (res < thread->buf_size)
07098             thread->buf[res++] = '\0';
07099          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07100             thread->buf[res - 1] = '\0';
07101       }
07102       f.datalen = res - sizeof(*fh);
07103 
07104       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07105          from the real peer, not the transfer peer */
07106       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07107           ((f.subclass != IAX_COMMAND_INVAL) ||
07108            (f.frametype != AST_FRAME_IAX))) {
07109          unsigned char x;
07110          int call_to_destroy;
07111          /* XXX This code is not very efficient.  Surely there is a better way which still
07112                 properly handles boundary conditions? XXX */
07113          /* First we have to qualify that the ACKed value is within our window */
07114          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07115             if (fr->iseqno == x)
07116                break;
07117          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07118             /* The acknowledgement is within our window.  Time to acknowledge everything
07119                that it says to */
07120             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07121                /* Ack the packet with the given timestamp */
07122                if (option_debug && iaxdebug)
07123                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07124                call_to_destroy = 0;
07125                AST_LIST_LOCK(&iaxq.queue);
07126                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07127                   /* If it's our call, and our timestamp, mark -1 retries */
07128                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07129                      cur->retries = -1;
07130                      /* Destroy call if this is the end */
07131                      if (cur->final)
07132                         call_to_destroy = fr->callno;
07133                   }
07134                }
07135                AST_LIST_UNLOCK(&iaxq.queue);
07136                if (call_to_destroy) {
07137                   if (iaxdebug && option_debug)
07138                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07139                   iax2_destroy(call_to_destroy);
07140                }
07141             }
07142             /* Note how much we've received acknowledgement for */
07143             if (iaxs[fr->callno])
07144                iaxs[fr->callno]->rseqno = fr->iseqno;
07145             else {
07146                /* Stop processing now */
07147                ast_mutex_unlock(&iaxsl[fr->callno]);
07148                return 1;
07149             }
07150          } else if (option_debug)
07151             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07152       }
07153       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07154          ((f.frametype != AST_FRAME_IAX) || 
07155           ((f.subclass != IAX_COMMAND_TXACC) &&
07156            (f.subclass != IAX_COMMAND_TXCNT)))) {
07157          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07158          ast_mutex_unlock(&iaxsl[fr->callno]);
07159          return 1;
07160       }
07161 
07162       if (f.datalen) {
07163          if (f.frametype == AST_FRAME_IAX) {
07164             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07165                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07166                ast_mutex_unlock(&iaxsl[fr->callno]);
07167                return 1;
07168             }
07169             f.data = NULL;
07170             f.datalen = 0;
07171          } else
07172             f.data = thread->buf + sizeof(*fh);
07173       } else {
07174          if (f.frametype == AST_FRAME_IAX)
07175             f.data = NULL;
07176          else
07177             f.data = empty;
07178          memset(&ies, 0, sizeof(ies));
07179       }
07180 
07181       /* when we receive the first full frame for a new incoming channel,
07182          it is safe to start the PBX on the channel because we have now
07183          completed a 3-way handshake with the peer */
07184       if ((f.frametype == AST_FRAME_VOICE) ||
07185           (f.frametype == AST_FRAME_VIDEO) ||
07186           (f.frametype == AST_FRAME_IAX)) {
07187          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07188             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07189             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07190                ast_mutex_unlock(&iaxsl[fr->callno]);
07191                return 1;
07192             }
07193          }
07194       }
07195 
07196       if (f.frametype == AST_FRAME_VOICE) {
07197          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07198                iaxs[fr->callno]->voiceformat = f.subclass;
07199                if (option_debug)
07200                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07201                if (iaxs[fr->callno]->owner) {
07202                   int orignative;
07203 retryowner:
07204                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07205                      ast_mutex_unlock(&iaxsl[fr->callno]);
07206                      usleep(1);
07207                      ast_mutex_lock(&iaxsl[fr->callno]);
07208                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07209                   }
07210                   if (iaxs[fr->callno]) {
07211                      if (iaxs[fr->callno]->owner) {
07212                         orignative = iaxs[fr->callno]->owner->nativeformats;
07213                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07214                         if (iaxs[fr->callno]->owner->readformat)
07215                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07216                         iaxs[fr->callno]->owner->nativeformats = orignative;
07217                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07218                      }
07219                   } else {
07220                      if (option_debug)
07221                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07222                      ast_mutex_unlock(&iaxsl[fr->callno]);
07223                      return 1;
07224                   }
07225                }
07226          }
07227       }
07228       if (f.frametype == AST_FRAME_VIDEO) {
07229          if (f.subclass != iaxs[fr->callno]->videoformat) {
07230             if (option_debug)
07231                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07232             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07233          }
07234       }
07235       if (f.frametype == AST_FRAME_IAX) {
07236          if (iaxs[fr->callno]->initid > -1) {
07237             /* Don't auto congest anymore since we've gotten something usefulb ack */
07238             ast_sched_del(sched, iaxs[fr->callno]->initid);
07239             iaxs[fr->callno]->initid = -1;
07240          }
07241          /* Handle the IAX pseudo frame itself */
07242          if (option_debug && iaxdebug)
07243             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07244 
07245                         /* Update last ts unless the frame's timestamp originated with us. */
07246          if (iaxs[fr->callno]->last < fr->ts &&
07247                             f.subclass != IAX_COMMAND_ACK &&
07248                             f.subclass != IAX_COMMAND_PONG &&
07249                             f.subclass != IAX_COMMAND_LAGRP) {
07250             iaxs[fr->callno]->last = fr->ts;
07251             if (option_debug && iaxdebug)
07252                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07253          }
07254 
07255          switch(f.subclass) {
07256          case IAX_COMMAND_ACK:
07257             /* Do nothing */
07258             break;
07259          case IAX_COMMAND_QUELCH:
07260             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07261                     /* Generate Manager Hold event, if necessary*/
07262                if (iaxs[fr->callno]->owner) {
07263                   manager_event(EVENT_FLAG_CALL, "Hold",
07264                      "Channel: %s\r\n"
07265                      "Uniqueid: %s\r\n",
07266                      iaxs[fr->callno]->owner->name, 
07267                      iaxs[fr->callno]->owner->uniqueid);
07268                }
07269 
07270                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07271                if (ies.musiconhold) {
07272                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07273                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07274                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07275                         S_OR(mohsuggest, NULL),
07276                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07277                      if (!iaxs[fr->callno]) {
07278                         ast_mutex_unlock(&iaxsl[fr->callno]);
07279                         return 1;
07280                      }
07281                   }
07282                }
07283             }
07284             break;
07285          case IAX_COMMAND_UNQUELCH:
07286             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07287                     /* Generate Manager Unhold event, if necessary*/
07288                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07289                   manager_event(EVENT_FLAG_CALL, "Unhold",
07290                      "Channel: %s\r\n"
07291                      "Uniqueid: %s\r\n",
07292                      iaxs[fr->callno]->owner->name, 
07293                      iaxs[fr->callno]->owner->uniqueid);
07294                }
07295 
07296                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07297                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07298                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07299                   if (!iaxs[fr->callno]) {
07300                      ast_mutex_unlock(&iaxsl[fr->callno]);
07301                      return 1;
07302                   }
07303                }
07304             }
07305             break;
07306          case IAX_COMMAND_TXACC:
07307             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07308                /* Ack the packet with the given timestamp */
07309                AST_LIST_LOCK(&iaxq.queue);
07310                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07311                   /* Cancel any outstanding txcnt's */
07312                   if ((fr->callno == cur->callno) && (cur->transfer))
07313                      cur->retries = -1;
07314                }
07315                AST_LIST_UNLOCK(&iaxq.queue);
07316                memset(&ied1, 0, sizeof(ied1));
07317                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07318                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07319                iaxs[fr->callno]->transferring = TRANSFER_READY;
07320             }
07321             break;
07322          case IAX_COMMAND_NEW:
07323             /* Ignore if it's already up */
07324             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07325                break;
07326             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07327                ast_mutex_unlock(&iaxsl[fr->callno]);
07328                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07329                ast_mutex_lock(&iaxsl[fr->callno]);
07330                if (!iaxs[fr->callno]) {
07331                   ast_mutex_unlock(&iaxsl[fr->callno]);
07332                   return 1;
07333                }
07334             }
07335             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07336             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07337                int new_callno;
07338                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07339                   fr->callno = new_callno;
07340             }
07341             /* For security, always ack immediately */
07342             if (delayreject)
07343                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07344             if (check_access(fr->callno, &sin, &ies)) {
07345                /* They're not allowed on */
07346                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07347                if (authdebug)
07348                   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);
07349                break;
07350             }
07351             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07352                const char *context, *exten, *cid_num;
07353 
07354                context = ast_strdupa(iaxs[fr->callno]->context);
07355                exten = ast_strdupa(iaxs[fr->callno]->exten);
07356                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07357 
07358                /* This might re-enter the IAX code and need the lock */
07359                ast_mutex_unlock(&iaxsl[fr->callno]);
07360                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07361                ast_mutex_lock(&iaxsl[fr->callno]);
07362 
07363                if (!iaxs[fr->callno]) {
07364                   ast_mutex_unlock(&iaxsl[fr->callno]);
07365                   return 1;
07366                }
07367             } else
07368                exists = 0;
07369             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07370                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07371                   memset(&ied0, 0, sizeof(ied0));
07372                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07373                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07374                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07375                   if (!iaxs[fr->callno]) {
07376                      ast_mutex_unlock(&iaxsl[fr->callno]);
07377                      return 1;
07378                   }
07379                   if (authdebug)
07380                      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);
07381                } else {
07382                   /* Select an appropriate format */
07383 
07384                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07385                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07386                         using_prefs = "reqonly";
07387                      } else {
07388                         using_prefs = "disabled";
07389                      }
07390                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07391                      memset(&pref, 0, sizeof(pref));
07392                      strcpy(caller_pref_buf, "disabled");
07393                      strcpy(host_pref_buf, "disabled");
07394                   } else {
07395                      using_prefs = "mine";
07396                      /* If the information elements are in here... use them */
07397                      if (ies.codec_prefs)
07398                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07399                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07400                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07401                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07402                            pref = iaxs[fr->callno]->rprefs;
07403                            using_prefs = "caller";
07404                         } else {
07405                            pref = iaxs[fr->callno]->prefs;
07406                         }
07407                      } else
07408                         pref = iaxs[fr->callno]->prefs;
07409                      
07410                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07411                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07412                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07413                   }
07414                   if (!format) {
07415                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07416                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07417                      if (!format) {
07418                         memset(&ied0, 0, sizeof(ied0));
07419                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07420                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07421                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07422                         if (!iaxs[fr->callno]) {
07423                            ast_mutex_unlock(&iaxsl[fr->callno]);
07424                            return 1;
07425                         }
07426                         if (authdebug) {
07427                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07428                               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);
07429                            else 
07430                               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);
07431                         }
07432                      } else {
07433                         /* Pick one... */
07434                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07435                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07436                               format = 0;
07437                         } else {
07438                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07439                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07440                               memset(&pref, 0, sizeof(pref));
07441                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07442                               strcpy(caller_pref_buf,"disabled");
07443                               strcpy(host_pref_buf,"disabled");
07444                            } else {
07445                               using_prefs = "mine";
07446                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07447                                  /* Do the opposite of what we tried above. */
07448                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07449                                     pref = iaxs[fr->callno]->prefs;                       
07450                                  } else {
07451                                     pref = iaxs[fr->callno]->rprefs;
07452                                     using_prefs = "caller";
07453                                  }
07454                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07455                            
07456                               } else /* if no codec_prefs IE do it the old way */
07457                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07458                            }
07459                         }
07460 
07461                         if (!format) {
07462                            memset(&ied0, 0, sizeof(ied0));
07463                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07464                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07465                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07466                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07467                            if (!iaxs[fr->callno]) {
07468                               ast_mutex_unlock(&iaxsl[fr->callno]);
07469                               return 1;
07470                            }
07471                            if (authdebug)
07472                               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);
07473                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07474                            break;
07475                         }
07476                      }
07477                   }
07478                   if (format) {
07479                      /* No authentication required, let them in */
07480                      memset(&ied1, 0, sizeof(ied1));
07481                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07482                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07483                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07484                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07485                         if (option_verbose > 2) 
07486                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07487                                     "%srequested format = %s,\n"
07488                                     "%srequested prefs = %s,\n"
07489                                     "%sactual format = %s,\n"
07490                                     "%shost prefs = %s,\n"
07491                                     "%spriority = %s\n",
07492                                     ast_inet_ntoa(sin.sin_addr), 
07493                                     VERBOSE_PREFIX_4,
07494                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07495                                     VERBOSE_PREFIX_4,
07496                                     caller_pref_buf,
07497                                     VERBOSE_PREFIX_4,
07498                                     ast_getformatname(format), 
07499                                     VERBOSE_PREFIX_4,
07500                                     host_pref_buf, 
07501                                     VERBOSE_PREFIX_4,
07502                                     using_prefs);
07503                         
07504                         iaxs[fr->callno]->chosenformat = format;
07505                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07506                      } else {
07507                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07508                         /* If this is a TBD call, we're ready but now what...  */
07509                         if (option_verbose > 2)
07510                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07511                      }
07512                   }
07513                }
07514                break;
07515             }
07516             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07517                merge_encryption(iaxs[fr->callno],ies.encmethods);
07518             else
07519                iaxs[fr->callno]->encmethods = 0;
07520             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07521                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07522             if (!iaxs[fr->callno]) {
07523                ast_mutex_unlock(&iaxsl[fr->callno]);
07524                return 1;
07525             }
07526             break;
07527          case IAX_COMMAND_DPREQ:
07528             /* Request status in the dialplan */
07529             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07530                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07531                if (iaxcompat) {
07532                   /* Spawn a thread for the lookup */
07533                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07534                } else {
07535                   /* Just look it up */
07536                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07537                }
07538             }
07539             break;
07540          case IAX_COMMAND_HANGUP:
07541             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07542             if (option_debug)
07543                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07544             /* Set hangup cause according to remote */
07545             if (ies.causecode && iaxs[fr->callno]->owner)
07546                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07547             /* Send ack immediately, before we destroy */
07548             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07549             iax2_destroy(fr->callno);
07550             break;
07551          case IAX_COMMAND_REJECT:
07552             /* Set hangup cause according to remote */
07553             if (ies.causecode && iaxs[fr->callno]->owner)
07554                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07555 
07556             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07557                if (iaxs[fr->callno]->owner && authdebug)
07558                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07559                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07560                      ies.cause ? ies.cause : "<Unknown>");
07561                if (option_debug)
07562                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07563                      fr->callno);
07564             }
07565             /* Send ack immediately, before we destroy */
07566             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07567                          fr->ts, NULL, 0, fr->iseqno);
07568             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07569                iaxs[fr->callno]->error = EPERM;
07570             iax2_destroy(fr->callno);
07571             break;
07572          case IAX_COMMAND_TRANSFER:
07573             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07574                /* Set BLINDTRANSFER channel variables */
07575                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07576                pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07577                if (!strcmp(ies.called_number, ast_parking_ext())) {
07578                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07579                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07580                   } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
07581                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07582                } else {
07583                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07584                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07585                         ies.called_number, iaxs[fr->callno]->context);
07586                   else
07587                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07588                         ies.called_number, iaxs[fr->callno]->context);
07589                }
07590             } else
07591                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07592             break;
07593          case IAX_COMMAND_ACCEPT:
07594             /* Ignore if call is already up or needs authentication or is a TBD */
07595             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07596                break;
07597             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07598                /* Send ack immediately, before we destroy */
07599                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07600                iax2_destroy(fr->callno);
07601                break;
07602             }
07603             if (ies.format) {
07604                iaxs[fr->callno]->peerformat = ies.format;
07605             } else {
07606                if (iaxs[fr->callno]->owner)
07607                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07608                else
07609                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07610             }
07611             if (option_verbose > 2)
07612                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));
07613             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07614                memset(&ied0, 0, sizeof(ied0));
07615                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07616                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07617                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07618                if (!iaxs[fr->callno]) {
07619                   ast_mutex_unlock(&iaxsl[fr->callno]);
07620                   return 1;
07621                }
07622                if (authdebug)
07623                   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);
07624             } else {
07625                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07626                if (iaxs[fr->callno]->owner) {
07627                   /* Switch us to use a compatible format */
07628                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07629                   if (option_verbose > 2)
07630                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07631 retryowner2:
07632                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07633                      ast_mutex_unlock(&iaxsl[fr->callno]);
07634                      usleep(1);
07635                      ast_mutex_lock(&iaxsl[fr->callno]);
07636                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07637                   }
07638                   
07639                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07640                      /* Setup read/write formats properly. */
07641                      if (iaxs[fr->callno]->owner->writeformat)
07642                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07643                      if (iaxs[fr->callno]->owner->readformat)
07644                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07645                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07646                   }
07647                }
07648             }
07649             if (iaxs[fr->callno]) {
07650                ast_mutex_lock(&dpcache_lock);
07651                dp = iaxs[fr->callno]->dpentries;
07652                while(dp) {
07653                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07654                      iax2_dprequest(dp, fr->callno);
07655                   }
07656                   dp = dp->peer;
07657                }
07658                ast_mutex_unlock(&dpcache_lock);
07659             }
07660             break;
07661          case IAX_COMMAND_POKE:
07662             /* Send back a pong packet with the original timestamp */
07663             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07664             if (!iaxs[fr->callno]) {
07665                ast_mutex_unlock(&iaxsl[fr->callno]);
07666                return 1;
07667             }
07668             break;
07669          case IAX_COMMAND_PING:
07670          {
07671             struct iax_ie_data pingied;
07672             construct_rr(iaxs[fr->callno], &pingied);
07673             /* Send back a pong packet with the original timestamp */
07674             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07675          }
07676             break;
07677          case IAX_COMMAND_PONG:
07678             /* Calculate ping time */
07679             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07680             /* save RR info */
07681             save_rr(fr, &ies);
07682 
07683             if (iaxs[fr->callno]->peerpoke) {
07684                peer = iaxs[fr->callno]->peerpoke;
07685                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07686                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07687                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07688                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07689                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07690                   }
07691                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07692                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07693                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07694                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07695                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07696                   }
07697                }
07698                peer->lastms = iaxs[fr->callno]->pingtime;
07699                if (peer->smoothing && (peer->lastms > -1))
07700                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07701                else if (peer->smoothing && peer->lastms < 0)
07702                   peer->historicms = (0 + peer->historicms) / 2;
07703                else              
07704                   peer->historicms = iaxs[fr->callno]->pingtime;
07705 
07706                /* Remove scheduled iax2_poke_noanswer */
07707                if (peer->pokeexpire > -1) {
07708                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07709                      peer_unref(peer);
07710                      peer->pokeexpire = -1;
07711                   }
07712                }
07713                /* Schedule the next cycle */
07714                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07715                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07716                else
07717                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07718                if (peer->pokeexpire == -1)
07719                   peer_unref(peer);
07720                /* and finally send the ack */
07721                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07722                /* And wrap up the qualify call */
07723                iax2_destroy(fr->callno);
07724                peer->callno = 0;
07725                if (option_debug)
07726                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07727             }
07728             break;
07729          case IAX_COMMAND_LAGRQ:
07730          case IAX_COMMAND_LAGRP:
07731             f.src = "LAGRQ";
07732             f.mallocd = 0;
07733             f.offset = 0;
07734             f.samples = 0;
07735             iax_frame_wrap(fr, &f);
07736             if(f.subclass == IAX_COMMAND_LAGRQ) {
07737                /* Received a LAGRQ - echo back a LAGRP */
07738                fr->af.subclass = IAX_COMMAND_LAGRP;
07739                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07740             } else {
07741                /* Received LAGRP in response to our LAGRQ */
07742                unsigned int ts;
07743                /* This is a reply we've been given, actually measure the difference */
07744                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07745                iaxs[fr->callno]->lag = ts - fr->ts;
07746                if (option_debug && iaxdebug)
07747                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07748                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07749             }
07750             break;
07751          case IAX_COMMAND_AUTHREQ:
07752             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07753                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>");
07754                break;
07755             }
07756             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07757                ast_log(LOG_WARNING, 
07758                   "I don't know how to authenticate %s to %s\n", 
07759                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07760             }
07761             if (!iaxs[fr->callno]) {
07762                ast_mutex_unlock(&iaxsl[fr->callno]);
07763                return 1;
07764             }
07765             break;
07766          case IAX_COMMAND_AUTHREP:
07767             /* For security, always ack immediately */
07768             if (delayreject)
07769                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07770             /* Ignore once we've started */
07771             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07772                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>");
07773                break;
07774             }
07775             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07776                if (authdebug)
07777                   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);
07778                memset(&ied0, 0, sizeof(ied0));
07779                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07780                break;
07781             }
07782             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07783                /* This might re-enter the IAX code and need the lock */
07784                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07785             } else
07786                exists = 0;
07787             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07788                if (authdebug)
07789                   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);
07790                memset(&ied0, 0, sizeof(ied0));
07791                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07792                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07793                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07794                if (!iaxs[fr->callno]) {
07795                   ast_mutex_unlock(&iaxsl[fr->callno]);
07796                   return 1;
07797                }
07798             } else {
07799                /* Select an appropriate format */
07800                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07801                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07802                      using_prefs = "reqonly";
07803                   } else {
07804                      using_prefs = "disabled";
07805                   }
07806                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07807                   memset(&pref, 0, sizeof(pref));
07808                   strcpy(caller_pref_buf, "disabled");
07809                   strcpy(host_pref_buf, "disabled");
07810                } else {
07811                   using_prefs = "mine";
07812                   if (ies.codec_prefs)
07813                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07814                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07815                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07816                         pref = iaxs[fr->callno]->rprefs;
07817                         using_prefs = "caller";
07818                      } else {
07819                         pref = iaxs[fr->callno]->prefs;
07820                      }
07821                   } else /* if no codec_prefs IE do it the old way */
07822                      pref = iaxs[fr->callno]->prefs;
07823                
07824                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07825                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07826                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07827                }
07828                if (!format) {
07829                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07830                      if (option_debug)
07831                         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);
07832                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07833                   }
07834                   if (!format) {
07835                      if (authdebug) {
07836                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07837                            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);
07838                         else
07839                            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);
07840                      }
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                   } else {
07850                      /* Pick one... */
07851                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07852                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07853                            format = 0;
07854                      } else {
07855                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07856                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07857                            memset(&pref, 0, sizeof(pref));
07858                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07859                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07860                            strcpy(caller_pref_buf,"disabled");
07861                            strcpy(host_pref_buf,"disabled");
07862                         } else {
07863                            using_prefs = "mine";
07864                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07865                               /* Do the opposite of what we tried above. */
07866                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07867                                  pref = iaxs[fr->callno]->prefs;                 
07868                               } else {
07869                                  pref = iaxs[fr->callno]->rprefs;
07870                                  using_prefs = "caller";
07871                               }
07872                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07873                            } else /* if no codec_prefs IE do it the old way */
07874                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07875                         }
07876                      }
07877                      if (!format) {
07878                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07879                         if (authdebug) {
07880                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07881                               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);
07882                            else
07883                               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);
07884                         }
07885                         memset(&ied0, 0, sizeof(ied0));
07886                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07887                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07888                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07889                         if (!iaxs[fr->callno]) {
07890                            ast_mutex_unlock(&iaxsl[fr->callno]);
07891                            return 1;
07892                         }
07893                      }
07894                   }
07895                }
07896                if (format) {
07897                   /* Authentication received */
07898                   memset(&ied1, 0, sizeof(ied1));
07899                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07900                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07901                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07902                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07903                      if (option_verbose > 2) 
07904                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07905                                  "%srequested format = %s,\n"
07906                                  "%srequested prefs = %s,\n"
07907                                  "%sactual format = %s,\n"
07908                                  "%shost prefs = %s,\n"
07909                                  "%spriority = %s\n", 
07910                                  ast_inet_ntoa(sin.sin_addr), 
07911                                  VERBOSE_PREFIX_4,
07912                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07913                                  VERBOSE_PREFIX_4,
07914                                  caller_pref_buf,
07915                                  VERBOSE_PREFIX_4,
07916                                  ast_getformatname(format),
07917                                  VERBOSE_PREFIX_4,
07918                                  host_pref_buf,
07919                                  VERBOSE_PREFIX_4,
07920                                  using_prefs);
07921 
07922                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07923                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07924                         iax2_destroy(fr->callno);
07925                   } else {
07926                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07927                      /* If this is a TBD call, we're ready but now what...  */
07928                      if (option_verbose > 2)
07929                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07930                   }
07931                }
07932             }
07933             break;
07934          case IAX_COMMAND_DIAL:
07935             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07936                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07937                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07938                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07939                   if (authdebug)
07940                      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);
07941                   memset(&ied0, 0, sizeof(ied0));
07942                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07943                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07944                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07945                   if (!iaxs[fr->callno]) {
07946                      ast_mutex_unlock(&iaxsl[fr->callno]);
07947                      return 1;
07948                   }
07949                } else {
07950                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07951                   if (option_verbose > 2) 
07952                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
07953                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07954                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07955                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07956                      iax2_destroy(fr->callno);
07957                }
07958             }
07959             break;
07960          case IAX_COMMAND_INVAL:
07961             iaxs[fr->callno]->error = ENOTCONN;
07962             if (option_debug)
07963                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07964             iax2_destroy(fr->callno);
07965             if (option_debug)
07966                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07967             break;
07968          case IAX_COMMAND_VNAK:
07969             if (option_debug)
07970                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07971             /* Force retransmission */
07972             vnak_retransmit(fr->callno, fr->iseqno);
07973             break;
07974          case IAX_COMMAND_REGREQ:
07975          case IAX_COMMAND_REGREL:
07976             /* For security, always ack immediately */
07977             if (delayreject)
07978                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07979             if (register_verify(fr->callno, &sin, &ies)) {
07980                if (!iaxs[fr->callno]) {
07981                   ast_mutex_unlock(&iaxsl[fr->callno]);
07982                   return 1;
07983                }
07984                /* Send delayed failure */
07985                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07986                break;
07987             }
07988             if (!iaxs[fr->callno]) {
07989                ast_mutex_unlock(&iaxsl[fr->callno]);
07990                return 1;
07991             }
07992             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
07993                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
07994                if (f.subclass == IAX_COMMAND_REGREL)
07995                   memset(&sin, 0, sizeof(sin));
07996                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
07997                   ast_log(LOG_WARNING, "Registry error\n");
07998                if (!iaxs[fr->callno]) {
07999                   ast_mutex_unlock(&iaxsl[fr->callno]);
08000                   return 1;
08001                }
08002                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08003                   ast_mutex_unlock(&iaxsl[fr->callno]);
08004                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08005                   ast_mutex_lock(&iaxsl[fr->callno]);
08006                   if (!iaxs[fr->callno]) {
08007                      ast_mutex_unlock(&iaxsl[fr->callno]);
08008                      return 1;
08009                   }
08010                }
08011                break;
08012             }
08013             registry_authrequest(fr->callno);
08014             if (!iaxs[fr->callno]) {
08015                ast_mutex_unlock(&iaxsl[fr->callno]);
08016                return 1;
08017             }
08018             break;
08019          case IAX_COMMAND_REGACK:
08020             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08021                ast_log(LOG_WARNING, "Registration failure\n");
08022             /* Send ack immediately, before we destroy */
08023             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08024             iax2_destroy(fr->callno);
08025             break;
08026          case IAX_COMMAND_REGREJ:
08027             if (iaxs[fr->callno]->reg) {
08028                if (authdebug) {
08029                   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));
08030                   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>");
08031                }
08032                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08033             }
08034             /* Send ack immediately, before we destroy */
08035             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08036             iax2_destroy(fr->callno);
08037             break;
08038          case IAX_COMMAND_REGAUTH:
08039             /* Authentication request */
08040             if (registry_rerequest(&ies, fr->callno, &sin)) {
08041                memset(&ied0, 0, sizeof(ied0));
08042                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08043                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08044                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08045                if (!iaxs[fr->callno]) {
08046                   ast_mutex_unlock(&iaxsl[fr->callno]);
08047                   return 1;
08048                }
08049             }
08050             break;
08051          case IAX_COMMAND_TXREJ:
08052             iaxs[fr->callno]->transferring = 0;
08053             if (option_verbose > 2) 
08054                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08055             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08056             if (iaxs[fr->callno]->bridgecallno) {
08057                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08058                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08059                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08060                }
08061             }
08062             break;
08063          case IAX_COMMAND_TXREADY:
08064             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08065                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08066                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08067                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08068                else
08069                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08070                if (option_verbose > 2) 
08071                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08072                if (iaxs[fr->callno]->bridgecallno) {
08073                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08074                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08075                      /* They're both ready, now release them. */
08076                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08077                         if (option_verbose > 2) 
08078                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08079                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08080 
08081                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08082                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08083 
08084                         memset(&ied0, 0, sizeof(ied0));
08085                         memset(&ied1, 0, sizeof(ied1));
08086                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08087                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08088                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08089                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08090                      } else {
08091                         if (option_verbose > 2) 
08092                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08093                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08094 
08095                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08096                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08097                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08098                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08099 
08100                         /* Stop doing lag & ping requests */
08101                         stop_stuff(fr->callno);
08102                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08103 
08104                         memset(&ied0, 0, sizeof(ied0));
08105                         memset(&ied1, 0, sizeof(ied1));
08106                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08107                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08108                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08109                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08110                      }
08111 
08112                   }
08113                }
08114             }
08115             break;
08116          case IAX_COMMAND_TXREQ:
08117             try_transfer(iaxs[fr->callno], &ies);
08118             break;
08119          case IAX_COMMAND_TXCNT:
08120             if (iaxs[fr->callno]->transferring)
08121                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08122             break;
08123          case IAX_COMMAND_TXREL:
08124             /* Send ack immediately, rather than waiting until we've changed addresses */
08125             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08126             complete_transfer(fr->callno, &ies);
08127             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08128             break;   
08129          case IAX_COMMAND_TXMEDIA:
08130             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08131                                         AST_LIST_LOCK(&iaxq.queue);
08132                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08133                                                 /* Cancel any outstanding frames and start anew */
08134                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08135                                                         cur->retries = -1;
08136                                                 }
08137                                         }
08138                                         AST_LIST_UNLOCK(&iaxq.queue);
08139                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08140                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08141             }
08142             break;   
08143          case IAX_COMMAND_DPREP:
08144             complete_dpreply(iaxs[fr->callno], &ies);
08145             break;
08146          case IAX_COMMAND_UNSUPPORT:
08147             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08148             break;
08149          case IAX_COMMAND_FWDOWNL:
08150             /* Firmware download */
08151             memset(&ied0, 0, sizeof(ied0));
08152             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08153             if (res < 0)
08154                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08155             else if (res > 0)
08156                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08157             else
08158                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08159             if (!iaxs[fr->callno]) {
08160                ast_mutex_unlock(&iaxsl[fr->callno]);
08161                return 1;
08162             }
08163             break;
08164          default:
08165             if (option_debug)
08166                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08167             memset(&ied0, 0, sizeof(ied0));
08168             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08169             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08170          }
08171          /* Don't actually pass these frames along */
08172          if ((f.subclass != IAX_COMMAND_ACK) && 
08173            (f.subclass != IAX_COMMAND_TXCNT) && 
08174            (f.subclass != IAX_COMMAND_TXACC) && 
08175            (f.subclass != IAX_COMMAND_INVAL) &&
08176            (f.subclass != IAX_COMMAND_VNAK)) { 
08177             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08178                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08179          }
08180          ast_mutex_unlock(&iaxsl[fr->callno]);
08181          return 1;
08182       }
08183       /* Unless this is an ACK or INVAL frame, ack it */
08184       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08185          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08186    } else if (minivid) {
08187       f.frametype = AST_FRAME_VIDEO;
08188       if (iaxs[fr->callno]->videoformat > 0) 
08189          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08190       else {
08191          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08192          iax2_vnak(fr->callno);
08193          ast_mutex_unlock(&iaxsl[fr->callno]);
08194          return 1;
08195       }
08196       f.datalen = res - sizeof(*vh);
08197       if (f.datalen)
08198          f.data = thread->buf + sizeof(*vh);
08199       else
08200          f.data = NULL;
08201 #ifdef IAXTESTS
08202       if (test_resync) {
08203          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08204       } else
08205 #endif /* IAXTESTS */
08206          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08207    } else {
08208       /* A mini frame */
08209       f.frametype = AST_FRAME_VOICE;
08210       if (iaxs[fr->callno]->voiceformat > 0)
08211          f.subclass = iaxs[fr->callno]->voiceformat;
08212       else {
08213          if (option_debug)
08214             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08215          iax2_vnak(fr->callno);
08216          ast_mutex_unlock(&iaxsl[fr->callno]);
08217          return 1;
08218       }
08219       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08220       if (f.datalen < 0) {
08221          ast_log(LOG_WARNING, "Datalen < 0?\n");
08222          ast_mutex_unlock(&iaxsl[fr->callno]);
08223          return 1;
08224       }
08225       if (f.datalen)
08226          f.data = thread->buf + sizeof(*mh);
08227       else
08228          f.data = NULL;
08229 #ifdef IAXTESTS
08230       if (test_resync) {
08231          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08232       } else
08233 #endif /* IAXTESTS */
08234       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08235       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08236    }
08237    /* Don't pass any packets until we're started */
08238    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08239       ast_mutex_unlock(&iaxsl[fr->callno]);
08240       return 1;
08241    }
08242    /* Common things */
08243    f.src = "IAX2";
08244    f.mallocd = 0;
08245    f.offset = 0;
08246    f.len = 0;
08247    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08248       f.samples = ast_codec_get_samples(&f);
08249       /* We need to byteswap incoming slinear samples from network byte order */
08250       if (f.subclass == AST_FORMAT_SLINEAR)
08251          ast_frame_byteswap_be(&f);
08252    } else
08253       f.samples = 0;
08254    iax_frame_wrap(fr, &f);
08255 
08256    /* If this is our most recent packet, use it as our basis for timestamping */
08257    if (iaxs[fr->callno]->last < fr->ts) {
08258       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08259       fr->outoforder = 0;
08260    } else {
08261       if (option_debug && iaxdebug)
08262          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);
08263       fr->outoforder = -1;
08264    }
08265    duped_fr = iaxfrdup2(fr);
08266    if (duped_fr) {
08267       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08268    }
08269    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08270       iaxs[fr->callno]->last = fr->ts;
08271 #if 1
08272       if (option_debug && iaxdebug)
08273          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08274 #endif
08275    }
08276 
08277    /* Always run again */
08278    ast_mutex_unlock(&iaxsl[fr->callno]);
08279    return 1;
08280 }
08281 
08282 /* Function to clean up process thread if it is cancelled */
08283 static void iax2_process_thread_cleanup(void *data)
08284 {
08285    struct iax2_thread *thread = data;
08286    ast_mutex_destroy(&thread->lock);
08287    ast_cond_destroy(&thread->cond);
08288    free(thread);
08289    ast_atomic_dec_and_test(&iaxactivethreadcount);
08290 }
08291 
08292 static void *iax2_process_thread(void *data)
08293 {
08294    struct iax2_thread *thread = data;
08295    struct timeval tv;
08296    struct timespec ts;
08297    int put_into_idle = 0;
08298 
08299    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08300    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08301    for(;;) {
08302       /* Wait for something to signal us to be awake */
08303       ast_mutex_lock(&thread->lock);
08304 
08305       /* Flag that we're ready to accept signals */
08306       thread->ready_for_signal = 1;
08307       
08308       /* Put into idle list if applicable */
08309       if (put_into_idle)
08310          insert_idle_thread(thread);
08311 
08312       if (thread->type == IAX_TYPE_DYNAMIC) {
08313          struct iax2_thread *t = NULL;
08314          /* Wait to be signalled or time out */
08315          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08316          ts.tv_sec = tv.tv_sec;
08317          ts.tv_nsec = tv.tv_usec * 1000;
08318          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08319             /* This thread was never put back into the available dynamic
08320              * thread list, so just go away. */
08321             if (!put_into_idle) {
08322                ast_mutex_unlock(&thread->lock);
08323                break;
08324             }
08325             AST_LIST_LOCK(&dynamic_list);
08326             /* Account for the case where this thread is acquired *right* after a timeout */
08327             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08328                iaxdynamicthreadcount--;
08329             AST_LIST_UNLOCK(&dynamic_list);
08330             if (t) {
08331                /* This dynamic thread timed out waiting for a task and was
08332                 * not acquired immediately after the timeout, 
08333                 * so it's time to go away. */
08334                ast_mutex_unlock(&thread->lock);
08335                break;
08336             }
08337             /* Someone grabbed our thread *right* after we timed out.
08338              * Wait for them to set us up with something to do and signal
08339              * us to continue. */
08340             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08341             ts.tv_sec = tv.tv_sec;
08342             ts.tv_nsec = tv.tv_usec * 1000;
08343             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08344             {
08345                ast_mutex_unlock(&thread->lock);
08346                break;
08347             }
08348          }
08349       } else {
08350          ast_cond_wait(&thread->cond, &thread->lock);
08351       }
08352 
08353       /* Go back into our respective list */
08354       put_into_idle = 1;
08355 
08356       ast_mutex_unlock(&thread->lock);
08357 
08358       if (thread->iostate == IAX_IOSTATE_IDLE)
08359          continue;
08360 
08361       /* Add ourselves to the active list now */
08362       AST_LIST_LOCK(&active_list);
08363       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08364       AST_LIST_UNLOCK(&active_list);
08365 
08366       /* See what we need to do */
08367       switch(thread->iostate) {
08368       case IAX_IOSTATE_READY:
08369          thread->actions++;
08370          thread->iostate = IAX_IOSTATE_PROCESSING;
08371          socket_process(thread);
08372          handle_deferred_full_frames(thread);
08373          break;
08374       case IAX_IOSTATE_SCHEDREADY:
08375          thread->actions++;
08376          thread->iostate = IAX_IOSTATE_PROCESSING;
08377 #ifdef SCHED_MULTITHREADED
08378          thread->schedfunc(thread->scheddata);
08379 #endif      
08380          break;
08381       }
08382       time(&thread->checktime);
08383       thread->iostate = IAX_IOSTATE_IDLE;
08384 #ifdef DEBUG_SCHED_MULTITHREAD
08385       thread->curfunc[0]='\0';
08386 #endif      
08387 
08388       /* Now... remove ourselves from the active list, and return to the idle list */
08389       AST_LIST_LOCK(&active_list);
08390       AST_LIST_REMOVE(&active_list, thread, list);
08391       AST_LIST_UNLOCK(&active_list);
08392 
08393       /* Make sure another frame didn't sneak in there after we thought we were done. */
08394       handle_deferred_full_frames(thread);
08395    }
08396 
08397    /*!\note For some reason, idle threads are exiting without being removed
08398     * from an idle list, which is causing memory corruption.  Forcibly remove
08399     * it from the list, if it's there.
08400     */
08401    AST_LIST_LOCK(&idle_list);
08402    AST_LIST_REMOVE(&idle_list, thread, list);
08403    AST_LIST_UNLOCK(&idle_list);
08404 
08405    AST_LIST_LOCK(&dynamic_list);
08406    AST_LIST_REMOVE(&dynamic_list, thread, list);
08407    AST_LIST_UNLOCK(&dynamic_list);
08408 
08409    /* I am exiting here on my own volition, I need to clean up my own data structures
08410    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08411    */
08412    pthread_cleanup_pop(1);
08413 
08414    return NULL;
08415 }
08416 
08417 static int iax2_do_register(struct iax2_registry *reg)
08418 {
08419    struct iax_ie_data ied;
08420    if (option_debug && iaxdebug)
08421       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08422 
08423    if (reg->dnsmgr && 
08424        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08425       /* Maybe the IP has changed, force DNS refresh */
08426       ast_dnsmgr_refresh(reg->dnsmgr);
08427    }
08428    
08429    /*
08430     * if IP has Changed, free allocated call to create a new one with new IP
08431     * call has the pointer to IP and must be updated to the new one
08432     */
08433    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08434       ast_mutex_lock(&iaxsl[reg->callno]);
08435       iax2_destroy(reg->callno);
08436       ast_mutex_unlock(&iaxsl[reg->callno]);
08437       reg->callno = 0;
08438    }
08439    if (!reg->addr.sin_addr.s_addr) {
08440       if (option_debug && iaxdebug)
08441          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08442       /* Setup the next registration attempt */
08443       if (reg->expire > -1)
08444          ast_sched_del(sched, reg->expire);
08445       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08446       return -1;
08447    }
08448 
08449    if (!reg->callno) {
08450       if (option_debug)
08451          ast_log(LOG_DEBUG, "Allocate call number\n");
08452       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, defaultsockfd);
08453       if (reg->callno < 1) {
08454          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08455          return -1;
08456       } else if (option_debug)
08457          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08458       iaxs[reg->callno]->reg = reg;
08459    }
08460    /* Schedule the next registration attempt */
08461    if (reg->expire > -1)
08462       ast_sched_del(sched, reg->expire);
08463    /* Setup the next registration a little early */
08464    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08465    /* Send the request */
08466    memset(&ied, 0, sizeof(ied));
08467    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08468    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08469    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08470    reg->regstate = REG_STATE_REGSENT;
08471    return 0;
08472 }
08473 
08474 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08475 {
08476    if (pos != 3)
08477       return NULL;
08478    return iax_prov_complete_template(line, word, pos, state);
08479 }
08480 
08481 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08482 {
08483    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08484       is found for template */
08485    struct iax_ie_data provdata;
08486    struct iax_ie_data ied;
08487    unsigned int sig;
08488    struct sockaddr_in sin;
08489    int callno;
08490    struct create_addr_info cai;
08491 
08492    memset(&cai, 0, sizeof(cai));
08493 
08494    if (option_debug)
08495       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08496 
08497    if (iax_provision_build(&provdata, &sig, template, force)) {
08498       if (option_debug)
08499          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08500       return 0;
08501    }
08502 
08503    if (end) {
08504       memcpy(&sin, end, sizeof(sin));
08505       cai.sockfd = sockfd;
08506    } else if (create_addr(dest, &sin, &cai))
08507       return -1;
08508 
08509    /* Build the rest of the message */
08510    memset(&ied, 0, sizeof(ied));
08511    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08512 
08513    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08514    if (!callno)
08515       return -1;
08516 
08517    ast_mutex_lock(&iaxsl[callno]);
08518    if (iaxs[callno]) {
08519       /* Schedule autodestruct in case they don't ever give us anything back */
08520       if (iaxs[callno]->autoid > -1)
08521          ast_sched_del(sched, iaxs[callno]->autoid);
08522       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08523       ast_set_flag(iaxs[callno], IAX_PROVISION);
08524       /* Got a call number now, so go ahead and send the provisioning information */
08525       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08526    }
08527    ast_mutex_unlock(&iaxsl[callno]);
08528 
08529    return 1;
08530 }
08531 
08532 static char *papp = "IAX2Provision";
08533 static char *psyn = "Provision a calling IAXy with a given template";
08534 static char *pdescrip = 
08535 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08536 "the calling entity is in fact an IAXy) with the given template or\n"
08537 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08538 
08539 /*! iax2provision
08540 \ingroup applications
08541 */
08542 static int iax2_prov_app(struct ast_channel *chan, void *data)
08543 {
08544    int res;
08545    char *sdata;
08546    char *opts;
08547    int force =0;
08548    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08549    if (ast_strlen_zero(data))
08550       data = "default";
08551    sdata = ast_strdupa(data);
08552    opts = strchr(sdata, '|');
08553    if (opts)
08554       *opts='\0';
08555 
08556    if (chan->tech != &iax2_tech) {
08557       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08558       return -1;
08559    } 
08560    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08561       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08562       return -1;
08563    }
08564    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08565    if (option_verbose > 2)
08566       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08567       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08568       sdata, res);
08569    return res;
08570 }
08571 
08572 
08573 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08574 {
08575    int force = 0;
08576    int res;
08577    if (argc < 4)
08578       return RESULT_SHOWUSAGE;
08579    if ((argc > 4)) {
08580       if (!strcasecmp(argv[4], "forced"))
08581          force = 1;
08582       else
08583          return RESULT_SHOWUSAGE;
08584    }
08585    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08586    if (res < 0)
08587       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08588    else if (res < 1)
08589       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08590    else
08591       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08592    return RESULT_SUCCESS;
08593 }
08594 
08595 static void __iax2_poke_noanswer(const void *data)
08596 {
08597    struct iax2_peer *peer = (struct iax2_peer *)data;
08598    if (peer->lastms > -1) {
08599       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08600       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08601       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08602    }
08603    if (peer->callno > 0) {
08604       ast_mutex_lock(&iaxsl[peer->callno]);
08605       iax2_destroy(peer->callno);
08606       ast_mutex_unlock(&iaxsl[peer->callno]);
08607    }
08608    peer->callno = 0;
08609    peer->lastms = -1;
08610    /* Try again quickly */
08611    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08612    if (peer->pokeexpire == -1)
08613       peer_unref(peer);
08614 }
08615 
08616 static int iax2_poke_noanswer(const void *data)
08617 {
08618    struct iax2_peer *peer = (struct iax2_peer *)data;
08619    peer->pokeexpire = -1;
08620 #ifdef SCHED_MULTITHREADED
08621    if (schedule_action(__iax2_poke_noanswer, data))
08622 #endif      
08623       __iax2_poke_noanswer(data);
08624    peer_unref(peer);
08625    return 0;
08626 }
08627 
08628 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08629 {
08630    struct iax2_peer *peer = obj;
08631 
08632    iax2_poke_peer(peer, 0);
08633 
08634    return 0;
08635 }
08636 
08637 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08638 {
08639    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08640       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08641         immediately after clearing things out */
08642       peer->lastms = 0;
08643       peer->historicms = 0;
08644       peer->pokeexpire = -1;
08645       peer->callno = 0;
08646       return 0;
08647    }
08648    if (peer->callno > 0) {
08649       ast_log(LOG_NOTICE, "Still have a callno...\n");
08650       ast_mutex_lock(&iaxsl[peer->callno]);
08651       iax2_destroy(peer->callno);
08652       ast_mutex_unlock(&iaxsl[peer->callno]);
08653    }
08654    if (heldcall)
08655       ast_mutex_unlock(&iaxsl[heldcall]);
08656    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd);
08657    if (heldcall)
08658       ast_mutex_lock(&iaxsl[heldcall]);
08659    if (peer->callno < 1) {
08660       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08661       return -1;
08662    }
08663 
08664    /* Speed up retransmission times for this qualify call */
08665    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08666    iaxs[peer->callno]->peerpoke = peer;
08667    
08668    /* Remove any pending pokeexpire task */
08669    if (peer->pokeexpire > -1) {
08670       if (!ast_sched_del(sched, peer->pokeexpire)) {
08671          peer->pokeexpire = -1;
08672          peer_unref(peer);
08673       }
08674    }
08675 
08676    /* Queue up a new task to handle no reply */
08677    /* If the host is already unreachable then use the unreachable interval instead */
08678    if (peer->lastms < 0) {
08679       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08680    } else
08681       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08682 
08683    if (peer->pokeexpire == -1)
08684       peer_unref(peer);
08685 
08686    /* And send the poke */
08687    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08688 
08689    return 0;
08690 }
08691 
08692 static void free_context(struct iax2_context *con)
08693 {
08694    struct iax2_context *conl;
08695    while(con) {
08696       conl = con;
08697       con = con->next;
08698       free(conl);
08699    }
08700 }
08701 
08702 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08703 {
08704    int callno;
08705    int res;
08706    int fmt, native;
08707    struct sockaddr_in sin;
08708    struct ast_channel *c;
08709    struct parsed_dial_string pds;
08710    struct create_addr_info cai;
08711    char *tmpstr;
08712 
08713    memset(&pds, 0, sizeof(pds));
08714    tmpstr = ast_strdupa(data);
08715    parse_dial_string(tmpstr, &pds);
08716 
08717    memset(&cai, 0, sizeof(cai));
08718    cai.capability = iax2_capability;
08719 
08720    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08721 
08722    if (!pds.peer) {
08723       ast_log(LOG_WARNING, "No peer given\n");
08724       return NULL;
08725    }
08726           
08727    
08728    /* Populate our address from the given */
08729    if (create_addr(pds.peer, &sin, &cai)) {
08730       *cause = AST_CAUSE_UNREGISTERED;
08731       return NULL;
08732    }
08733 
08734    if (pds.port)
08735       sin.sin_port = htons(atoi(pds.port));
08736 
08737    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08738    if (callno < 1) {
08739       ast_log(LOG_WARNING, "Unable to create call\n");
08740       *cause = AST_CAUSE_CONGESTION;
08741       return NULL;
08742    }
08743 
08744    ast_mutex_lock(&iaxsl[callno]);
08745 
08746    /* If this is a trunk, update it now */
08747    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08748    if (ast_test_flag(&cai, IAX_TRUNK)) {
08749       int new_callno;
08750       if ((new_callno = make_trunk(callno, 1)) != -1)
08751          callno = new_callno;
08752    }
08753    iaxs[callno]->maxtime = cai.maxtime;
08754    if (cai.found)
08755       ast_string_field_set(iaxs[callno], host, pds.peer);
08756 
08757    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08758 
08759    ast_mutex_unlock(&iaxsl[callno]);
08760 
08761    if (c) {
08762       /* Choose a format we can live with */
08763       if (c->nativeformats & format) 
08764          c->nativeformats &= format;
08765       else {
08766          native = c->nativeformats;
08767          fmt = format;
08768          res = ast_translator_best_choice(&fmt, &native);
08769          if (res < 0) {
08770             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08771                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08772             ast_hangup(c);
08773             return NULL;
08774          }
08775          c->nativeformats = native;
08776       }
08777       c->readformat = ast_best_codec(c->nativeformats);
08778       c->writeformat = c->readformat;
08779    }
08780 
08781    return c;
08782 }
08783 
08784 static void *sched_thread(void *ignore)
08785 {
08786    int count;
08787    int res;
08788    struct timeval tv;
08789    struct timespec ts;
08790 
08791    for (;;) {
08792       res = ast_sched_wait(sched);
08793       if ((res > 1000) || (res < 0))
08794          res = 1000;
08795       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08796       ts.tv_sec = tv.tv_sec;
08797       ts.tv_nsec = tv.tv_usec * 1000;
08798 
08799       pthread_testcancel();
08800       ast_mutex_lock(&sched_lock);
08801       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08802       ast_mutex_unlock(&sched_lock);
08803       pthread_testcancel();
08804 
08805       count = ast_sched_runq(sched);
08806       if (option_debug && count >= 20)
08807          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08808    }
08809    return NULL;
08810 }
08811 
08812 static void *network_thread(void *ignore)
08813 {
08814    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08815       from the network, and queue them for delivery to the channels */
08816    int res, count, wakeup;
08817    struct iax_frame *f;
08818 
08819    if (timingfd > -1)
08820       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08821    
08822    for(;;) {
08823       pthread_testcancel();
08824 
08825       /* Go through the queue, sending messages which have not yet been
08826          sent, and scheduling retransmissions if appropriate */
08827       AST_LIST_LOCK(&iaxq.queue);
08828       count = 0;
08829       wakeup = -1;
08830       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08831          if (f->sentyet)
08832             continue;
08833          
08834          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
08835          if (ast_mutex_trylock(&iaxsl[f->callno])) {
08836             wakeup = 1;
08837             continue;
08838          }
08839 
08840          f->sentyet++;
08841 
08842          if (iaxs[f->callno]) {
08843             send_packet(f);
08844             count++;
08845          } 
08846 
08847          ast_mutex_unlock(&iaxsl[f->callno]);
08848 
08849          if (f->retries < 0) {
08850             /* This is not supposed to be retransmitted */
08851             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
08852             iaxq.count--;
08853             /* Free the iax frame */
08854             iax_frame_free(f);
08855          } else {
08856             /* We need reliable delivery.  Schedule a retransmission */
08857             f->retries++;
08858             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
08859          }
08860       }
08861       AST_LIST_TRAVERSE_SAFE_END
08862       AST_LIST_UNLOCK(&iaxq.queue);
08863 
08864       pthread_testcancel();
08865 
08866       if (option_debug && count >= 20)
08867          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08868 
08869       /* Now do the IO, and run scheduled tasks */
08870       res = ast_io_wait(io, wakeup);
08871       if (res >= 0) {
08872          if (option_debug && res >= 20)
08873             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08874       }
08875    }
08876    return NULL;
08877 }
08878 
08879 static int start_network_thread(void)
08880 {
08881    pthread_attr_t attr;
08882    int threadcount = 0;
08883    int x;
08884    for (x = 0; x < iaxthreadcount; x++) {
08885       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08886       if (thread) {
08887          thread->type = IAX_TYPE_POOL;
08888          thread->threadnum = ++threadcount;
08889          ast_mutex_init(&thread->lock);
08890          ast_cond_init(&thread->cond, NULL);
08891          pthread_attr_init(&attr);
08892          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08893          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08894             ast_log(LOG_WARNING, "Failed to create new thread!\n");
08895             free(thread);
08896             thread = NULL;
08897          }
08898          AST_LIST_LOCK(&idle_list);
08899          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08900          AST_LIST_UNLOCK(&idle_list);
08901       }
08902    }
08903    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08904    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08905    if (option_verbose > 1)
08906       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08907    return 0;
08908 }
08909 
08910 static struct iax2_context *build_context(char *context)
08911 {
08912    struct iax2_context *con;
08913 
08914    if ((con = ast_calloc(1, sizeof(*con))))
08915       ast_copy_string(con->context, context, sizeof(con->context));
08916    
08917    return con;
08918 }
08919 
08920 static int get_auth_methods(char *value)
08921 {
08922    int methods = 0;
08923    if (strstr(value, "rsa"))
08924       methods |= IAX_AUTH_RSA;
08925    if (strstr(value, "md5"))
08926       methods |= IAX_AUTH_MD5;
08927    if (strstr(value, "plaintext"))
08928       methods |= IAX_AUTH_PLAINTEXT;
08929    return methods;
08930 }
08931 
08932 
08933 /*! \brief Check if address can be used as packet source.
08934  \return 0  address available, 1  address unavailable, -1  error
08935 */
08936 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08937 {
08938    int sd;
08939    int res;
08940    
08941    sd = socket(AF_INET, SOCK_DGRAM, 0);
08942    if (sd < 0) {
08943       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08944       return -1;
08945    }
08946 
08947    res = bind(sd, sa, salen);
08948    if (res < 0) {
08949       if (option_debug)
08950          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08951       close(sd);
08952       return 1;
08953    }
08954 
08955    close(sd);
08956    return 0;
08957 }
08958 
08959 /*! \brief Parse the "sourceaddress" value,
08960   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08961   not found. */
08962 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08963 {
08964    struct sockaddr_in sin;
08965    int nonlocal = 1;
08966    int port = IAX_DEFAULT_PORTNO;
08967    int sockfd = defaultsockfd;
08968    char *tmp;
08969    char *addr;
08970    char *portstr;
08971 
08972    if (!(tmp = ast_strdupa(srcaddr)))
08973       return -1;
08974 
08975    addr = strsep(&tmp, ":");
08976    portstr = tmp;
08977 
08978    if (portstr) {
08979       port = atoi(portstr);
08980       if (port < 1)
08981          port = IAX_DEFAULT_PORTNO;
08982    }
08983    
08984    if (!ast_get_ip(&sin, addr)) {
08985       struct ast_netsock *sock;
08986       int res;
08987 
08988       sin.sin_port = 0;
08989       sin.sin_family = AF_INET;
08990       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08991       if (res == 0) {
08992          /* ip address valid. */
08993          sin.sin_port = htons(port);
08994          if (!(sock = ast_netsock_find(netsock, &sin)))
08995             sock = ast_netsock_find(outsock, &sin);
08996          if (sock) {
08997             sockfd = ast_netsock_sockfd(sock);
08998             nonlocal = 0;
08999          } else {
09000             unsigned int orig_saddr = sin.sin_addr.s_addr;
09001             /* INADDR_ANY matches anyway! */
09002             sin.sin_addr.s_addr = INADDR_ANY;
09003             if (ast_netsock_find(netsock, &sin)) {
09004                sin.sin_addr.s_addr = orig_saddr;
09005                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09006                if (sock) {
09007                   sockfd = ast_netsock_sockfd(sock);
09008                   ast_netsock_unref(sock);
09009                   nonlocal = 0;
09010                } else {
09011                   nonlocal = 2;
09012                }
09013             }
09014          }
09015       }
09016    }
09017       
09018    peer->sockfd = sockfd;
09019 
09020    if (nonlocal == 1) {
09021       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09022          srcaddr, peer->name);
09023       return -1;
09024         } else if (nonlocal == 2) {
09025       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09026          srcaddr, peer->name);
09027          return -1;
09028    } else {
09029       if (option_debug)
09030          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09031       return 0;
09032    }
09033 }
09034 
09035 static void peer_destructor(void *obj)
09036 {
09037    struct iax2_peer *peer = obj;
09038 
09039    ast_free_ha(peer->ha);
09040 
09041    if (peer->callno > 0) {
09042       ast_mutex_lock(&iaxsl[peer->callno]);
09043       iax2_destroy(peer->callno);
09044       ast_mutex_unlock(&iaxsl[peer->callno]);
09045    }
09046 
09047    register_peer_exten(peer, 0);
09048 
09049    if (peer->dnsmgr)
09050       ast_dnsmgr_release(peer->dnsmgr);
09051 
09052    ast_string_field_free_memory(peer);
09053 }
09054 
09055 /*! \brief Create peer structure based on configuration */
09056 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09057 {
09058    struct iax2_peer *peer = NULL;
09059    struct ast_ha *oldha = NULL;
09060    int maskfound=0;
09061    int found=0;
09062    int firstpass=1;
09063    struct iax2_peer tmp_peer = {
09064       .name = name,
09065    };
09066 
09067    if (!temponly) {
09068       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09069       if (peer && !ast_test_flag(peer, IAX_DELME))
09070          firstpass = 0;
09071    }
09072 
09073    if (peer) {
09074       found++;
09075       if (firstpass) {
09076          oldha = peer->ha;
09077          peer->ha = NULL;
09078       }
09079       unlink_peer(peer);
09080    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09081       peer->expire = -1;
09082       peer->pokeexpire = -1;
09083       peer->sockfd = defaultsockfd;
09084       if (ast_string_field_init(peer, 32))
09085          peer = peer_unref(peer);
09086    }
09087 
09088    if (peer) {
09089       if (firstpass) {
09090          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09091          peer->encmethods = iax2_encryption;
09092          peer->adsi = adsi;
09093          ast_string_field_set(peer,secret,"");
09094          if (!found) {
09095             ast_string_field_set(peer, name, name);
09096             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09097             peer->expiry = min_reg_expire;
09098          }
09099          peer->prefs = prefs;
09100          peer->capability = iax2_capability;
09101          peer->smoothing = 0;
09102          peer->pokefreqok = DEFAULT_FREQ_OK;
09103          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09104          ast_string_field_set(peer,context,"");
09105          ast_string_field_set(peer,peercontext,"");
09106          ast_clear_flag(peer, IAX_HASCALLERID);
09107          ast_string_field_set(peer, cid_name, "");
09108          ast_string_field_set(peer, cid_num, "");
09109       }
09110 
09111       if (!v) {
09112          v = alt;
09113          alt = NULL;
09114       }
09115       while(v) {
09116          if (!strcasecmp(v->name, "secret")) {
09117             ast_string_field_set(peer, secret, v->value);
09118          } else if (!strcasecmp(v->name, "mailbox")) {
09119             ast_string_field_set(peer, mailbox, v->value);
09120          } else if (!strcasecmp(v->name, "mohinterpret")) {
09121             ast_string_field_set(peer, mohinterpret, v->value);
09122          } else if (!strcasecmp(v->name, "mohsuggest")) {
09123             ast_string_field_set(peer, mohsuggest, v->value);
09124          } else if (!strcasecmp(v->name, "dbsecret")) {
09125             ast_string_field_set(peer, dbsecret, v->value);
09126          } else if (!strcasecmp(v->name, "trunk")) {
09127             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09128             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09129                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09130                ast_clear_flag(peer, IAX_TRUNK);
09131             }
09132          } else if (!strcasecmp(v->name, "auth")) {
09133             peer->authmethods = get_auth_methods(v->value);
09134          } else if (!strcasecmp(v->name, "encryption")) {
09135             peer->encmethods = get_encrypt_methods(v->value);
09136          } else if (!strcasecmp(v->name, "notransfer")) {
09137             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09138             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09139             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09140          } else if (!strcasecmp(v->name, "transfer")) {
09141             if (!strcasecmp(v->value, "mediaonly")) {
09142                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09143             } else if (ast_true(v->value)) {
09144                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09145             } else 
09146                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09147          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09148             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09149          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09150             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09151          } else if (!strcasecmp(v->name, "host")) {
09152             if (!strcasecmp(v->value, "dynamic")) {
09153                /* They'll register with us */
09154                ast_set_flag(peer, IAX_DYNAMIC); 
09155                if (!found) {
09156                   /* Initialize stuff iff we're not found, otherwise
09157                      we keep going with what we had */
09158                   memset(&peer->addr.sin_addr, 0, 4);
09159                   if (peer->addr.sin_port) {
09160                      /* If we've already got a port, make it the default rather than absolute */
09161                      peer->defaddr.sin_port = peer->addr.sin_port;
09162                      peer->addr.sin_port = 0;
09163                   }
09164                }
09165             } else {
09166                /* Non-dynamic.  Make sure we become that way if we're not */
09167                if (peer->expire > -1)
09168                   ast_sched_del(sched, peer->expire);
09169                peer->expire = -1;
09170                ast_clear_flag(peer, IAX_DYNAMIC);
09171                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09172                   return peer_unref(peer);
09173                if (!peer->addr.sin_port)
09174                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09175             }
09176             if (!maskfound)
09177                inet_aton("255.255.255.255", &peer->mask);
09178          } else if (!strcasecmp(v->name, "defaultip")) {
09179             if (ast_get_ip(&peer->defaddr, v->value))
09180                return peer_unref(peer);
09181          } else if (!strcasecmp(v->name, "sourceaddress")) {
09182             peer_set_srcaddr(peer, v->value);
09183          } else if (!strcasecmp(v->name, "permit") ||
09184                   !strcasecmp(v->name, "deny")) {
09185             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09186          } else if (!strcasecmp(v->name, "mask")) {
09187             maskfound++;
09188             inet_aton(v->value, &peer->mask);
09189          } else if (!strcasecmp(v->name, "context")) {
09190             ast_string_field_set(peer, context, v->value);
09191          } else if (!strcasecmp(v->name, "regexten")) {
09192             ast_string_field_set(peer, regexten, v->value);
09193          } else if (!strcasecmp(v->name, "peercontext")) {
09194             ast_string_field_set(peer, peercontext, v->value);
09195          } else if (!strcasecmp(v->name, "port")) {
09196             if (ast_test_flag(peer, IAX_DYNAMIC))
09197                peer->defaddr.sin_port = htons(atoi(v->value));
09198             else
09199                peer->addr.sin_port = htons(atoi(v->value));
09200          } else if (!strcasecmp(v->name, "username")) {
09201             ast_string_field_set(peer, username, v->value);
09202          } else if (!strcasecmp(v->name, "allow")) {
09203             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09204          } else if (!strcasecmp(v->name, "disallow")) {
09205             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09206          } else if (!strcasecmp(v->name, "callerid")) {
09207             if (!ast_strlen_zero(v->value)) {
09208                char name2[80];
09209                char num2[80];
09210                ast_callerid_split(v->value, name2, 80, num2, 80);
09211                ast_string_field_set(peer, cid_name, name2);
09212                ast_string_field_set(peer, cid_num, num2);
09213                ast_set_flag(peer, IAX_HASCALLERID);
09214             } else {
09215                ast_clear_flag(peer, IAX_HASCALLERID);
09216                ast_string_field_set(peer, cid_name, "");
09217                ast_string_field_set(peer, cid_num, "");
09218             }
09219          } else if (!strcasecmp(v->name, "fullname")) {
09220             if (!ast_strlen_zero(v->value)) {
09221                ast_string_field_set(peer, cid_name, v->value);
09222                ast_set_flag(peer, IAX_HASCALLERID);
09223             } else {
09224                ast_string_field_set(peer, cid_name, "");
09225                if (ast_strlen_zero(peer->cid_num))
09226                   ast_clear_flag(peer, IAX_HASCALLERID);
09227             }
09228          } else if (!strcasecmp(v->name, "cid_number")) {
09229             if (!ast_strlen_zero(v->value)) {
09230                ast_string_field_set(peer, cid_num, v->value);
09231                ast_set_flag(peer, IAX_HASCALLERID);
09232             } else {
09233                ast_string_field_set(peer, cid_num, "");
09234                if (ast_strlen_zero(peer->cid_name))
09235                   ast_clear_flag(peer, IAX_HASCALLERID);
09236             }
09237          } else if (!strcasecmp(v->name, "sendani")) {
09238             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09239          } else if (!strcasecmp(v->name, "inkeys")) {
09240             ast_string_field_set(peer, inkeys, v->value);
09241          } else if (!strcasecmp(v->name, "outkey")) {
09242             ast_string_field_set(peer, outkey, v->value);
09243          } else if (!strcasecmp(v->name, "qualify")) {
09244             if (!strcasecmp(v->value, "no")) {
09245                peer->maxms = 0;
09246             } else if (!strcasecmp(v->value, "yes")) {
09247                peer->maxms = DEFAULT_MAXMS;
09248             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09249                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);
09250                peer->maxms = 0;
09251             }
09252          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09253             peer->smoothing = ast_true(v->value);
09254          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09255             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09256                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);
09257             }
09258          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09259             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09260                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);
09261             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09262          } else if (!strcasecmp(v->name, "timezone")) {
09263             ast_string_field_set(peer, zonetag, v->value);
09264          } else if (!strcasecmp(v->name, "adsi")) {
09265             peer->adsi = ast_true(v->value);
09266          }/* else if (strcasecmp(v->name,"type")) */
09267          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09268          v = v->next;
09269          if (!v) {
09270             v = alt;
09271             alt = NULL;
09272          }
09273       }
09274       if (!peer->authmethods)
09275          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09276       ast_clear_flag(peer, IAX_DELME); 
09277       /* Make sure these are IPv4 addresses */
09278       peer->addr.sin_family = AF_INET;
09279    }
09280    if (oldha)
09281       ast_free_ha(oldha);
09282    return peer;
09283 }
09284 
09285 static void user_destructor(void *obj)
09286 {
09287    struct iax2_user *user = obj;
09288 
09289    ast_free_ha(user->ha);
09290    free_context(user->contexts);
09291    if(user->vars) {
09292       ast_variables_destroy(user->vars);
09293       user->vars = NULL;
09294    }
09295    ast_string_field_free_memory(user);
09296 }
09297 
09298 /*! \brief Create in-memory user structure from configuration */
09299 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09300 {
09301    struct iax2_user *user = NULL;
09302    struct iax2_context *con, *conl = NULL;
09303    struct ast_ha *oldha = NULL;
09304    struct iax2_context *oldcon = NULL;
09305    int format;
09306    int firstpass=1;
09307    int oldcurauthreq = 0;
09308    char *varname = NULL, *varval = NULL;
09309    struct ast_variable *tmpvar = NULL;
09310    struct iax2_user tmp_user = {
09311       .name = name,
09312    };
09313 
09314    if (!temponly) {
09315       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09316       if (user && !ast_test_flag(user, IAX_DELME))
09317          firstpass = 0;
09318    }
09319 
09320    if (user) {
09321       if (firstpass) {
09322          oldcurauthreq = user->curauthreq;
09323          oldha = user->ha;
09324          oldcon = user->contexts;
09325          user->ha = NULL;
09326          user->contexts = NULL;
09327       }
09328       /* Already in the list, remove it and it will be added back (or FREE'd) */
09329       ao2_unlink(users, user);
09330    } else {
09331       user = ao2_alloc(sizeof(*user), user_destructor);
09332    }
09333    
09334    if (user) {
09335       if (firstpass) {
09336          ast_string_field_free_memory(user);
09337          memset(user, 0, sizeof(struct iax2_user));
09338          if (ast_string_field_init(user, 32)) {
09339             user = user_unref(user);
09340             goto cleanup;
09341          }
09342          user->maxauthreq = maxauthreq;
09343          user->curauthreq = oldcurauthreq;
09344          user->prefs = prefs;
09345          user->capability = iax2_capability;
09346          user->encmethods = iax2_encryption;
09347          user->adsi = adsi;
09348          ast_string_field_set(user, name, name);
09349          ast_string_field_set(user, language, language);
09350          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09351          ast_clear_flag(user, IAX_HASCALLERID);
09352          ast_string_field_set(user, cid_name, "");
09353          ast_string_field_set(user, cid_num, "");
09354       }
09355       if (!v) {
09356          v = alt;
09357          alt = NULL;
09358       }
09359       while(v) {
09360          if (!strcasecmp(v->name, "context")) {
09361             con = build_context(v->value);
09362             if (con) {
09363                if (conl)
09364                   conl->next = con;
09365                else
09366                   user->contexts = con;
09367                conl = con;
09368             }
09369          } else if (!strcasecmp(v->name, "permit") ||
09370                   !strcasecmp(v->name, "deny")) {
09371             user->ha = ast_append_ha(v->name, v->value, user->ha);
09372          } else if (!strcasecmp(v->name, "setvar")) {
09373             varname = ast_strdupa(v->value);
09374             if (varname && (varval = strchr(varname,'='))) {
09375                *varval = '\0';
09376                varval++;
09377                if((tmpvar = ast_variable_new(varname, varval))) {
09378                   tmpvar->next = user->vars; 
09379                   user->vars = tmpvar;
09380                }
09381             }
09382          } else if (!strcasecmp(v->name, "allow")) {
09383             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09384          } else if (!strcasecmp(v->name, "disallow")) {
09385             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09386          } else if (!strcasecmp(v->name, "trunk")) {
09387             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09388             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09389                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09390                ast_clear_flag(user, IAX_TRUNK);
09391             }
09392          } else if (!strcasecmp(v->name, "auth")) {
09393             user->authmethods = get_auth_methods(v->value);
09394          } else if (!strcasecmp(v->name, "encryption")) {
09395             user->encmethods = get_encrypt_methods(v->value);
09396          } else if (!strcasecmp(v->name, "notransfer")) {
09397             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09398             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09399             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09400          } else if (!strcasecmp(v->name, "transfer")) {
09401             if (!strcasecmp(v->value, "mediaonly")) {
09402                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09403             } else if (ast_true(v->value)) {
09404                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09405             } else 
09406                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09407          } else if (!strcasecmp(v->name, "codecpriority")) {
09408             if(!strcasecmp(v->value, "caller"))
09409                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09410             else if(!strcasecmp(v->value, "disabled"))
09411                ast_set_flag(user, IAX_CODEC_NOPREFS);
09412             else if(!strcasecmp(v->value, "reqonly")) {
09413                ast_set_flag(user, IAX_CODEC_NOCAP);
09414                ast_set_flag(user, IAX_CODEC_NOPREFS);
09415             }
09416          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09417             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09418          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09419             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09420          } else if (!strcasecmp(v->name, "dbsecret")) {
09421             ast_string_field_set(user, dbsecret, v->value);
09422          } else if (!strcasecmp(v->name, "secret")) {
09423             if (!ast_strlen_zero(user->secret)) {
09424                char *old = ast_strdupa(user->secret);
09425 
09426                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09427             } else
09428                ast_string_field_set(user, secret, v->value);
09429          } else if (!strcasecmp(v->name, "callerid")) {
09430             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09431                char name2[80];
09432                char num2[80];
09433                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09434                ast_string_field_set(user, cid_name, name2);
09435                ast_string_field_set(user, cid_num, num2);
09436                ast_set_flag(user, IAX_HASCALLERID);
09437             } else {
09438                ast_clear_flag(user, IAX_HASCALLERID);
09439                ast_string_field_set(user, cid_name, "");
09440                ast_string_field_set(user, cid_num, "");
09441             }
09442          } else if (!strcasecmp(v->name, "fullname")) {
09443             if (!ast_strlen_zero(v->value)) {
09444                ast_string_field_set(user, cid_name, v->value);
09445                ast_set_flag(user, IAX_HASCALLERID);
09446             } else {
09447                ast_string_field_set(user, cid_name, "");
09448                if (ast_strlen_zero(user->cid_num))
09449                   ast_clear_flag(user, IAX_HASCALLERID);
09450             }
09451          } else if (!strcasecmp(v->name, "cid_number")) {
09452             if (!ast_strlen_zero(v->value)) {
09453                ast_string_field_set(user, cid_num, v->value);
09454                ast_set_flag(user, IAX_HASCALLERID);
09455             } else {
09456                ast_string_field_set(user, cid_num, "");
09457                if (ast_strlen_zero(user->cid_name))
09458                   ast_clear_flag(user, IAX_HASCALLERID);
09459             }
09460          } else if (!strcasecmp(v->name, "accountcode")) {
09461             ast_string_field_set(user, accountcode, v->value);
09462          } else if (!strcasecmp(v->name, "mohinterpret")) {
09463             ast_string_field_set(user, mohinterpret, v->value);
09464          } else if (!strcasecmp(v->name, "mohsuggest")) {
09465             ast_string_field_set(user, mohsuggest, v->value);
09466          } else if (!strcasecmp(v->name, "language")) {
09467             ast_string_field_set(user, language, v->value);
09468          } else if (!strcasecmp(v->name, "amaflags")) {
09469             format = ast_cdr_amaflags2int(v->value);
09470             if (format < 0) {
09471                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09472             } else {
09473                user->amaflags = format;
09474             }
09475          } else if (!strcasecmp(v->name, "inkeys")) {
09476             ast_string_field_set(user, inkeys, v->value);
09477          } else if (!strcasecmp(v->name, "maxauthreq")) {
09478             user->maxauthreq = atoi(v->value);
09479             if (user->maxauthreq < 0)
09480                user->maxauthreq = 0;
09481          } else if (!strcasecmp(v->name, "adsi")) {
09482             user->adsi = ast_true(v->value);
09483          }/* else if (strcasecmp(v->name,"type")) */
09484          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09485          v = v->next;
09486          if (!v) {
09487             v = alt;
09488             alt = NULL;
09489          }
09490       }
09491       if (!user->authmethods) {
09492          if (!ast_strlen_zero(user->secret)) {
09493             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09494             if (!ast_strlen_zero(user->inkeys))
09495                user->authmethods |= IAX_AUTH_RSA;
09496          } else if (!ast_strlen_zero(user->inkeys)) {
09497             user->authmethods = IAX_AUTH_RSA;
09498          } else {
09499             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09500          }
09501       }
09502       ast_clear_flag(user, IAX_DELME);
09503    }
09504 cleanup:
09505    if (oldha)
09506       ast_free_ha(oldha);
09507    if (oldcon)
09508       free_context(oldcon);
09509    return user;
09510 }
09511 
09512 static int peer_delme_cb(void *obj, void *arg, int flags)
09513 {
09514    struct iax2_peer *peer = obj;
09515 
09516    ast_set_flag(peer, IAX_DELME);
09517 
09518    return 0;
09519 }
09520 
09521 static int user_delme_cb(void *obj, void *arg, int flags)
09522 {
09523    struct iax2_user *user = obj;
09524 
09525    ast_set_flag(user, IAX_DELME);
09526 
09527    return 0;
09528 }
09529 
09530 static void delete_users(void)
09531 {
09532    struct iax2_registry *reg;
09533 
09534    ao2_callback(users, 0, user_delme_cb, NULL);
09535 
09536    AST_LIST_LOCK(&registrations);
09537    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09538       if (reg->expire > -1)
09539          ast_sched_del(sched, reg->expire);
09540       if (reg->callno) {
09541          ast_mutex_lock(&iaxsl[reg->callno]);
09542          if (iaxs[reg->callno]) {
09543             iaxs[reg->callno]->reg = NULL;
09544             iax2_destroy(reg->callno);
09545          }
09546          ast_mutex_unlock(&iaxsl[reg->callno]);
09547       }
09548       if (reg->dnsmgr)
09549          ast_dnsmgr_release(reg->dnsmgr);
09550       free(reg);
09551    }
09552    AST_LIST_UNLOCK(&registrations);
09553 
09554    ao2_callback(peers, 0, peer_delme_cb, NULL);
09555 }
09556 
09557 static void prune_users(void)
09558 {
09559    struct iax2_user *user;
09560    struct ao2_iterator i;
09561 
09562    i = ao2_iterator_init(users, 0);
09563    while ((user = ao2_iterator_next(&i))) {
09564       if (ast_test_flag(user, IAX_DELME))
09565          ao2_unlink(users, user);
09566       user_unref(user);
09567    }
09568 }
09569 
09570 /* Prune peers who still are supposed to be deleted */
09571 static void prune_peers(void)
09572 {
09573    struct iax2_peer *peer;
09574    struct ao2_iterator i;
09575 
09576    i = ao2_iterator_init(peers, 0);
09577    while ((peer = ao2_iterator_next(&i))) {
09578       if (ast_test_flag(peer, IAX_DELME))
09579          unlink_peer(peer);
09580       peer_unref(peer);
09581    }
09582 }
09583 
09584 static void set_timing(void)
09585 {
09586 #ifdef HAVE_ZAPTEL
09587    int bs = trunkfreq * 8;
09588    if (timingfd > -1) {
09589       if (
09590 #ifdef ZT_TIMERACK
09591          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09592 #endif         
09593          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09594          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09595    }
09596 #endif
09597 }
09598 
09599 static void set_config_destroy(void)
09600 {
09601    strcpy(accountcode, "");
09602    strcpy(language, "");
09603    strcpy(mohinterpret, "default");
09604    strcpy(mohsuggest, "");
09605    amaflags = 0;
09606    delayreject = 0;
09607    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09608    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09609    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09610    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09611    delete_users();
09612 }
09613 
09614 /*! \brief Load configuration */
09615 static int set_config(char *config_file, int reload)
09616 {
09617    struct ast_config *cfg, *ucfg;
09618    int capability=iax2_capability;
09619    struct ast_variable *v;
09620    char *cat;
09621    const char *utype;
09622    const char *tosval;
09623    int format;
09624    int portno = IAX_DEFAULT_PORTNO;
09625    int  x;
09626    struct iax2_user *user;
09627    struct iax2_peer *peer;
09628    struct ast_netsock *ns;
09629 #if 0
09630    static unsigned short int last_port=0;
09631 #endif
09632 
09633    cfg = ast_config_load(config_file);
09634    
09635    if (!cfg) {
09636       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09637       return -1;
09638    }
09639 
09640    if (reload) {
09641       set_config_destroy();
09642    }
09643 
09644    /* Reset global codec prefs */   
09645    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09646    
09647    /* Reset Global Flags */
09648    memset(&globalflags, 0, sizeof(globalflags));
09649    ast_set_flag(&globalflags, IAX_RTUPDATE);
09650 
09651 #ifdef SO_NO_CHECK
09652    nochecksums = 0;
09653 #endif
09654 
09655    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09656    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09657 
09658    maxauthreq = 3;
09659 
09660    v = ast_variable_browse(cfg, "general");
09661 
09662    /* Seed initial tos value */
09663    tosval = ast_variable_retrieve(cfg, "general", "tos");
09664    if (tosval) {
09665       if (ast_str2tos(tosval, &tos))
09666          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09667    }
09668    while(v) {
09669       if (!strcasecmp(v->name, "bindport")){ 
09670          if (reload)
09671             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09672          else
09673             portno = atoi(v->value);
09674       } else if (!strcasecmp(v->name, "pingtime")) 
09675          ping_time = atoi(v->value);
09676       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09677          if (reload) {
09678             if (atoi(v->value) != iaxthreadcount)
09679                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09680          } else {
09681             iaxthreadcount = atoi(v->value);
09682             if (iaxthreadcount < 1) {
09683                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09684                iaxthreadcount = 1;
09685             } else if (iaxthreadcount > 256) {
09686                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09687                iaxthreadcount = 256;
09688             }
09689          }
09690       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09691          if (reload) {
09692             AST_LIST_LOCK(&dynamic_list);
09693             iaxmaxthreadcount = atoi(v->value);
09694             AST_LIST_UNLOCK(&dynamic_list);
09695          } else {
09696             iaxmaxthreadcount = atoi(v->value);
09697             if (iaxmaxthreadcount < 0) {
09698                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09699                iaxmaxthreadcount = 0;
09700             } else if (iaxmaxthreadcount > 256) {
09701                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09702                iaxmaxthreadcount = 256;
09703             }
09704          }
09705       } else if (!strcasecmp(v->name, "nochecksums")) {
09706 #ifdef SO_NO_CHECK
09707          if (ast_true(v->value))
09708             nochecksums = 1;
09709          else
09710             nochecksums = 0;
09711 #else
09712          if (ast_true(v->value))
09713             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09714 #endif
09715       }
09716       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09717          maxjitterbuffer = atoi(v->value);
09718       else if (!strcasecmp(v->name, "resyncthreshold")) 
09719          resyncthreshold = atoi(v->value);
09720       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09721          maxjitterinterps = atoi(v->value);
09722       else if (!strcasecmp(v->name, "lagrqtime")) 
09723          lagrq_time = atoi(v->value);
09724       else if (!strcasecmp(v->name, "maxregexpire")) 
09725          max_reg_expire = atoi(v->value);
09726       else if (!strcasecmp(v->name, "minregexpire")) 
09727          min_reg_expire = atoi(v->value);
09728       else if (!strcasecmp(v->name, "bindaddr")) {
09729          if (reload) {
09730             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09731          } else {
09732             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09733                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09734             } else {
09735                if (option_verbose > 1) {
09736                   if (strchr(v->value, ':'))
09737                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09738                   else
09739                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09740                }
09741                if (defaultsockfd < 0) 
09742                   defaultsockfd = ast_netsock_sockfd(ns);
09743                ast_netsock_unref(ns);
09744             }
09745          }
09746       } else if (!strcasecmp(v->name, "authdebug"))
09747          authdebug = ast_true(v->value);
09748       else if (!strcasecmp(v->name, "encryption"))
09749          iax2_encryption = get_encrypt_methods(v->value);
09750       else if (!strcasecmp(v->name, "notransfer")) {
09751          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09752          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09753          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09754       } else if (!strcasecmp(v->name, "transfer")) {
09755          if (!strcasecmp(v->value, "mediaonly")) {
09756             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09757          } else if (ast_true(v->value)) {
09758             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09759          } else 
09760             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09761       } else if (!strcasecmp(v->name, "codecpriority")) {
09762          if(!strcasecmp(v->value, "caller"))
09763             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09764          else if(!strcasecmp(v->value, "disabled"))
09765             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09766          else if(!strcasecmp(v->value, "reqonly")) {
09767             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09768             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09769          }
09770       } else if (!strcasecmp(v->name, "jitterbuffer"))
09771          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
09772       else if (!strcasecmp(v->name, "forcejitterbuffer"))
09773          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
09774       else if (!strcasecmp(v->name, "delayreject"))
09775          delayreject = ast_true(v->value);
09776       else if (!strcasecmp(v->name, "rtcachefriends"))
09777          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
09778       else if (!strcasecmp(v->name, "rtignoreregexpire"))
09779          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
09780       else if (!strcasecmp(v->name, "rtupdate"))
09781          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09782       else if (!strcasecmp(v->name, "trunktimestamps"))
09783          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09784       else if (!strcasecmp(v->name, "rtautoclear")) {
09785          int i = atoi(v->value);
09786          if(i > 0)
09787             global_rtautoclear = i;
09788          else
09789             i = 0;
09790          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
09791       } else if (!strcasecmp(v->name, "trunkfreq")) {
09792          trunkfreq = atoi(v->value);
09793          if (trunkfreq < 10)
09794             trunkfreq = 10;
09795       } else if (!strcasecmp(v->name, "autokill")) {
09796          if (sscanf(v->value, "%d", &x) == 1) {
09797             if (x >= 0)
09798                autokill = x;
09799             else
09800                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09801          } else if (ast_true(v->value)) {
09802             autokill = DEFAULT_MAXMS;
09803          } else {
09804             autokill = 0;
09805          }
09806       } else if (!strcasecmp(v->name, "bandwidth")) {
09807          if (!strcasecmp(v->value, "low")) {
09808             capability = IAX_CAPABILITY_LOWBANDWIDTH;
09809          } else if (!strcasecmp(v->value, "medium")) {
09810             capability = IAX_CAPABILITY_MEDBANDWIDTH;
09811          } else if (!strcasecmp(v->value, "high")) {
09812             capability = IAX_CAPABILITY_FULLBANDWIDTH;
09813          } else
09814             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09815       } else if (!strcasecmp(v->name, "allow")) {
09816          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09817       } else if (!strcasecmp(v->name, "disallow")) {
09818          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09819       } else if (!strcasecmp(v->name, "register")) {
09820          iax2_register(v->value, v->lineno);
09821       } else if (!strcasecmp(v->name, "iaxcompat")) {
09822          iaxcompat = ast_true(v->value);
09823       } else if (!strcasecmp(v->name, "regcontext")) {
09824          ast_copy_string(regcontext, v->value, sizeof(regcontext));
09825          /* Create context if it doesn't exist already */
09826          if (!ast_context_find(regcontext))
09827             ast_context_create(NULL, regcontext, "IAX2");
09828       } else if (!strcasecmp(v->name, "tos")) {
09829          if (ast_str2tos(v->value, &tos))
09830             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09831       } else if (!strcasecmp(v->name, "accountcode")) {
09832          ast_copy_string(accountcode, v->value, sizeof(accountcode));
09833       } else if (!strcasecmp(v->name, "mohinterpret")) {
09834          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09835       } else if (!strcasecmp(v->name, "mohsuggest")) {
09836          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09837       } else if (!strcasecmp(v->name, "amaflags")) {
09838          format = ast_cdr_amaflags2int(v->value);
09839          if (format < 0) {
09840             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09841          } else {
09842             amaflags = format;
09843          }
09844       } else if (!strcasecmp(v->name, "language")) {
09845          ast_copy_string(language, v->value, sizeof(language));
09846       } else if (!strcasecmp(v->name, "maxauthreq")) {
09847          maxauthreq = atoi(v->value);
09848          if (maxauthreq < 0)
09849             maxauthreq = 0;
09850       } else if (!strcasecmp(v->name, "adsi")) {
09851          adsi = ast_true(v->value);
09852       } /*else if (strcasecmp(v->name,"type")) */
09853       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09854       v = v->next;
09855    }
09856    
09857    if (defaultsockfd < 0) {
09858       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09859          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09860       } else {
09861          if (option_verbose > 1)
09862             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09863          defaultsockfd = ast_netsock_sockfd(ns);
09864          ast_netsock_unref(ns);
09865       }
09866    }
09867    if (reload) {
09868       ast_netsock_release(outsock);
09869       outsock = ast_netsock_list_alloc();
09870       if (!outsock) {
09871          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09872          return -1;
09873       }
09874       ast_netsock_init(outsock);
09875    }
09876 
09877    if (min_reg_expire > max_reg_expire) {
09878       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09879          min_reg_expire, max_reg_expire, max_reg_expire);
09880       min_reg_expire = max_reg_expire;
09881    }
09882    iax2_capability = capability;
09883    
09884    ucfg = ast_config_load("users.conf");
09885    if (ucfg) {
09886       struct ast_variable *gen;
09887       int genhasiax;
09888       int genregisteriax;
09889       const char *hasiax, *registeriax;
09890       
09891       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09892       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09893       gen = ast_variable_browse(ucfg, "general");
09894       cat = ast_category_browse(ucfg, NULL);
09895       while (cat) {
09896          if (strcasecmp(cat, "general")) {
09897             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09898             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09899             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09900                /* Start with general parameters, then specific parameters, user and peer */
09901                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09902                if (user) {
09903                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09904                   user = user_unref(user);
09905                }
09906                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09907                if (peer) {
09908                   if (ast_test_flag(peer, IAX_DYNAMIC))
09909                      reg_source_db(peer);
09910                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09911                   peer = peer_unref(peer);
09912                }
09913             }
09914             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09915                char tmp[256];
09916                const char *host = ast_variable_retrieve(ucfg, cat, "host");
09917                const char *username = ast_variable_retrieve(ucfg, cat, "username");
09918                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09919                if (!host)
09920                   host = ast_variable_retrieve(ucfg, "general", "host");
09921                if (!username)
09922                   username = ast_variable_retrieve(ucfg, "general", "username");
09923                if (!secret)
09924                   secret = ast_variable_retrieve(ucfg, "general", "secret");
09925                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09926                   if (!ast_strlen_zero(secret))
09927                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09928                   else
09929                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09930                   iax2_register(tmp, 0);
09931                }
09932             }
09933          }
09934          cat = ast_category_browse(ucfg, cat);
09935       }
09936       ast_config_destroy(ucfg);
09937    }
09938    
09939    cat = ast_category_browse(cfg, NULL);
09940    while(cat) {
09941       if (strcasecmp(cat, "general")) {
09942          utype = ast_variable_retrieve(cfg, cat, "type");
09943          if (utype) {
09944             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09945                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09946                if (user) {
09947                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09948                   user = user_unref(user);
09949                }
09950             }
09951             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09952                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09953                if (peer) {
09954                   if (ast_test_flag(peer, IAX_DYNAMIC))
09955                      reg_source_db(peer);
09956                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09957                   peer = peer_unref(peer);
09958                }
09959             } else if (strcasecmp(utype, "user")) {
09960                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
09961             }
09962          } else
09963             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
09964       }
09965       cat = ast_category_browse(cfg, cat);
09966    }
09967    ast_config_destroy(cfg);
09968    set_timing();
09969    return 1;
09970 }
09971 
09972 static void poke_all_peers(void)
09973 {
09974    struct ao2_iterator i;
09975    struct iax2_peer *peer;
09976 
09977    i = ao2_iterator_init(peers, 0);
09978    while ((peer = ao2_iterator_next(&i))) {
09979       iax2_poke_peer(peer, 0);
09980       peer_unref(peer);
09981    }
09982 }
09983 static int reload_config(void)
09984 {
09985    char *config = "iax.conf";
09986    struct iax2_registry *reg;
09987 
09988    if (set_config(config, 1) > 0) {
09989       prune_peers();
09990       prune_users();
09991       AST_LIST_LOCK(&registrations);
09992       AST_LIST_TRAVERSE(&registrations, reg, entry)
09993          iax2_do_register(reg);
09994       AST_LIST_UNLOCK(&registrations);
09995       /* Qualify hosts, too */
09996       poke_all_peers();
09997    }
09998    reload_firmware(0);
09999    iax_provision_reload();
10000 
10001    return 0;
10002 }
10003 
10004 static int iax2_reload(int fd, int argc, char *argv[])
10005 {
10006    return reload_config();
10007 }
10008 
10009 static int reload(void)
10010 {
10011    return reload_config();
10012 }
10013 
10014 static int cache_get_callno_locked(const char *data)
10015 {
10016    struct sockaddr_in sin;
10017    int x;
10018    int callno;
10019    struct iax_ie_data ied;
10020    struct create_addr_info cai;
10021    struct parsed_dial_string pds;
10022    char *tmpstr;
10023 
10024    for (x=0; x<IAX_MAX_CALLS; x++) {
10025       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10026          look up entries for a single context */
10027       if (!ast_mutex_trylock(&iaxsl[x])) {
10028          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10029             return x;
10030          ast_mutex_unlock(&iaxsl[x]);
10031       }
10032    }
10033 
10034    /* No match found, we need to create a new one */
10035 
10036    memset(&cai, 0, sizeof(cai));
10037    memset(&ied, 0, sizeof(ied));
10038    memset(&pds, 0, sizeof(pds));
10039 
10040    tmpstr = ast_strdupa(data);
10041    parse_dial_string(tmpstr, &pds);
10042 
10043    /* Populate our address from the given */
10044    if (create_addr(pds.peer, &sin, &cai))
10045       return -1;
10046 
10047    if (option_debug)
10048       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10049          pds.peer, pds.username, pds.password, pds.context);
10050 
10051    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
10052    if (callno < 1) {
10053       ast_log(LOG_WARNING, "Unable to create call\n");
10054       return -1;
10055    }
10056 
10057    ast_mutex_lock(&iaxsl[callno]);
10058    ast_string_field_set(iaxs[callno], dproot, data);
10059    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10060 
10061    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10062    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10063    /* the string format is slightly different from a standard dial string,
10064       because the context appears in the 'exten' position
10065    */
10066    if (pds.exten)
10067       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10068    if (pds.username)
10069       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10070    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10071    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10072    /* Keep password handy */
10073    if (pds.password)
10074       ast_string_field_set(iaxs[callno], secret, pds.password);
10075    if (pds.key)
10076       ast_string_field_set(iaxs[callno], outkey, pds.key);
10077    /* Start the call going */
10078    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10079 
10080    return callno;
10081 }
10082 
10083 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10084 {
10085    struct iax2_dpcache *dp, *prev = NULL, *next;
10086    struct timeval tv;
10087    int x;
10088    int com[2];
10089    int timeout;
10090    int old=0;
10091    int outfd;
10092    int abort;
10093    int callno;
10094    struct ast_channel *c;
10095    struct ast_frame *f;
10096    gettimeofday(&tv, NULL);
10097    dp = dpcache;
10098    while(dp) {
10099       next = dp->next;
10100       /* Expire old caches */
10101       if (ast_tvcmp(tv, dp->expiry) > 0) {
10102             /* It's expired, let it disappear */
10103             if (prev)
10104                prev->next = dp->next;
10105             else
10106                dpcache = dp->next;
10107             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10108                /* Free memory and go again */
10109                free(dp);
10110             } else {
10111                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);
10112             }
10113             dp = next;
10114             continue;
10115       }
10116       /* We found an entry that matches us! */
10117       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10118          break;
10119       prev = dp;
10120       dp = next;
10121    }
10122    if (!dp) {
10123       /* No matching entry.  Create a new one. */
10124       /* First, can we make a callno? */
10125       callno = cache_get_callno_locked(data);
10126       if (callno < 0) {
10127          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10128          return NULL;
10129       }
10130       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10131          ast_mutex_unlock(&iaxsl[callno]);
10132          return NULL;
10133       }
10134       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10135       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10136       gettimeofday(&dp->expiry, NULL);
10137       dp->orig = dp->expiry;
10138       /* Expires in 30 mins by default */
10139       dp->expiry.tv_sec += iaxdefaultdpcache;
10140       dp->next = dpcache;
10141       dp->flags = CACHE_FLAG_PENDING;
10142       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10143          dp->waiters[x] = -1;
10144       dpcache = dp;
10145       dp->peer = iaxs[callno]->dpentries;
10146       iaxs[callno]->dpentries = dp;
10147       /* Send the request if we're already up */
10148       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10149          iax2_dprequest(dp, callno);
10150       ast_mutex_unlock(&iaxsl[callno]);
10151    }
10152    /* By here we must have a dp */
10153    if (dp->flags & CACHE_FLAG_PENDING) {
10154       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10155          for a reply to come back so long as it's pending */
10156       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10157          /* Find an empty slot */
10158          if (dp->waiters[x] < 0)
10159             break;
10160       }
10161       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10162          ast_log(LOG_WARNING, "No more waiter positions available\n");
10163          return NULL;
10164       }
10165       if (pipe(com)) {
10166          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10167          return NULL;
10168       }
10169       dp->waiters[x] = com[1];
10170       /* Okay, now we wait */
10171       timeout = iaxdefaulttimeout * 1000;
10172       /* Temporarily unlock */
10173       ast_mutex_unlock(&dpcache_lock);
10174       /* Defer any dtmf */
10175       if (chan)
10176          old = ast_channel_defer_dtmf(chan);
10177       abort = 0;
10178       while(timeout) {
10179          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10180          if (outfd > -1) {
10181             break;
10182          }
10183          if (c) {
10184             f = ast_read(c);
10185             if (f)
10186                ast_frfree(f);
10187             else {
10188                /* Got hung up on, abort! */
10189                break;
10190                abort = 1;
10191             }
10192          }
10193       }
10194       if (!timeout) {
10195          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10196       }
10197       ast_mutex_lock(&dpcache_lock);
10198       dp->waiters[x] = -1;
10199       close(com[1]);
10200       close(com[0]);
10201       if (abort) {
10202          /* Don't interpret anything, just abort.  Not sure what th epoint
10203            of undeferring dtmf on a hung up channel is but hey whatever */
10204          if (!old && chan)
10205             ast_channel_undefer_dtmf(chan);
10206          return NULL;
10207       }
10208       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10209          /* Now to do non-independent analysis the results of our wait */
10210          if (dp->flags & CACHE_FLAG_PENDING) {
10211             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10212                pending.  Don't let it take as long to timeout. */
10213             dp->flags &= ~CACHE_FLAG_PENDING;
10214             dp->flags |= CACHE_FLAG_TIMEOUT;
10215             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10216                systems without leaving it unavailable once the server comes back online */
10217             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10218             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10219                if (dp->waiters[x] > -1)
10220                   write(dp->waiters[x], "asdf", 4);
10221          }
10222       }
10223       /* Our caller will obtain the rest */
10224       if (!old && chan)
10225          ast_channel_undefer_dtmf(chan);
10226    }
10227    return dp;  
10228 }
10229 
10230 /*! \brief Part of the IAX2 switch interface */
10231 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10232 {
10233    struct iax2_dpcache *dp;
10234    int res = 0;
10235 #if 0
10236    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10237 #endif
10238    if ((priority != 1) && (priority != 2))
10239       return 0;
10240    ast_mutex_lock(&dpcache_lock);
10241    dp = find_cache(chan, data, context, exten, priority);
10242    if (dp) {
10243       if (dp->flags & CACHE_FLAG_EXISTS)
10244          res= 1;
10245    }
10246    ast_mutex_unlock(&dpcache_lock);
10247    if (!dp) {
10248       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10249    }
10250    return res;
10251 }
10252 
10253 /*! \brief part of the IAX2 dial plan switch interface */
10254 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10255 {
10256    int res = 0;
10257    struct iax2_dpcache *dp;
10258 #if 0
10259    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10260 #endif
10261    if ((priority != 1) && (priority != 2))
10262       return 0;
10263    ast_mutex_lock(&dpcache_lock);
10264    dp = find_cache(chan, data, context, exten, priority);
10265    if (dp) {
10266       if (dp->flags & CACHE_FLAG_CANEXIST)
10267          res= 1;
10268    }
10269    ast_mutex_unlock(&dpcache_lock);
10270    if (!dp) {
10271       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10272    }
10273    return res;
10274 }
10275 
10276 /*! \brief Part of the IAX2 Switch interface */
10277 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10278 {
10279    int res = 0;
10280    struct iax2_dpcache *dp;
10281 #if 0
10282    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10283 #endif
10284    if ((priority != 1) && (priority != 2))
10285       return 0;
10286    ast_mutex_lock(&dpcache_lock);
10287    dp = find_cache(chan, data, context, exten, priority);
10288    if (dp) {
10289       if (dp->flags & CACHE_FLAG_MATCHMORE)
10290          res= 1;
10291    }
10292    ast_mutex_unlock(&dpcache_lock);
10293    if (!dp) {
10294       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10295    }
10296    return res;
10297 }
10298 
10299 /*! \brief Execute IAX2 dialplan switch */
10300 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10301 {
10302    char odata[256];
10303    char req[256];
10304    char *ncontext;
10305    struct iax2_dpcache *dp;
10306    struct ast_app *dial;
10307 #if 0
10308    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);
10309 #endif
10310    if (priority == 2) {
10311       /* Indicate status, can be overridden in dialplan */
10312       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10313       if (dialstatus) {
10314          dial = pbx_findapp(dialstatus);
10315          if (dial) 
10316             pbx_exec(chan, dial, "");
10317       }
10318       return -1;
10319    } else if (priority != 1)
10320       return -1;
10321    ast_mutex_lock(&dpcache_lock);
10322    dp = find_cache(chan, data, context, exten, priority);
10323    if (dp) {
10324       if (dp->flags & CACHE_FLAG_EXISTS) {
10325          ast_copy_string(odata, data, sizeof(odata));
10326          ncontext = strchr(odata, '/');
10327          if (ncontext) {
10328             *ncontext = '\0';
10329             ncontext++;
10330             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10331          } else {
10332             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10333          }
10334          if (option_verbose > 2)
10335             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10336       } else {
10337          ast_mutex_unlock(&dpcache_lock);
10338          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10339          return -1;
10340       }
10341    }
10342    ast_mutex_unlock(&dpcache_lock);
10343    dial = pbx_findapp("Dial");
10344    if (dial) {
10345       return pbx_exec(chan, dial, req);
10346    } else {
10347       ast_log(LOG_WARNING, "No dial application registered\n");
10348    }
10349    return -1;
10350 }
10351 
10352 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10353 {
10354    struct iax2_peer *peer;
10355    char *peername, *colname;
10356 
10357    peername = ast_strdupa(data);
10358 
10359    /* if our channel, return the IP address of the endpoint of current channel */
10360    if (!strcmp(peername,"CURRENTCHANNEL")) {
10361            unsigned short callno;
10362       if (chan->tech != &iax2_tech)
10363          return -1;
10364       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10365       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10366       return 0;
10367    }
10368 
10369    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10370       *colname++ = '\0';
10371    else if ((colname = strchr(peername, '|')))
10372       *colname++ = '\0';
10373    else
10374       colname = "ip";
10375 
10376    if (!(peer = find_peer(peername, 1)))
10377       return -1;
10378 
10379    if (!strcasecmp(colname, "ip")) {
10380       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10381    } else  if (!strcasecmp(colname, "status")) {
10382       peer_status(peer, buf, len); 
10383    } else  if (!strcasecmp(colname, "mailbox")) {
10384       ast_copy_string(buf, peer->mailbox, len);
10385    } else  if (!strcasecmp(colname, "context")) {
10386       ast_copy_string(buf, peer->context, len);
10387    } else  if (!strcasecmp(colname, "expire")) {
10388       snprintf(buf, len, "%d", peer->expire);
10389    } else  if (!strcasecmp(colname, "dynamic")) {
10390       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10391    } else  if (!strcasecmp(colname, "callerid_name")) {
10392       ast_copy_string(buf, peer->cid_name, len);
10393    } else  if (!strcasecmp(colname, "callerid_num")) {
10394       ast_copy_string(buf, peer->cid_num, len);
10395    } else  if (!strcasecmp(colname, "codecs")) {
10396       ast_getformatname_multiple(buf, len -1, peer->capability);
10397    } else  if (!strncasecmp(colname, "codec[", 6)) {
10398       char *codecnum, *ptr;
10399       int index = 0, codec = 0;
10400       
10401       codecnum = strchr(colname, '[');
10402       *codecnum = '\0';
10403       codecnum++;
10404       if ((ptr = strchr(codecnum, ']'))) {
10405          *ptr = '\0';
10406       }
10407       index = atoi(codecnum);
10408       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10409          ast_copy_string(buf, ast_getformatname(codec), len);
10410       }
10411    }
10412 
10413    peer_unref(peer);
10414 
10415    return 0;
10416 }
10417 
10418 struct ast_custom_function iaxpeer_function = {
10419    .name = "IAXPEER",
10420    .synopsis = "Gets IAX peer information",
10421    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10422    .read = function_iaxpeer,
10423    .desc = "If peername specified, valid items are:\n"
10424    "- ip (default)          The IP address.\n"
10425    "- status                The peer's status (if qualify=yes)\n"
10426    "- mailbox               The configured mailbox.\n"
10427    "- context               The configured context.\n"
10428    "- expire                The epoch time of the next expire.\n"
10429    "- dynamic               Is it dynamic? (yes/no).\n"
10430    "- callerid_name         The configured Caller ID name.\n"
10431    "- callerid_num          The configured Caller ID number.\n"
10432    "- codecs                The configured codecs.\n"
10433    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10434    "\n"
10435    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10436    "\n"
10437 };
10438 
10439 
10440 /*! \brief Part of the device state notification system ---*/
10441 static int iax2_devicestate(void *data) 
10442 {
10443    struct parsed_dial_string pds;
10444    char *tmp = ast_strdupa(data);
10445    struct iax2_peer *p;
10446    int res = AST_DEVICE_INVALID;
10447 
10448    memset(&pds, 0, sizeof(pds));
10449    parse_dial_string(tmp, &pds);
10450    if (ast_strlen_zero(pds.peer))
10451       return res;
10452    
10453    if (option_debug > 2)
10454       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10455 
10456    /* SLD: FIXME: second call to find_peer during registration */
10457    if (!(p = find_peer(pds.peer, 1)))
10458       return res;
10459 
10460    res = AST_DEVICE_UNAVAILABLE;
10461    if (option_debug > 2) 
10462       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10463          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10464    
10465    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10466        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10467       /* Peer is registered, or have default IP address
10468          and a valid registration */
10469       if (p->historicms == 0 || p->historicms <= p->maxms)
10470          /* let the core figure out whether it is in use or not */
10471          res = AST_DEVICE_UNKNOWN;  
10472    }
10473 
10474    peer_unref(p);
10475 
10476    return res;
10477 }
10478 
10479 static struct ast_switch iax2_switch = 
10480 {
10481    name:          "IAX2",
10482    description:      "IAX Remote Dialplan Switch",
10483    exists:        iax2_exists,
10484    canmatch:      iax2_canmatch,
10485    exec:       iax2_exec,
10486    matchmore:     iax2_matchmore,
10487 };
10488 
10489 static char show_stats_usage[] =
10490 "Usage: iax2 show stats\n"
10491 "       Display statistics on IAX channel driver.\n";
10492 
10493 static char show_cache_usage[] =
10494 "Usage: iax2 show cache\n"
10495 "       Display currently cached IAX Dialplan results.\n";
10496 
10497 static char show_peer_usage[] =
10498 "Usage: iax2 show peer <name>\n"
10499 "       Display details on specific IAX peer\n";
10500 
10501 static char prune_realtime_usage[] =
10502 "Usage: iax2 prune realtime [<peername>|all]\n"
10503 "       Prunes object(s) from the cache\n";
10504 
10505 static char iax2_reload_usage[] =
10506 "Usage: iax2 reload\n"
10507 "       Reloads IAX configuration from iax.conf\n";
10508 
10509 static char show_prov_usage[] =
10510 "Usage: iax2 provision <host> <template> [forced]\n"
10511 "       Provisions the given peer or IP address using a template\n"
10512 "       matching either 'template' or '*' if the template is not\n"
10513 "       found.  If 'forced' is specified, even empty provisioning\n"
10514 "       fields will be provisioned as empty fields.\n";
10515 
10516 static char show_users_usage[] = 
10517 "Usage: iax2 show users [like <pattern>]\n"
10518 "       Lists all known IAX2 users.\n"
10519 "       Optional regular expression pattern is used to filter the user list.\n";
10520 
10521 static char show_channels_usage[] = 
10522 "Usage: iax2 show channels\n"
10523 "       Lists all currently active IAX channels.\n";
10524 
10525 static char show_netstats_usage[] = 
10526 "Usage: iax2 show netstats\n"
10527 "       Lists network status for all currently active IAX channels.\n";
10528 
10529 static char show_threads_usage[] = 
10530 "Usage: iax2 show threads\n"
10531 "       Lists status of IAX helper threads\n";
10532 
10533 static char show_peers_usage[] = 
10534 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10535 "       Lists all known IAX2 peers.\n"
10536 "       Optional 'registered' argument lists only peers with known addresses.\n"
10537 "       Optional regular expression pattern is used to filter the peer list.\n";
10538 
10539 static char show_firmware_usage[] = 
10540 "Usage: iax2 show firmware\n"
10541 "       Lists all known IAX firmware images.\n";
10542 
10543 static char show_reg_usage[] =
10544 "Usage: iax2 show registry\n"
10545 "       Lists all registration requests and status.\n";
10546 
10547 static char debug_usage[] = 
10548 "Usage: iax2 set debug\n"
10549 "       Enables dumping of IAX packets for debugging purposes\n";
10550 
10551 static char no_debug_usage[] = 
10552 "Usage: iax2 set debug off\n"
10553 "       Disables dumping of IAX packets for debugging purposes\n";
10554 
10555 static char debug_trunk_usage[] =
10556 "Usage: iax2 set debug trunk\n"
10557 "       Requests current status of IAX trunking\n";
10558 
10559 static char no_debug_trunk_usage[] =
10560 "Usage: iax2 set debug trunk off\n"
10561 "       Requests current status of IAX trunking\n";
10562 
10563 static char debug_jb_usage[] =
10564 "Usage: iax2 set debug jb\n"
10565 "       Enables jitterbuffer debugging information\n";
10566 
10567 static char no_debug_jb_usage[] =
10568 "Usage: iax2 set debug jb off\n"
10569 "       Disables jitterbuffer debugging information\n";
10570 
10571 static char iax2_test_losspct_usage[] =
10572 "Usage: iax2 test losspct <percentage>\n"
10573 "       For testing, throws away <percentage> percent of incoming packets\n";
10574 
10575 #ifdef IAXTESTS
10576 static char iax2_test_late_usage[] =
10577 "Usage: iax2 test late <ms>\n"
10578 "       For testing, count the next frame as <ms> ms late\n";
10579 
10580 static char iax2_test_resync_usage[] =
10581 "Usage: iax2 test resync <ms>\n"
10582 "       For testing, adjust all future frames by <ms> ms\n";
10583 
10584 static char iax2_test_jitter_usage[] =
10585 "Usage: iax2 test jitter <ms> <pct>\n"
10586 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10587 #endif /* IAXTESTS */
10588 
10589 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10590    { "iax2", "trunk", "debug", NULL },
10591    iax2_do_trunk_debug, NULL,
10592    NULL };
10593 
10594 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10595    { "iax2", "jb", "debug", NULL },
10596    iax2_do_jb_debug, NULL,
10597    NULL };
10598 
10599 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10600    { "iax2", "no", "debug", NULL },
10601    iax2_no_debug, NULL,
10602    NULL };
10603 
10604 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10605    { "iax2", "no", "trunk", "debug", NULL },
10606    iax2_no_trunk_debug, NULL,
10607    NULL };
10608 
10609 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10610    { "iax2", "no", "jb", "debug", NULL },
10611    iax2_no_jb_debug, NULL,
10612    NULL };
10613 
10614 static struct ast_cli_entry cli_iax2[] = {
10615    { { "iax2", "show", "cache", NULL },
10616    iax2_show_cache, "Display IAX cached dialplan",
10617    show_cache_usage, NULL, },
10618 
10619    { { "iax2", "show", "channels", NULL },
10620    iax2_show_channels, "List active IAX channels",
10621    show_channels_usage, NULL, },
10622 
10623    { { "iax2", "show", "firmware", NULL },
10624    iax2_show_firmware, "List available IAX firmwares",
10625    show_firmware_usage, NULL, },
10626 
10627    { { "iax2", "show", "netstats", NULL },
10628    iax2_show_netstats, "List active IAX channel netstats",
10629    show_netstats_usage, NULL, },
10630 
10631    { { "iax2", "show", "peers", NULL },
10632    iax2_show_peers, "List defined IAX peers",
10633    show_peers_usage, NULL, },
10634 
10635    { { "iax2", "show", "registry", NULL },
10636    iax2_show_registry, "Display IAX registration status",
10637    show_reg_usage, NULL, },
10638 
10639    { { "iax2", "show", "stats", NULL },
10640    iax2_show_stats, "Display IAX statistics",
10641    show_stats_usage, NULL, },
10642 
10643    { { "iax2", "show", "threads", NULL },
10644    iax2_show_threads, "Display IAX helper thread info",
10645    show_threads_usage, NULL, },
10646 
10647    { { "iax2", "show", "users", NULL },
10648    iax2_show_users, "List defined IAX users",
10649    show_users_usage, NULL, },
10650 
10651    { { "iax2", "prune", "realtime", NULL },
10652    iax2_prune_realtime, "Prune a cached realtime lookup",
10653    prune_realtime_usage, complete_iax2_show_peer },
10654 
10655    { { "iax2", "reload", NULL },
10656    iax2_reload, "Reload IAX configuration",
10657    iax2_reload_usage },
10658 
10659    { { "iax2", "show", "peer", NULL },
10660    iax2_show_peer, "Show details on specific IAX peer",
10661    show_peer_usage, complete_iax2_show_peer },
10662 
10663    { { "iax2", "set", "debug", NULL },
10664    iax2_do_debug, "Enable IAX debugging",
10665    debug_usage },
10666 
10667    { { "iax2", "set", "debug", "trunk", NULL },
10668    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10669    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10670 
10671    { { "iax2", "set", "debug", "jb", NULL },
10672    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10673    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10674 
10675    { { "iax2", "set", "debug", "off", NULL },
10676    iax2_no_debug, "Disable IAX debugging",
10677    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10678 
10679    { { "iax2", "set", "debug", "trunk", "off", NULL },
10680    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10681    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10682 
10683    { { "iax2", "set", "debug", "jb", "off", NULL },
10684    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10685    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10686 
10687    { { "iax2", "test", "losspct", NULL },
10688    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10689    iax2_test_losspct_usage },
10690 
10691    { { "iax2", "provision", NULL },
10692    iax2_prov_cmd, "Provision an IAX device",
10693    show_prov_usage, iax2_prov_complete_template_3rd },
10694 
10695 #ifdef IAXTESTS
10696    { { "iax2", "test", "late", NULL },
10697    iax2_test_late, "Test the receipt of a late frame",
10698    iax2_test_late_usage },
10699 
10700    { { "iax2", "test", "resync", NULL },
10701    iax2_test_resync, "Test a resync in received timestamps",
10702    iax2_test_resync_usage },
10703 
10704    { { "iax2", "test", "jitter", NULL },
10705    iax2_test_jitter, "Simulates jitter for testing",
10706    iax2_test_jitter_usage },
10707 #endif /* IAXTESTS */
10708 };
10709 
10710 static int __unload_module(void)
10711 {
10712    struct iax2_thread *thread = NULL;
10713    int x;
10714 
10715    /* Make sure threads do not hold shared resources when they are canceled */
10716    
10717    /* Grab the sched lock resource to keep it away from threads about to die */
10718    /* Cancel the network thread, close the net socket */
10719    if (netthreadid != AST_PTHREADT_NULL) {
10720       AST_LIST_LOCK(&iaxq.queue);
10721       ast_mutex_lock(&sched_lock);
10722       pthread_cancel(netthreadid);
10723       ast_cond_signal(&sched_cond);
10724       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10725       AST_LIST_UNLOCK(&iaxq.queue);
10726       pthread_join(netthreadid, NULL);
10727    }
10728    if (schedthreadid != AST_PTHREADT_NULL) {
10729       ast_mutex_lock(&sched_lock);  
10730       pthread_cancel(schedthreadid);
10731       ast_cond_signal(&sched_cond);
10732       ast_mutex_unlock(&sched_lock);   
10733       pthread_join(schedthreadid, NULL);
10734    }
10735    
10736    /* Call for all threads to halt */
10737    AST_LIST_LOCK(&idle_list);
10738    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10739       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10740       pthread_cancel(thread->threadid);
10741    }
10742    AST_LIST_TRAVERSE_SAFE_END
10743    AST_LIST_UNLOCK(&idle_list);
10744 
10745    AST_LIST_LOCK(&active_list);
10746    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10747       AST_LIST_REMOVE_CURRENT(&active_list, list);
10748       pthread_cancel(thread->threadid);
10749    }
10750    AST_LIST_TRAVERSE_SAFE_END
10751    AST_LIST_UNLOCK(&active_list);
10752 
10753    AST_LIST_LOCK(&dynamic_list);
10754         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10755       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10756       pthread_cancel(thread->threadid);
10757         }
10758    AST_LIST_TRAVERSE_SAFE_END
10759         AST_LIST_UNLOCK(&dynamic_list);
10760 
10761    AST_LIST_HEAD_DESTROY(&iaxq.queue);
10762 
10763    /* Wait for threads to exit */
10764    while(0 < iaxactivethreadcount)
10765       usleep(10000);
10766    
10767    ast_netsock_release(netsock);
10768    ast_netsock_release(outsock);
10769    for (x=0;x<IAX_MAX_CALLS;x++)
10770       if (iaxs[x])
10771          iax2_destroy(x);
10772    ast_manager_unregister( "IAXpeers" );
10773    ast_manager_unregister( "IAXnetstats" );
10774    ast_unregister_application(papp);
10775    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10776    ast_unregister_switch(&iax2_switch);
10777    ast_channel_unregister(&iax2_tech);
10778    delete_users();
10779    iax_provision_unload();
10780    sched_context_destroy(sched);
10781    reload_firmware(1);
10782 
10783    ast_mutex_destroy(&waresl.lock);
10784 
10785    for (x = 0; x < IAX_MAX_CALLS; x++)
10786       ast_mutex_destroy(&iaxsl[x]);
10787 
10788    ao2_ref(peers, -1);
10789    ao2_ref(users, -1);
10790 
10791    return 0;
10792 }
10793 
10794 static int unload_module(void)
10795 {
10796    ast_custom_function_unregister(&iaxpeer_function);
10797    return __unload_module();
10798 }
10799 
10800 static int peer_set_sock_cb(void *obj, void *arg, int flags)
10801 {
10802    struct iax2_peer *peer = obj;
10803 
10804    if (peer->sockfd < 0)
10805       peer->sockfd = defaultsockfd;
10806 
10807    return 0;
10808 }
10809 
10810 /*! \brief Load IAX2 module, load configuraiton ---*/
10811 static int load_module(void)
10812 {
10813    char *config = "iax.conf";
10814    int res = 0;
10815    int x;
10816    struct iax2_registry *reg = NULL;
10817 
10818    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
10819    if (!peers)
10820       return AST_MODULE_LOAD_FAILURE;
10821    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
10822    if (!users) {
10823       ao2_ref(peers, -1);
10824       return AST_MODULE_LOAD_FAILURE;
10825    }
10826 
10827    ast_custom_function_register(&iaxpeer_function);
10828 
10829    iax_set_output(iax_debug_output);
10830    iax_set_error(iax_error_output);
10831    jb_setoutput(jb_error_output, jb_warning_output, NULL);
10832    
10833 #ifdef HAVE_ZAPTEL
10834 #ifdef ZT_TIMERACK
10835    timingfd = open("/dev/zap/timer", O_RDWR);
10836    if (timingfd < 0)
10837 #endif
10838       timingfd = open("/dev/zap/pseudo", O_RDWR);
10839    if (timingfd < 0) 
10840       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10841 #endif      
10842 
10843    memset(iaxs, 0, sizeof(iaxs));
10844 
10845    for (x=0;x<IAX_MAX_CALLS;x++)
10846       ast_mutex_init(&iaxsl[x]);
10847    
10848    ast_cond_init(&sched_cond, NULL);
10849 
10850    io = io_context_create();
10851    sched = sched_context_create();
10852    
10853    if (!io || !sched) {
10854       ast_log(LOG_ERROR, "Out of memory\n");
10855       return -1;
10856    }
10857 
10858    netsock = ast_netsock_list_alloc();
10859    if (!netsock) {
10860       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10861       return -1;
10862    }
10863    ast_netsock_init(netsock);
10864 
10865    outsock = ast_netsock_list_alloc();
10866    if (!outsock) {
10867       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10868       return -1;
10869    }
10870    ast_netsock_init(outsock);
10871 
10872    ast_mutex_init(&waresl.lock);
10873 
10874    AST_LIST_HEAD_INIT(&iaxq.queue);
10875    
10876    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10877 
10878    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10879    
10880    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10881    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10882 
10883    if(set_config(config, 0) == -1)
10884       return AST_MODULE_LOAD_DECLINE;
10885 
10886    if (ast_channel_register(&iax2_tech)) {
10887       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10888       __unload_module();
10889       return -1;
10890    }
10891 
10892    if (ast_register_switch(&iax2_switch)) 
10893       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10894 
10895    res = start_network_thread();
10896    if (!res) {
10897       if (option_verbose > 1) 
10898          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10899    } else {
10900       ast_log(LOG_ERROR, "Unable to start network thread\n");
10901       ast_netsock_release(netsock);
10902       ast_netsock_release(outsock);
10903    }
10904 
10905    AST_LIST_LOCK(&registrations);
10906    AST_LIST_TRAVERSE(&registrations, reg, entry)
10907       iax2_do_register(reg);
10908    AST_LIST_UNLOCK(&registrations); 
10909 
10910    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
10911    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
10912 
10913    reload_firmware(0);
10914    iax_provision_reload();
10915    return res;
10916 }
10917 
10918 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10919       .load = load_module,
10920       .unload = unload_module,
10921       .reload = reload,
10922           );

Generated on Sat Apr 12 07:12:20 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5