Fri Aug 24 02:22:13 2007

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>zaptel</use>
00033  ***/
00034 
00035 #include "asterisk.h"
00036 
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <sys/types.h>
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <string.h>
00053 #include <strings.h>
00054 #include <errno.h>
00055 #include <unistd.h>
00056 #include <netdb.h>
00057 #include <fcntl.h>
00058 #include <sys/stat.h>
00059 #include <regex.h>
00060 
00061 #ifdef HAVE_ZAPTEL
00062 #include <sys/ioctl.h>
00063 #include <zaptel/zaptel.h>
00064 #endif
00065 
00066 #include "asterisk/lock.h"
00067 #include "asterisk/frame.h" 
00068 #include "asterisk/channel.h"
00069 #include "asterisk/logger.h"
00070 #include "asterisk/module.h"
00071 #include "asterisk/pbx.h"
00072 #include "asterisk/sched.h"
00073 #include "asterisk/io.h"
00074 #include "asterisk/config.h"
00075 #include "asterisk/options.h"
00076 #include "asterisk/cli.h"
00077 #include "asterisk/translate.h"
00078 #include "asterisk/md5.h"
00079 #include "asterisk/cdr.h"
00080 #include "asterisk/crypto.h"
00081 #include "asterisk/acl.h"
00082 #include "asterisk/manager.h"
00083 #include "asterisk/callerid.h"
00084 #include "asterisk/app.h"
00085 #include "asterisk/astdb.h"
00086 #include "asterisk/musiconhold.h"
00087 #include "asterisk/features.h"
00088 #include "asterisk/utils.h"
00089 #include "asterisk/causes.h"
00090 #include "asterisk/localtime.h"
00091 #include "asterisk/aes.h"
00092 #include "asterisk/dnsmgr.h"
00093 #include "asterisk/devicestate.h"
00094 #include "asterisk/netsock.h"
00095 #include "asterisk/stringfields.h"
00096 #include "asterisk/linkedlists.h"
00097 #include "asterisk/astobj2.h"
00098 
00099 #include "iax2.h"
00100 #include "iax2-parser.h"
00101 #include "iax2-provision.h"
00102 #include "jitterbuf.h"
00103 
00104 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00105    multithreaded mode. */
00106 #define SCHED_MULTITHREADED
00107 
00108 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00109    thread is actually doing. */
00110 #define DEBUG_SCHED_MULTITHREAD
00111 
00112 #ifndef IPTOS_MINCOST
00113 #define IPTOS_MINCOST 0x02
00114 #endif
00115 
00116 #ifdef SO_NO_CHECK
00117 static int nochecksums = 0;
00118 #endif
00119 
00120 
00121 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00122 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00123 
00124 #define DEFAULT_THREAD_COUNT 10
00125 #define DEFAULT_MAX_THREAD_COUNT 100
00126 #define DEFAULT_RETRY_TIME 1000
00127 #define MEMORY_SIZE 100
00128 #define DEFAULT_DROP 3
00129 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00130    but keeps the division between trunked and non-trunked better. */
00131 #define TRUNK_CALL_START   0x4000
00132 
00133 #define DEBUG_SUPPORT
00134 
00135 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00136 
00137 /* Sample over last 100 units to determine historic jitter */
00138 #define GAMMA (0.01)
00139 
00140 static struct ast_codec_pref prefs;
00141 
00142 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00143 
00144 static char context[80] = "default";
00145 
00146 static char language[MAX_LANGUAGE] = "";
00147 static char regcontext[AST_MAX_CONTEXT] = "";
00148 
00149 static int maxauthreq = 3;
00150 static int max_retries = 4;
00151 static int ping_time = 21;
00152 static int lagrq_time = 10;
00153 static int maxtrunkcall = TRUNK_CALL_START;
00154 static int maxnontrunkcall = 1;
00155 static int maxjitterbuffer=1000;
00156 static int resyncthreshold=1000;
00157 static int maxjitterinterps=10;
00158 static int trunkfreq = 20;
00159 static int authdebug = 1;
00160 static int autokill = 0;
00161 static int iaxcompat = 0;
00162 
00163 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00164 
00165 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00166 
00167 static unsigned int tos = 0;
00168 
00169 static int min_reg_expire;
00170 static int max_reg_expire;
00171 
00172 static int timingfd = -1;           /* Timing file descriptor */
00173 
00174 static struct ast_netsock_list *netsock;
00175 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00176 static int defaultsockfd = -1;
00177 
00178 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00179 
00180 /* Ethernet, etc */
00181 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00182 /* T1, maybe ISDN */
00183 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00184                 ~AST_FORMAT_SLINEAR &        \
00185                 ~AST_FORMAT_ULAW &        \
00186                 ~AST_FORMAT_ALAW &        \
00187                 ~AST_FORMAT_G722) 
00188 /* A modem */
00189 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00190                 ~AST_FORMAT_G726 &        \
00191                 ~AST_FORMAT_G726_AAL2 &      \
00192                 ~AST_FORMAT_ADPCM)
00193 
00194 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00195                 ~AST_FORMAT_G723_1)
00196 
00197 
00198 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00199 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00200 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00201 
00202 static   struct io_context *io;
00203 static   struct sched_context *sched;
00204 
00205 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00206 
00207 static int iaxdebug = 0;
00208 
00209 static int iaxtrunkdebug = 0;
00210 
00211 static int test_losspct = 0;
00212 #ifdef IAXTESTS
00213 static int test_late = 0;
00214 static int test_resync = 0;
00215 static int test_jit = 0;
00216 static int test_jitpct = 0;
00217 #endif /* IAXTESTS */
00218 
00219 static char accountcode[AST_MAX_ACCOUNT_CODE];
00220 static char mohinterpret[MAX_MUSICCLASS];
00221 static char mohsuggest[MAX_MUSICCLASS];
00222 static int amaflags = 0;
00223 static int adsi = 0;
00224 static int delayreject = 0;
00225 static int iax2_encryption = 0;
00226 
00227 static struct ast_flags globalflags = { 0 };
00228 
00229 static pthread_t netthreadid = AST_PTHREADT_NULL;
00230 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00231 AST_MUTEX_DEFINE_STATIC(sched_lock);
00232 static ast_cond_t sched_cond;
00233 
00234 enum {
00235    IAX_STATE_STARTED =     (1 << 0),
00236    IAX_STATE_AUTHENTICATED =  (1 << 1),
00237    IAX_STATE_TBD =      (1 << 2),
00238    IAX_STATE_UNCHANGED =      (1 << 3),
00239 } iax2_state;
00240 
00241 struct iax2_context {
00242    char context[AST_MAX_CONTEXT];
00243    struct iax2_context *next;
00244 };
00245 
00246 enum {
00247    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00248    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00249    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00250    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00251    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00252    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00253    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00254    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00255         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00256    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00257    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00258    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00259    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00260    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00261    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00262    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00263    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00264    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00265    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00266    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00267    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00268    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00269    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00270    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00271    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00272    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00273                        response, so that we've achieved a three-way handshake with
00274                        them before sending voice or anything else*/
00275 } iax2_flags;
00276 
00277 static int global_rtautoclear = 120;
00278 
00279 static int reload_config(void);
00280 static int iax2_reload(int fd, int argc, char *argv[]);
00281 
00282 
00283 struct iax2_user {
00284    AST_DECLARE_STRING_FIELDS(
00285       AST_STRING_FIELD(name);
00286       AST_STRING_FIELD(secret);
00287       AST_STRING_FIELD(dbsecret);
00288       AST_STRING_FIELD(accountcode);
00289       AST_STRING_FIELD(mohinterpret);
00290       AST_STRING_FIELD(mohsuggest);
00291       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00292       AST_STRING_FIELD(language);
00293       AST_STRING_FIELD(cid_num);
00294       AST_STRING_FIELD(cid_name);
00295    );
00296    
00297    int authmethods;
00298    int encmethods;
00299    int amaflags;
00300    int adsi;
00301    unsigned int flags;
00302    int capability;
00303    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00304    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00305    struct ast_codec_pref prefs;
00306    struct ast_ha *ha;
00307    struct iax2_context *contexts;
00308    struct ast_variable *vars;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361 };
00362 
00363 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00364 
00365 static struct iax2_trunk_peer {
00366    ast_mutex_t lock;
00367    int sockfd;
00368    struct sockaddr_in addr;
00369    struct timeval txtrunktime;      /*!< Transmit trunktime */
00370    struct timeval rxtrunktime;      /*!< Receive trunktime */
00371    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00372    struct timeval trunkact;      /*!< Last trunk activity */
00373    unsigned int lastsent;        /*!< Last sent time */
00374    /* Trunk data and length */
00375    unsigned char *trunkdata;
00376    unsigned int trunkdatalen;
00377    unsigned int trunkdataalloc;
00378    struct iax2_trunk_peer *next;
00379    int trunkerror;
00380    int calls;
00381 } *tpeers = NULL;
00382 
00383 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00384 
00385 struct iax_firmware {
00386    struct iax_firmware *next;
00387    int fd;
00388    int mmaplen;
00389    int dead;
00390    struct ast_iax2_firmware_header *fwh;
00391    unsigned char *buf;
00392 };
00393 
00394 enum iax_reg_state {
00395    REG_STATE_UNREGISTERED = 0,
00396    REG_STATE_REGSENT,
00397    REG_STATE_AUTHSENT,
00398    REG_STATE_REGISTERED,
00399    REG_STATE_REJECTED,
00400    REG_STATE_TIMEOUT,
00401    REG_STATE_NOAUTH
00402 };
00403 
00404 enum iax_transfer_state {
00405    TRANSFER_NONE = 0,
00406    TRANSFER_BEGIN,
00407    TRANSFER_READY,
00408    TRANSFER_RELEASED,
00409    TRANSFER_PASSTHROUGH,
00410    TRANSFER_MBEGIN,
00411    TRANSFER_MREADY,
00412    TRANSFER_MRELEASED,
00413    TRANSFER_MPASSTHROUGH,
00414    TRANSFER_MEDIA,
00415    TRANSFER_MEDIAPASS
00416 };
00417 
00418 struct iax2_registry {
00419    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00420    char username[80];
00421    char secret[80];        /*!< Password or key name in []'s */
00422    char random[80];
00423    int expire;          /*!< Sched ID of expiration */
00424    int refresh;            /*!< How often to refresh */
00425    enum iax_reg_state regstate;
00426    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00427    int callno;          /*!< Associated call number if applicable */
00428    struct sockaddr_in us;        /*!< Who the server thinks we are */
00429    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00430    AST_LIST_ENTRY(iax2_registry) entry;
00431 };
00432 
00433 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00434 
00435 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00436 #define MIN_RETRY_TIME     100
00437 #define MAX_RETRY_TIME     10000
00438 
00439 #define MAX_JITTER_BUFFER  50
00440 #define MIN_JITTER_BUFFER  10
00441 
00442 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00443 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00444 
00445 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00446 
00447 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00448 #define TS_GAP_FOR_JB_RESYNC  5000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxactivethreadcount = 0;
00454 
00455 struct iax_rr {
00456    int jitter;
00457    int losspct;
00458    int losscnt;
00459    int packets;
00460    int delay;
00461    int dropped;
00462    int ooo;
00463 };
00464 
00465 struct chan_iax2_pvt {
00466    /*! Socket to send/receive on for this call */
00467    int sockfd;
00468    /*! Last received voice format */
00469    int voiceformat;
00470    /*! Last received video format */
00471    int videoformat;
00472    /*! Last sent voice format */
00473    int svoiceformat;
00474    /*! Last sent video format */
00475    int svideoformat;
00476    /*! What we are capable of sending */
00477    int capability;
00478    /*! Last received timestamp */
00479    unsigned int last;
00480    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00481    unsigned int lastsent;
00482    /*! Next outgoing timestamp if everything is good */
00483    unsigned int nextpred;
00484    /*! True if the last voice we transmitted was not silence/CNG */
00485    int notsilenttx;
00486    /*! Ping time */
00487    unsigned int pingtime;
00488    /*! Max time for initial response */
00489    int maxtime;
00490    /*! Peer Address */
00491    struct sockaddr_in addr;
00492    /*! Actual used codec preferences */
00493    struct ast_codec_pref prefs;
00494    /*! Requested codec preferences */
00495    struct ast_codec_pref rprefs;
00496    /*! Our call number */
00497    unsigned short callno;
00498    /*! Peer callno */
00499    unsigned short peercallno;
00500    /*! Negotiated format, this is only used to remember what format was
00501        chosen for an unauthenticated call so that the channel can get
00502        created later using the right format */
00503    int chosenformat;
00504    /*! Peer selected format */
00505    int peerformat;
00506    /*! Peer capability */
00507    int peercapability;
00508    /*! timeval that we base our transmission on */
00509    struct timeval offset;
00510    /*! timeval that we base our delivery on */
00511    struct timeval rxcore;
00512    /*! The jitterbuffer */
00513         jitterbuf *jb;
00514    /*! active jb read scheduler id */
00515         int jbid;                       
00516    /*! LAG */
00517    int lag;
00518    /*! Error, as discovered by the manager */
00519    int error;
00520    /*! Owner if we have one */
00521    struct ast_channel *owner;
00522    /*! What's our state? */
00523    struct ast_flags state;
00524    /*! Expiry (optional) */
00525    int expiry;
00526    /*! Next outgoing sequence number */
00527    unsigned char oseqno;
00528    /*! Next sequence number they have not yet acknowledged */
00529    unsigned char rseqno;
00530    /*! Next incoming sequence number */
00531    unsigned char iseqno;
00532    /*! Last incoming sequence number we have acknowledged */
00533    unsigned char aseqno;
00534 
00535    AST_DECLARE_STRING_FIELDS(
00536       /*! Peer name */
00537       AST_STRING_FIELD(peer);
00538       /*! Default Context */
00539       AST_STRING_FIELD(context);
00540       /*! Caller ID if available */
00541       AST_STRING_FIELD(cid_num);
00542       AST_STRING_FIELD(cid_name);
00543       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00544       AST_STRING_FIELD(ani);
00545       /*! DNID */
00546       AST_STRING_FIELD(dnid);
00547       /*! RDNIS */
00548       AST_STRING_FIELD(rdnis);
00549       /*! Requested Extension */
00550       AST_STRING_FIELD(exten);
00551       /*! Expected Username */
00552       AST_STRING_FIELD(username);
00553       /*! Expected Secret */
00554       AST_STRING_FIELD(secret);
00555       /*! MD5 challenge */
00556       AST_STRING_FIELD(challenge);
00557       /*! Public keys permitted keys for incoming authentication */
00558       AST_STRING_FIELD(inkeys);
00559       /*! Private key for outgoing authentication */
00560       AST_STRING_FIELD(outkey);
00561       /*! Preferred language */
00562       AST_STRING_FIELD(language);
00563       /*! Hostname/peername for naming purposes */
00564       AST_STRING_FIELD(host);
00565 
00566       AST_STRING_FIELD(dproot);
00567       AST_STRING_FIELD(accountcode);
00568       AST_STRING_FIELD(mohinterpret);
00569       AST_STRING_FIELD(mohsuggest);
00570    );
00571    
00572    /*! permitted authentication methods */
00573    int authmethods;
00574    /*! permitted encryption methods */
00575    int encmethods;
00576    /*! Encryption AES-128 Key */
00577    aes_encrypt_ctx ecx;
00578    /*! Decryption AES-128 Key */
00579    aes_decrypt_ctx dcx;
00580    /*! 32 bytes of semi-random data */
00581    unsigned char semirand[32];
00582    /*! Associated registry */
00583    struct iax2_registry *reg;
00584    /*! Associated peer for poking */
00585    struct iax2_peer *peerpoke;
00586    /*! IAX_ flags */
00587    unsigned int flags;
00588    int adsi;
00589 
00590    /*! Transferring status */
00591    enum iax_transfer_state transferring;
00592    /*! Transfer identifier */
00593    int transferid;
00594    /*! Who we are IAX transfering to */
00595    struct sockaddr_in transfer;
00596    /*! What's the new call number for the transfer */
00597    unsigned short transfercallno;
00598    /*! Transfer decrypt AES-128 Key */
00599    aes_encrypt_ctx tdcx;
00600 
00601    /*! Status of knowledge of peer ADSI capability */
00602    int peeradsicpe;
00603 
00604    /*! Who we are bridged to */
00605    unsigned short bridgecallno;
00606    
00607    int pingid;       /*!< Transmit PING request */
00608    int lagid;        /*!< Retransmit lag request */
00609    int autoid;       /*!< Auto hangup for Dialplan requestor */
00610    int authid;       /*!< Authentication rejection ID */
00611    int authfail;        /*!< Reason to report failure */
00612    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00613    int calling_ton;
00614    int calling_tns;
00615    int calling_pres;
00616    int amaflags;
00617    struct iax2_dpcache *dpentries;
00618    struct ast_variable *vars;
00619    /*! last received remote rr */
00620    struct iax_rr remote_rr;
00621    /*! Current base time: (just for stats) */
00622    int min;
00623    /*! Dropped frame count: (just for stats) */
00624    int frames_dropped;
00625    /*! received frame count: (just for stats) */
00626    int frames_received;
00627 };
00628 
00629 static struct ast_iax2_queue {
00630    AST_LIST_HEAD(, iax_frame) queue;
00631    int count;
00632 } iaxq;
00633 
00634 /*!
00635  * This module will get much higher performance when doing a lot of
00636  * user and peer lookups if the number of buckets is increased from 1.
00637  * However, to maintain old behavior for Asterisk 1.4, these are set to
00638  * 1 by default.  When using multiple buckets, search order through these
00639  * containers is considered random, so you will not be able to depend on
00640  * the order the entires are specified in iax.conf for matching order. */
00641 #ifdef LOW_MEMORY
00642 #define MAX_PEER_BUCKETS 1
00643 /* #define MAX_PEER_BUCKETS 17 */
00644 #else
00645 #define MAX_PEER_BUCKETS 1
00646 /* #define MAX_PEER_BUCKETS 563 */
00647 #endif
00648 static ao2_container *peers;
00649 
00650 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00651 static ao2_container *users;
00652 
00653 static struct ast_firmware_list {
00654    struct iax_firmware *wares;
00655    ast_mutex_t lock;
00656 } waresl;
00657 
00658 /*! Extension exists */
00659 #define CACHE_FLAG_EXISTS     (1 << 0)
00660 /*! Extension is nonexistent */
00661 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00662 /*! Extension can exist */
00663 #define CACHE_FLAG_CANEXIST      (1 << 2)
00664 /*! Waiting to hear back response */
00665 #define CACHE_FLAG_PENDING    (1 << 3)
00666 /*! Timed out */
00667 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00668 /*! Request transmitted */
00669 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00670 /*! Timeout */
00671 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00672 /*! Matchmore */
00673 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00674 
00675 static struct iax2_dpcache {
00676    char peercontext[AST_MAX_CONTEXT];
00677    char exten[AST_MAX_EXTENSION];
00678    struct timeval orig;
00679    struct timeval expiry;
00680    int flags;
00681    unsigned short callno;
00682    int waiters[256];
00683    struct iax2_dpcache *next;
00684    struct iax2_dpcache *peer; /*!< For linking in peers */
00685 } *dpcache;
00686 
00687 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00688 
00689 static void reg_source_db(struct iax2_peer *p);
00690 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00691 
00692 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00693 
00694 #define IAX_IOSTATE_IDLE      0
00695 #define IAX_IOSTATE_READY     1
00696 #define IAX_IOSTATE_PROCESSING   2
00697 #define IAX_IOSTATE_SCHEDREADY   3
00698 
00699 #define IAX_TYPE_POOL    1
00700 #define IAX_TYPE_DYNAMIC 2
00701 
00702 struct iax2_pkt_buf {
00703    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00704    size_t len;
00705    unsigned char buf[1];
00706 };
00707 
00708 struct iax2_thread {
00709    AST_LIST_ENTRY(iax2_thread) list;
00710    int type;
00711    int iostate;
00712 #ifdef SCHED_MULTITHREADED
00713    void (*schedfunc)(void *);
00714    void *scheddata;
00715 #endif
00716 #ifdef DEBUG_SCHED_MULTITHREAD
00717    char curfunc[80];
00718 #endif   
00719    int actions;
00720    pthread_t threadid;
00721    int threadnum;
00722    struct sockaddr_in iosin;
00723    unsigned char readbuf[4096]; 
00724    unsigned char *buf;
00725    ssize_t buf_len;
00726    size_t buf_size;
00727    int iofd;
00728    time_t checktime;
00729    ast_mutex_t lock;
00730    ast_cond_t cond;
00731    unsigned int ready_for_signal:1;
00732    /*! if this thread is processing a full frame,
00733      some information about that frame will be stored
00734      here, so we can avoid dispatching any more full
00735      frames for that callno to other threads */
00736    struct {
00737       unsigned short callno;
00738       struct sockaddr_in sin;
00739       unsigned char type;
00740       unsigned char csub;
00741    } ffinfo;
00742    /*! Queued up full frames for processing.  If more full frames arrive for
00743     *  a call which this thread is already processing a full frame for, they
00744     *  are queued up here. */
00745    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00746 };
00747 
00748 /* Thread lists */
00749 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00750 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00751 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00752 
00753 static void *iax2_process_thread(void *data);
00754 
00755 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00756 {
00757    ast_mutex_lock(lock);
00758    ast_cond_signal(cond);
00759    ast_mutex_unlock(lock);
00760 }
00761 
00762 static void iax_debug_output(const char *data)
00763 {
00764    if (iaxdebug)
00765       ast_verbose("%s", data);
00766 }
00767 
00768 static void iax_error_output(const char *data)
00769 {
00770    ast_log(LOG_WARNING, "%s", data);
00771 }
00772 
00773 static void jb_error_output(const char *fmt, ...)
00774 {
00775    va_list args;
00776    char buf[1024];
00777 
00778    va_start(args, fmt);
00779    vsnprintf(buf, 1024, fmt, args);
00780    va_end(args);
00781 
00782    ast_log(LOG_ERROR, buf);
00783 }
00784 
00785 static void jb_warning_output(const char *fmt, ...)
00786 {
00787    va_list args;
00788    char buf[1024];
00789 
00790    va_start(args, fmt);
00791    vsnprintf(buf, 1024, fmt, args);
00792    va_end(args);
00793 
00794    ast_log(LOG_WARNING, buf);
00795 }
00796 
00797 static void jb_debug_output(const char *fmt, ...)
00798 {
00799    va_list args;
00800    char buf[1024];
00801 
00802    va_start(args, fmt);
00803    vsnprintf(buf, 1024, fmt, args);
00804    va_end(args);
00805 
00806    ast_verbose(buf);
00807 }
00808 
00809 /* XXX We probably should use a mutex when working with this XXX */
00810 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00811 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
00812 static struct timeval lastused[IAX_MAX_CALLS];
00813 
00814 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);
00815 static int expire_registry(void *data);
00816 static int iax2_answer(struct ast_channel *c);
00817 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00818 static int iax2_devicestate(void *data);
00819 static int iax2_digit_begin(struct ast_channel *c, char digit);
00820 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00821 static int iax2_do_register(struct iax2_registry *reg);
00822 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00823 static int iax2_hangup(struct ast_channel *c);
00824 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00825 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00826 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00827 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00828 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00829 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00830 static int iax2_sendtext(struct ast_channel *c, const char *text);
00831 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00832 static int iax2_transfer(struct ast_channel *c, const char *dest);
00833 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00834 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00835 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00836 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00837 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00838 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00839 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00840 static struct ast_frame *iax2_read(struct ast_channel *c);
00841 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00842 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00843 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00844 static void prune_peers(void);
00845 
00846 static const struct ast_channel_tech iax2_tech = {
00847    .type = "IAX2",
00848    .description = tdesc,
00849    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00850    .properties = AST_CHAN_TP_WANTSJITTER,
00851    .requester = iax2_request,
00852    .devicestate = iax2_devicestate,
00853    .send_digit_begin = iax2_digit_begin,
00854    .send_digit_end = iax2_digit_end,
00855    .send_text = iax2_sendtext,
00856    .send_image = iax2_sendimage,
00857    .send_html = iax2_sendhtml,
00858    .call = iax2_call,
00859    .hangup = iax2_hangup,
00860    .answer = iax2_answer,
00861    .read = iax2_read,
00862    .write = iax2_write,
00863    .write_video = iax2_write,
00864    .indicate = iax2_indicate,
00865    .setoption = iax2_setoption,
00866    .bridge = iax2_bridge,
00867    .transfer = iax2_transfer,
00868    .fixup = iax2_fixup,
00869 };
00870 
00871 /* WARNING: insert_idle_thread should only ever be called within the
00872  * context of an iax2_process_thread() thread.
00873  */
00874 static void insert_idle_thread(struct iax2_thread *thread)
00875 {
00876    if (thread->type == IAX_TYPE_DYNAMIC) {
00877       AST_LIST_LOCK(&dynamic_list);
00878       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00879       AST_LIST_UNLOCK(&dynamic_list);
00880    } else {
00881       AST_LIST_LOCK(&idle_list);
00882       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00883       AST_LIST_UNLOCK(&idle_list);
00884    }
00885 
00886    return;
00887 }
00888 
00889 static struct iax2_thread *find_idle_thread(void)
00890 {
00891    pthread_attr_t attr;
00892    struct iax2_thread *thread = NULL;
00893 
00894    /* Pop the head of the list off */
00895    AST_LIST_LOCK(&idle_list);
00896    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00897    AST_LIST_UNLOCK(&idle_list);
00898 
00899    /* If no idle thread is available from the regular list, try dynamic */
00900    if (thread == NULL) {
00901       AST_LIST_LOCK(&dynamic_list);
00902       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00903       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00904       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00905          /* We need to MAKE a thread! */
00906          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00907             thread->threadnum = iaxdynamicthreadcount;
00908             thread->type = IAX_TYPE_DYNAMIC;
00909             ast_mutex_init(&thread->lock);
00910             ast_cond_init(&thread->cond, NULL);
00911             pthread_attr_init(&attr);
00912             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00913             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00914                free(thread);
00915                thread = NULL;
00916             } else {
00917                /* All went well and the thread is up, so increment our count */
00918                iaxdynamicthreadcount++;
00919                
00920                /* Wait for the thread to be ready before returning it to the caller */
00921                while (!thread->ready_for_signal)
00922                   usleep(1);
00923             }
00924          }
00925       }
00926       AST_LIST_UNLOCK(&dynamic_list);
00927    }
00928 
00929    /* this thread is not processing a full frame (since it is idle),
00930       so ensure that the field for the full frame call number is empty */
00931    if (thread)
00932       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00933 
00934    return thread;
00935 }
00936 
00937 #ifdef SCHED_MULTITHREADED
00938 static int __schedule_action(void (*func)(void *data), void *data, const char *funcname)
00939 {
00940    struct iax2_thread *thread = NULL;
00941    static time_t lasterror;
00942    static time_t t;
00943 
00944    thread = find_idle_thread();
00945 
00946    if (thread != NULL) {
00947       thread->schedfunc = func;
00948       thread->scheddata = data;
00949       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00950 #ifdef DEBUG_SCHED_MULTITHREAD
00951       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00952 #endif
00953       signal_condition(&thread->lock, &thread->cond);
00954       return 0;
00955    }
00956    time(&t);
00957    if (t != lasterror) 
00958       ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
00959    lasterror = t;
00960 
00961    return -1;
00962 }
00963 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00964 #endif
00965 
00966 static int send_ping(void *data);
00967 
00968 static void __send_ping(void *data)
00969 {
00970    int callno = (long)data;
00971    ast_mutex_lock(&iaxsl[callno]);
00972    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00973       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00974       iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data);
00975    }
00976    ast_mutex_unlock(&iaxsl[callno]);
00977 }
00978 
00979 static int send_ping(void *data)
00980 {
00981 #ifdef SCHED_MULTITHREADED
00982    if (schedule_action(__send_ping, data))
00983 #endif      
00984       __send_ping(data);
00985    return 0;
00986 }
00987 
00988 static int get_encrypt_methods(const char *s)
00989 {
00990    int e;
00991    if (!strcasecmp(s, "aes128"))
00992       e = IAX_ENCRYPT_AES128;
00993    else if (ast_true(s))
00994       e = IAX_ENCRYPT_AES128;
00995    else
00996       e = 0;
00997    return e;
00998 }
00999 
01000 static int send_lagrq(void *data);
01001 
01002 static void __send_lagrq(void *data)
01003 {
01004    int callno = (long)data;
01005    /* Ping only if it's real not if it's bridged */
01006    ast_mutex_lock(&iaxsl[callno]);
01007    if (iaxs[callno] && iaxs[callno]->lagid != -1) {
01008       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01009       iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01010    }
01011    ast_mutex_unlock(&iaxsl[callno]);
01012 }
01013 
01014 static int send_lagrq(void *data)
01015 {
01016 #ifdef SCHED_MULTITHREADED
01017    if (schedule_action(__send_lagrq, data))
01018 #endif      
01019       __send_lagrq(data);
01020    return 0;
01021 }
01022 
01023 static unsigned char compress_subclass(int subclass)
01024 {
01025    int x;
01026    int power=-1;
01027    /* If it's 128 or smaller, just return it */
01028    if (subclass < IAX_FLAG_SC_LOG)
01029       return subclass;
01030    /* Otherwise find its power */
01031    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01032       if (subclass & (1 << x)) {
01033          if (power > -1) {
01034             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01035             return 0;
01036          } else
01037             power = x;
01038       }
01039    }
01040    return power | IAX_FLAG_SC_LOG;
01041 }
01042 
01043 static int uncompress_subclass(unsigned char csub)
01044 {
01045    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01046    if (csub & IAX_FLAG_SC_LOG) {
01047       /* special case for 'compressed' -1 */
01048       if (csub == 0xff)
01049          return -1;
01050       else
01051          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01052    }
01053    else
01054       return csub;
01055 }
01056 
01057 /*!
01058  * \note The only member of the peer passed here guaranteed to be set is the name field
01059  */
01060 static int peer_hash_cb(const void *obj, const int flags)
01061 {
01062    const struct iax2_peer *peer = obj;
01063 
01064    return ast_str_hash(peer->name);
01065 }
01066 
01067 /*!
01068  * \note The only member of the peer passed here guaranteed to be set is the name field
01069  */
01070 static int peer_cmp_cb(void *obj, void *arg, int flags)
01071 {
01072    struct iax2_peer *peer = obj, *peer2 = arg;
01073 
01074    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01075 }
01076 
01077 /*!
01078  * \note The only member of the user passed here guaranteed to be set is the name field
01079  */
01080 static int user_hash_cb(const void *obj, const int flags)
01081 {
01082    const struct iax2_user *user = obj;
01083 
01084    return ast_str_hash(user->name);
01085 }
01086 
01087 /*!
01088  * \note The only member of the user passed here guaranteed to be set is the name field
01089  */
01090 static int user_cmp_cb(void *obj, void *arg, int flags)
01091 {
01092    struct iax2_user *user = obj, *user2 = arg;
01093 
01094    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01095 }
01096 
01097 /*!
01098  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01099  *       so do not call it with a pvt lock held.
01100  */
01101 static struct iax2_peer *find_peer(const char *name, int realtime) 
01102 {
01103    struct iax2_peer *peer = NULL;
01104    struct iax2_peer tmp_peer = {
01105       .name = name,
01106    };
01107 
01108    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01109 
01110    /* Now go for realtime if applicable */
01111    if(!peer && realtime)
01112       peer = realtime_peer(name, NULL);
01113 
01114    return peer;
01115 }
01116 
01117 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01118 {
01119    ao2_ref(peer, +1);
01120    return peer;
01121 }
01122 
01123 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01124 {
01125    ao2_ref(peer, -1);
01126    return NULL;
01127 }
01128 
01129 static inline struct iax2_user *user_ref(struct iax2_user *user)
01130 {
01131    ao2_ref(user, +1);
01132    return user;
01133 }
01134 
01135 static inline struct iax2_user *user_unref(struct iax2_user *user)
01136 {
01137    ao2_ref(user, -1);
01138    return NULL;
01139 }
01140 
01141 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01142 {
01143    struct iax2_peer *peer = NULL;
01144    int res = 0;
01145    ao2_iterator i;
01146 
01147    i = ao2_iterator_init(peers, 0);
01148    while ((peer = ao2_iterator_next(&i))) {
01149       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01150           (peer->addr.sin_port == sin.sin_port)) {
01151          ast_copy_string(host, peer->name, len);
01152          peer_unref(peer);
01153          res = 1;
01154          break;
01155       }
01156       peer_unref(peer);
01157    }
01158 
01159    if (!peer) {
01160       peer = realtime_peer(NULL, &sin);
01161       if (peer) {
01162          ast_copy_string(host, peer->name, len);
01163          peer_unref(peer);
01164          res = 1;
01165       }
01166    }
01167 
01168    return res;
01169 }
01170 
01171 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01172 {
01173    struct chan_iax2_pvt *tmp;
01174    jb_conf jbconf;
01175 
01176    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01177       return NULL;
01178 
01179    if (ast_string_field_init(tmp, 32)) {
01180       free(tmp);
01181       tmp = NULL;
01182       return NULL;
01183    }
01184       
01185    tmp->prefs = prefs;
01186    tmp->callno = 0;
01187    tmp->peercallno = 0;
01188    tmp->transfercallno = 0;
01189    tmp->bridgecallno = 0;
01190    tmp->pingid = -1;
01191    tmp->lagid = -1;
01192    tmp->autoid = -1;
01193    tmp->authid = -1;
01194    tmp->initid = -1;
01195 
01196    ast_string_field_set(tmp,exten, "s");
01197    ast_string_field_set(tmp,host, host);
01198 
01199    tmp->jb = jb_new();
01200    tmp->jbid = -1;
01201    jbconf.max_jitterbuf = maxjitterbuffer;
01202    jbconf.resync_threshold = resyncthreshold;
01203    jbconf.max_contig_interp = maxjitterinterps;
01204    jb_setconf(tmp->jb,&jbconf);
01205 
01206    return tmp;
01207 }
01208 
01209 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01210 {
01211    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01212    if (new) {
01213       size_t afdatalen = new->afdatalen;
01214       memcpy(new, fr, sizeof(*new));
01215       iax_frame_wrap(new, &fr->af);
01216       new->afdatalen = afdatalen;
01217       new->data = NULL;
01218       new->datalen = 0;
01219       new->direction = DIRECTION_INGRESS;
01220       new->retrans = -1;
01221    }
01222    return new;
01223 }
01224 
01225 #define NEW_PREVENT  0
01226 #define NEW_ALLOW    1
01227 #define NEW_FORCE    2
01228 
01229 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
01230 {
01231    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01232       (cur->addr.sin_port == sin->sin_port)) {
01233       /* This is the main host */
01234       if ((cur->peercallno == callno) ||
01235          ((dcallno == cur->callno) && !cur->peercallno)) {
01236          /* That's us.  Be sure we keep track of the peer call number */
01237          return 1;
01238       }
01239    }
01240    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01241        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01242       /* We're transferring */
01243       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01244          return 1;
01245    }
01246    return 0;
01247 }
01248 
01249 static void update_max_trunk(void)
01250 {
01251    int max = TRUNK_CALL_START;
01252    int x;
01253    /* XXX Prolly don't need locks here XXX */
01254    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01255       if (iaxs[x])
01256          max = x + 1;
01257    }
01258    maxtrunkcall = max;
01259    if (option_debug && iaxdebug)
01260       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01261 }
01262 
01263 static void update_max_nontrunk(void)
01264 {
01265    int max = 1;
01266    int x;
01267    /* XXX Prolly don't need locks here XXX */
01268    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01269       if (iaxs[x])
01270          max = x + 1;
01271    }
01272    maxnontrunkcall = max;
01273    if (option_debug && iaxdebug)
01274       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01275 }
01276 
01277 static int make_trunk(unsigned short callno, int locked)
01278 {
01279    int x;
01280    int res= 0;
01281    struct timeval now;
01282    if (iaxs[callno]->oseqno) {
01283       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01284       return -1;
01285    }
01286    if (callno & TRUNK_CALL_START) {
01287       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01288       return -1;
01289    }
01290    gettimeofday(&now, NULL);
01291    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01292       ast_mutex_lock(&iaxsl[x]);
01293       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01294          iaxs[x] = iaxs[callno];
01295          iaxs[x]->callno = x;
01296          iaxs[callno] = NULL;
01297          /* Update the two timers that should have been started */
01298          if (iaxs[x]->pingid > -1)
01299             ast_sched_del(sched, iaxs[x]->pingid);
01300          if (iaxs[x]->lagid > -1)
01301             ast_sched_del(sched, iaxs[x]->lagid);
01302          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01303          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01304          if (locked)
01305             ast_mutex_unlock(&iaxsl[callno]);
01306          res = x;
01307          if (!locked)
01308             ast_mutex_unlock(&iaxsl[x]);
01309          break;
01310       }
01311       ast_mutex_unlock(&iaxsl[x]);
01312    }
01313    if (x >= IAX_MAX_CALLS - 1) {
01314       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01315       return -1;
01316    }
01317    ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01318    /* We move this call from a non-trunked to a trunked call */
01319    update_max_trunk();
01320    update_max_nontrunk();
01321    return res;
01322 }
01323 
01324 /*!
01325  * \note Calling this function while holding another pvt lock can cause a deadlock.
01326  */
01327 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd)
01328 {
01329    int res = 0;
01330    int x;
01331    struct timeval now;
01332    char host[80];
01333 
01334    if (new <= NEW_ALLOW) {
01335       /* Look for an existing connection first */
01336       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01337          ast_mutex_lock(&iaxsl[x]);
01338          if (iaxs[x]) {
01339             /* Look for an exact match */
01340             if (match(sin, callno, dcallno, iaxs[x])) {
01341                res = x;
01342             }
01343          }
01344          ast_mutex_unlock(&iaxsl[x]);
01345       }
01346       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01347          ast_mutex_lock(&iaxsl[x]);
01348          if (iaxs[x]) {
01349             /* Look for an exact match */
01350             if (match(sin, callno, dcallno, iaxs[x])) {
01351                res = x;
01352             }
01353          }
01354          ast_mutex_unlock(&iaxsl[x]);
01355       }
01356    }
01357    if ((res < 1) && (new >= NEW_ALLOW)) {
01358       /* It may seem odd that we look through the peer list for a name for
01359        * this *incoming* call.  Well, it is weird.  However, users don't
01360        * have an IP address/port number that we can match against.  So,
01361        * this is just checking for a peer that has that IP/port and
01362        * assuming that we have a user of the same name.  This isn't always
01363        * correct, but it will be changed if needed after authentication. */
01364       if (!iax2_getpeername(*sin, host, sizeof(host)))
01365          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01366       gettimeofday(&now, NULL);
01367       for (x=1;x<TRUNK_CALL_START;x++) {
01368          /* Find first unused call number that hasn't been used in a while */
01369          ast_mutex_lock(&iaxsl[x]);
01370          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01371          ast_mutex_unlock(&iaxsl[x]);
01372       }
01373       /* We've still got lock held if we found a spot */
01374       if (x >= TRUNK_CALL_START) {
01375          ast_log(LOG_WARNING, "No more space\n");
01376          return 0;
01377       }
01378       iaxs[x] = new_iax(sin, host);
01379       update_max_nontrunk();
01380       if (iaxs[x]) {
01381          if (option_debug && iaxdebug)
01382             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01383          iaxs[x]->sockfd = sockfd;
01384          iaxs[x]->addr.sin_port = sin->sin_port;
01385          iaxs[x]->addr.sin_family = sin->sin_family;
01386          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01387          iaxs[x]->peercallno = callno;
01388          iaxs[x]->callno = x;
01389          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01390          iaxs[x]->expiry = min_reg_expire;
01391          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01392          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01393          iaxs[x]->amaflags = amaflags;
01394          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01395          
01396          ast_string_field_set(iaxs[x], accountcode, accountcode);
01397          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01398          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01399       } else {
01400          ast_log(LOG_WARNING, "Out of resources\n");
01401          ast_mutex_unlock(&iaxsl[x]);
01402          return 0;
01403       }
01404       ast_mutex_unlock(&iaxsl[x]);
01405       res = x;
01406    }
01407    return res;
01408 }
01409 
01410 static void iax2_frame_free(struct iax_frame *fr)
01411 {
01412    if (fr->retrans > -1)
01413       ast_sched_del(sched, fr->retrans);
01414    iax_frame_free(fr);
01415 }
01416 
01417 /*!
01418  * \brief Queue a frame to a call's owning asterisk channel
01419  *
01420  * \pre This function assumes that iaxsl[callno] is locked when called.
01421  *
01422  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01423  * was valid before calling it, it may no longer be valid after calling it.
01424  * This function may unlock and lock the mutex associated with this callno,
01425  * meaning that another thread may grab it and destroy the call.
01426  */
01427 static int iax2_queue_frame(int callno, struct ast_frame *f)
01428 {
01429    for (;;) {
01430       if (iaxs[callno] && iaxs[callno]->owner) {
01431          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01432             /* Avoid deadlock by pausing and trying again */
01433             ast_mutex_unlock(&iaxsl[callno]);
01434             usleep(1);
01435             ast_mutex_lock(&iaxsl[callno]);
01436          } else {
01437             ast_queue_frame(iaxs[callno]->owner, f);
01438             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01439             break;
01440          }
01441       } else
01442          break;
01443    }
01444    return 0;
01445 }
01446 
01447 /*!
01448  * \brief Queue a hangup frame on the ast_channel owner
01449  *
01450  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01451  * is active for the given call number.
01452  *
01453  * \pre Assumes lock for callno is already held.
01454  *
01455  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01456  * was valid before calling it, it may no longer be valid after calling it.
01457  * This function may unlock and lock the mutex associated with this callno,
01458  * meaning that another thread may grab it and destroy the call.
01459  */
01460 static int iax2_queue_hangup(int callno)
01461 {
01462    for (;;) {
01463       if (iaxs[callno] && iaxs[callno]->owner) {
01464          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01465             /* Avoid deadlock by pausing and trying again */
01466             ast_mutex_unlock(&iaxsl[callno]);
01467             usleep(1);
01468             ast_mutex_lock(&iaxsl[callno]);
01469          } else {
01470             ast_queue_hangup(iaxs[callno]->owner);
01471             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01472             break;
01473          }
01474       } else
01475          break;
01476    }
01477    return 0;
01478 }
01479 
01480 /*!
01481  * \brief Queue a control frame on the ast_channel owner
01482  *
01483  * This function queues a control frame on the owner of the IAX2 pvt struct that
01484  * is active for the given call number.
01485  *
01486  * \pre Assumes lock for callno is already held.
01487  *
01488  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01489  * was valid before calling it, it may no longer be valid after calling it.
01490  * This function may unlock and lock the mutex associated with this callno,
01491  * meaning that another thread may grab it and destroy the call.
01492  */
01493 static int iax2_queue_control_data(int callno, 
01494    enum ast_control_frame_type control, const void *data, size_t datalen)
01495 {
01496    for (;;) {
01497       if (iaxs[callno] && iaxs[callno]->owner) {
01498          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01499             /* Avoid deadlock by pausing and trying again */
01500             ast_mutex_unlock(&iaxsl[callno]);
01501             usleep(1);
01502             ast_mutex_lock(&iaxsl[callno]);
01503          } else {
01504             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01505             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01506             break;
01507          }
01508       } else
01509          break;
01510    }
01511    return 0;
01512 }
01513 static void destroy_firmware(struct iax_firmware *cur)
01514 {
01515    /* Close firmware */
01516    if (cur->fwh) {
01517       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01518    }
01519    close(cur->fd);
01520    free(cur);
01521 }
01522 
01523 static int try_firmware(char *s)
01524 {
01525    struct stat stbuf;
01526    struct iax_firmware *cur;
01527    int ifd;
01528    int fd;
01529    int res;
01530    
01531    struct ast_iax2_firmware_header *fwh, fwh2;
01532    struct MD5Context md5;
01533    unsigned char sum[16];
01534    unsigned char buf[1024];
01535    int len, chunk;
01536    char *s2;
01537    char *last;
01538    s2 = alloca(strlen(s) + 100);
01539    if (!s2) {
01540       ast_log(LOG_WARNING, "Alloca failed!\n");
01541       return -1;
01542    }
01543    last = strrchr(s, '/');
01544    if (last)
01545       last++;
01546    else
01547       last = s;
01548    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01549    res = stat(s, &stbuf);
01550    if (res < 0) {
01551       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01552       return -1;
01553    }
01554    /* Make sure it's not a directory */
01555    if (S_ISDIR(stbuf.st_mode))
01556       return -1;
01557    ifd = open(s, O_RDONLY);
01558    if (ifd < 0) {
01559       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01560       return -1;
01561    }
01562    fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
01563    if (fd < 0) {
01564       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01565       close(ifd);
01566       return -1;
01567    }
01568    /* Unlink our newly created file */
01569    unlink(s2);
01570    
01571    /* Now copy the firmware into it */
01572    len = stbuf.st_size;
01573    while(len) {
01574       chunk = len;
01575       if (chunk > sizeof(buf))
01576          chunk = sizeof(buf);
01577       res = read(ifd, buf, chunk);
01578       if (res != chunk) {
01579          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01580          close(ifd);
01581          close(fd);
01582          return -1;
01583       }
01584       res = write(fd, buf, chunk);
01585       if (res != chunk) {
01586          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01587          close(ifd);
01588          close(fd);
01589          return -1;
01590       }
01591       len -= chunk;
01592    }
01593    close(ifd);
01594    /* Return to the beginning */
01595    lseek(fd, 0, SEEK_SET);
01596    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01597       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01598       close(fd);
01599       return -1;
01600    }
01601    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01602       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01603       close(fd);
01604       return -1;
01605    }
01606    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01607       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01608       close(fd);
01609       return -1;
01610    }
01611    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01612       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01613       close(fd);
01614       return -1;
01615    }
01616    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01617    if (fwh == (void *) -1) {
01618       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01619       close(fd);
01620       return -1;
01621    }
01622    MD5Init(&md5);
01623    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01624    MD5Final(sum, &md5);
01625    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01626       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01627       munmap((void*)fwh, stbuf.st_size);
01628       close(fd);
01629       return -1;
01630    }
01631    cur = waresl.wares;
01632    while(cur) {
01633       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01634          /* Found a candidate */
01635          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01636             /* The version we have on loaded is older, load this one instead */
01637             break;
01638          /* This version is no newer than what we have.  Don't worry about it.
01639             We'll consider it a proper load anyhow though */
01640          munmap((void*)fwh, stbuf.st_size);
01641          close(fd);
01642          return 0;
01643       }
01644       cur = cur->next;
01645    }
01646    if (!cur) {
01647       /* Allocate a new one and link it */
01648       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01649          cur->fd = -1;
01650          cur->next = waresl.wares;
01651          waresl.wares = cur;
01652       }
01653    }
01654    if (cur) {
01655       if (cur->fwh) {
01656          munmap((void*)cur->fwh, cur->mmaplen);
01657       }
01658       if (cur->fd > -1)
01659          close(cur->fd);
01660       cur->fwh = fwh;
01661       cur->fd = fd;
01662       cur->mmaplen = stbuf.st_size;
01663       cur->dead = 0;
01664    }
01665    return 0;
01666 }
01667 
01668 static int iax_check_version(char *dev)
01669 {
01670    int res = 0;
01671    struct iax_firmware *cur;
01672    if (!ast_strlen_zero(dev)) {
01673       ast_mutex_lock(&waresl.lock);
01674       cur = waresl.wares;
01675       while(cur) {
01676          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01677             res = ntohs(cur->fwh->version);
01678             break;
01679          }
01680          cur = cur->next;
01681       }
01682       ast_mutex_unlock(&waresl.lock);
01683    }
01684    return res;
01685 }
01686 
01687 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01688 {
01689    int res = -1;
01690    unsigned int bs = desc & 0xff;
01691    unsigned int start = (desc >> 8) & 0xffffff;
01692    unsigned int bytes;
01693    struct iax_firmware *cur;
01694    if (!ast_strlen_zero((char *)dev) && bs) {
01695       start *= bs;
01696       ast_mutex_lock(&waresl.lock);
01697       cur = waresl.wares;
01698       while(cur) {
01699          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01700             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01701             if (start < ntohl(cur->fwh->datalen)) {
01702                bytes = ntohl(cur->fwh->datalen) - start;
01703                if (bytes > bs)
01704                   bytes = bs;
01705                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01706             } else {
01707                bytes = 0;
01708                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01709             }
01710             if (bytes == bs)
01711                res = 0;
01712             else
01713                res = 1;
01714             break;
01715          }
01716          cur = cur->next;
01717       }
01718       ast_mutex_unlock(&waresl.lock);
01719    }
01720    return res;
01721 }
01722 
01723 
01724 static void reload_firmware(void)
01725 {
01726    struct iax_firmware *cur, *curl, *curp;
01727    DIR *fwd;
01728    struct dirent *de;
01729    char dir[256];
01730    char fn[256];
01731    /* Mark all as dead */
01732    ast_mutex_lock(&waresl.lock);
01733    cur = waresl.wares;
01734    while(cur) {
01735       cur->dead = 1;
01736       cur = cur->next;
01737    }
01738    /* Now that we've freed them, load the new ones */
01739    snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01740    fwd = opendir(dir);
01741    if (fwd) {
01742       while((de = readdir(fwd))) {
01743          if (de->d_name[0] != '.') {
01744             snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01745             if (!try_firmware(fn)) {
01746                if (option_verbose > 1)
01747                   ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01748             }
01749          }
01750       }
01751       closedir(fwd);
01752    } else 
01753       ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01754 
01755    /* Clean up leftovers */
01756    cur = waresl.wares;
01757    curp = NULL;
01758    while(cur) {
01759       curl = cur;
01760       cur = cur->next;
01761       if (curl->dead) {
01762          if (curp) {
01763             curp->next = cur;
01764          } else {
01765             waresl.wares = cur;
01766          }
01767          destroy_firmware(curl);
01768       } else {
01769          curp = cur;
01770       }
01771    }
01772    ast_mutex_unlock(&waresl.lock);
01773 }
01774 
01775 /*!
01776  * \note This function assumes that iaxsl[callno] is locked when called.
01777  *
01778  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01779  * was valid before calling it, it may no longer be valid after calling it.
01780  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
01781  * associated with this callno, meaning that another thread may grab it and destroy the call.
01782  */
01783 static int __do_deliver(void *data)
01784 {
01785    /* Just deliver the packet by using queueing.  This is called by
01786      the IAX thread with the iaxsl lock held. */
01787    struct iax_frame *fr = data;
01788    fr->retrans = -1;
01789    fr->af.has_timing_info = 0;
01790    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01791       iax2_queue_frame(fr->callno, &fr->af);
01792    /* Free our iax frame */
01793    iax2_frame_free(fr);
01794    /* And don't run again */
01795    return 0;
01796 }
01797 
01798 static int handle_error(void)
01799 {
01800    /* XXX Ideally we should figure out why an error occured and then abort those
01801       rather than continuing to try.  Unfortunately, the published interface does
01802       not seem to work XXX */
01803 #if 0
01804    struct sockaddr_in *sin;
01805    int res;
01806    struct msghdr m;
01807    struct sock_extended_err e;
01808    m.msg_name = NULL;
01809    m.msg_namelen = 0;
01810    m.msg_iov = NULL;
01811    m.msg_control = &e;
01812    m.msg_controllen = sizeof(e);
01813    m.msg_flags = 0;
01814    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01815    if (res < 0)
01816       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01817    else {
01818       if (m.msg_controllen) {
01819          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01820          if (sin) 
01821             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
01822          else
01823             ast_log(LOG_WARNING, "No address detected??\n");
01824       } else {
01825          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01826       }
01827    }
01828 #endif
01829    return 0;
01830 }
01831 
01832 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
01833 {
01834    int res;
01835    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01836                sizeof(*sin));
01837    if (res < 0) {
01838       if (option_debug)
01839          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01840       handle_error();
01841    } else
01842       res = 0;
01843    return res;
01844 }
01845 
01846 static int send_packet(struct iax_frame *f)
01847 {
01848    int res;
01849    int callno;
01850 
01851    if( f == NULL ) {
01852        ast_log(LOG_ERROR, "send_packet( NULL )\n");
01853        ast_backtrace();
01854        return -1;
01855    }
01856    
01857    callno = f->callno;
01858 
01859    /* Don't send if there was an error, but return error instead */
01860    if (!callno || !iaxs[callno] || iaxs[callno]->error)
01861        return -1;
01862    
01863    /* Called with iaxsl held */
01864    if (option_debug > 2 && iaxdebug)
01865       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));
01866    if (f->transfer) {
01867       if (iaxdebug)
01868          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01869       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
01870                sizeof(iaxs[callno]->transfer));
01871    } else {
01872       if (iaxdebug)
01873          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01874       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
01875                sizeof(iaxs[callno]->addr));
01876    }
01877    if (res < 0) {
01878       if (option_debug && iaxdebug)
01879          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01880       handle_error();
01881    } else
01882       res = 0;
01883    return res;
01884 }
01885 
01886 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01887 {
01888    /* Decrement AUTHREQ count if needed */
01889    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01890       struct iax2_user *user;
01891       struct iax2_user tmp_user = {
01892          .name = pvt->username,
01893       };
01894 
01895       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01896       if (user) {
01897          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01898          user_unref(user); 
01899       }
01900 
01901       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01902    }
01903    /* No more pings or lagrq's */
01904    if (pvt->pingid > -1)
01905       ast_sched_del(sched, pvt->pingid);
01906    pvt->pingid = -1;
01907    if (pvt->lagid > -1)
01908       ast_sched_del(sched, pvt->lagid);
01909    pvt->lagid = -1;
01910    if (pvt->autoid > -1)
01911       ast_sched_del(sched, pvt->autoid);
01912    pvt->autoid = -1;
01913    if (pvt->authid > -1)
01914       ast_sched_del(sched, pvt->authid);
01915    pvt->authid = -1;
01916    if (pvt->initid > -1)
01917       ast_sched_del(sched, pvt->initid);
01918    pvt->initid = -1;
01919    if (pvt->jbid > -1)
01920       ast_sched_del(sched, pvt->jbid);
01921    pvt->jbid = -1;
01922 }
01923 
01924 /*!
01925  * \note Since this function calls iax2_queue_hangup(), the pvt struct
01926  *       for the given call number may disappear during its execution.
01927  */
01928 static int iax2_predestroy(int callno)
01929 {
01930    struct ast_channel *c;
01931    struct chan_iax2_pvt *pvt = iaxs[callno];
01932 
01933    if (!pvt)
01934       return -1;
01935    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01936       iax2_destroy_helper(pvt);
01937       ast_set_flag(pvt, IAX_ALREADYGONE); 
01938    }
01939    c = pvt->owner;
01940    if (c) {
01941       c->tech_pvt = NULL;
01942       iax2_queue_hangup(callno);
01943       pvt->owner = NULL;
01944       ast_module_unref(ast_module_info->self);
01945    }
01946    return 0;
01947 }
01948 
01949 static void iax2_destroy(int callno)
01950 {
01951    struct chan_iax2_pvt *pvt;
01952    struct iax_frame *cur;
01953    struct ast_channel *owner;
01954 
01955 retry:
01956    pvt = iaxs[callno];
01957    gettimeofday(&lastused[callno], NULL);
01958    
01959    owner = pvt ? pvt->owner : NULL;
01960 
01961    if (owner) {
01962       if (ast_mutex_trylock(&owner->lock)) {
01963          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01964          ast_mutex_unlock(&iaxsl[callno]);
01965          usleep(1);
01966          ast_mutex_lock(&iaxsl[callno]);
01967          goto retry;
01968       }
01969    }
01970    if (!owner)
01971       iaxs[callno] = NULL;
01972    if (pvt) {
01973       if (!owner)
01974          pvt->owner = NULL;
01975       iax2_destroy_helper(pvt);
01976 
01977       /* Already gone */
01978       ast_set_flag(pvt, IAX_ALREADYGONE); 
01979 
01980       if (owner) {
01981          /* If there's an owner, prod it to give up */
01982          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01983           * because we already hold the owner channel lock. */
01984          ast_queue_hangup(owner);
01985       }
01986 
01987       AST_LIST_LOCK(&iaxq.queue);
01988       AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01989          /* Cancel any pending transmissions */
01990          if (cur->callno == pvt->callno) 
01991             cur->retries = -1;
01992       }
01993       AST_LIST_UNLOCK(&iaxq.queue);
01994 
01995       if (pvt->reg)
01996          pvt->reg->callno = 0;
01997       if (!owner) {
01998          jb_frame frame;
01999          if (pvt->vars) {
02000              ast_variables_destroy(pvt->vars);
02001              pvt->vars = NULL;
02002          }
02003 
02004          while (jb_getall(pvt->jb, &frame) == JB_OK)
02005             iax2_frame_free(frame.data);
02006          jb_destroy(pvt->jb);
02007          /* gotta free up the stringfields */
02008          ast_string_field_free_pools(pvt);
02009          free(pvt);
02010       }
02011    }
02012    if (owner) {
02013       ast_mutex_unlock(&owner->lock);
02014    }
02015    if (callno & 0x4000)
02016       update_max_trunk();
02017 }
02018 
02019 static int update_packet(struct iax_frame *f)
02020 {
02021    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02022    struct ast_iax2_full_hdr *fh = f->data;
02023    /* Mark this as a retransmission */
02024    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02025    /* Update iseqno */
02026    f->iseqno = iaxs[f->callno]->iseqno;
02027    fh->iseqno = f->iseqno;
02028    return 0;
02029 }
02030 
02031 static int attempt_transmit(void *data);
02032 static void __attempt_transmit(void *data)
02033 {
02034    /* Attempt to transmit the frame to the remote peer...
02035       Called without iaxsl held. */
02036    struct iax_frame *f = data;
02037    int freeme=0;
02038    int callno = f->callno;
02039    /* Make sure this call is still active */
02040    if (callno) 
02041       ast_mutex_lock(&iaxsl[callno]);
02042    if (callno && iaxs[callno]) {
02043       if ((f->retries < 0) /* Already ACK'd */ ||
02044           (f->retries >= max_retries) /* Too many attempts */) {
02045             /* Record an error if we've transmitted too many times */
02046             if (f->retries >= max_retries) {
02047                if (f->transfer) {
02048                   /* Transfer timeout */
02049                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02050                } else if (f->final) {
02051                   if (f->final) 
02052                      iax2_destroy(callno);
02053                } else {
02054                   if (iaxs[callno]->owner)
02055                      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);
02056                   iaxs[callno]->error = ETIMEDOUT;
02057                   if (iaxs[callno]->owner) {
02058                      struct ast_frame fr = { 0, };
02059                      /* Hangup the fd */
02060                      fr.frametype = AST_FRAME_CONTROL;
02061                      fr.subclass = AST_CONTROL_HANGUP;
02062                      iax2_queue_frame(callno, &fr); // XXX
02063                      /* Remember, owner could disappear */
02064                      if (iaxs[callno] && iaxs[callno]->owner)
02065                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02066                   } else {
02067                      if (iaxs[callno]->reg) {
02068                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02069                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02070                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02071                      }
02072                      iax2_destroy(callno);
02073                   }
02074                }
02075 
02076             }
02077             freeme++;
02078       } else {
02079          /* Update it if it needs it */
02080          update_packet(f);
02081          /* Attempt transmission */
02082          send_packet(f);
02083          f->retries++;
02084          /* Try again later after 10 times as long */
02085          f->retrytime *= 10;
02086          if (f->retrytime > MAX_RETRY_TIME)
02087             f->retrytime = MAX_RETRY_TIME;
02088          /* Transfer messages max out at one second */
02089          if (f->transfer && (f->retrytime > 1000))
02090             f->retrytime = 1000;
02091          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
02092       }
02093    } else {
02094       /* Make sure it gets freed */
02095       f->retries = -1;
02096       freeme++;
02097    }
02098    if (callno)
02099       ast_mutex_unlock(&iaxsl[callno]);
02100    /* Do not try again */
02101    if (freeme) {
02102       /* Don't attempt delivery, just remove it from the queue */
02103       AST_LIST_LOCK(&iaxq.queue);
02104       AST_LIST_REMOVE(&iaxq.queue, f, list);
02105       iaxq.count--;
02106       AST_LIST_UNLOCK(&iaxq.queue);
02107       f->retrans = -1;
02108       /* Free the IAX frame */
02109       iax2_frame_free(f);
02110    }
02111 }
02112 
02113 static int attempt_transmit(void *data)
02114 {
02115 #ifdef SCHED_MULTITHREADED
02116    if (schedule_action(__attempt_transmit, data))
02117 #endif      
02118       __attempt_transmit(data);
02119    return 0;
02120 }
02121 
02122 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02123 {
02124    struct iax2_peer *peer;
02125 
02126    if (argc != 4)
02127         return RESULT_SHOWUSAGE;
02128    if (!strcmp(argv[3],"all")) {
02129       reload_config();
02130       ast_cli(fd, "OK cache is flushed.\n");
02131    } else if ((peer = find_peer(argv[3], 0))) {
02132       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02133          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02134          expire_registry((void *)peer->name);
02135          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02136       } else {
02137          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02138       }
02139       peer_unref(peer);
02140    } else {
02141       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02142    }
02143    
02144    return RESULT_SUCCESS;
02145 }
02146 
02147 static int iax2_test_losspct(int fd, int argc, char *argv[])
02148 {
02149        if (argc != 4)
02150                return RESULT_SHOWUSAGE;
02151 
02152        test_losspct = atoi(argv[3]);
02153 
02154        return RESULT_SUCCESS;
02155 }
02156 
02157 #ifdef IAXTESTS
02158 static int iax2_test_late(int fd, int argc, char *argv[])
02159 {
02160    if (argc != 4)
02161       return RESULT_SHOWUSAGE;
02162 
02163    test_late = atoi(argv[3]);
02164 
02165    return RESULT_SUCCESS;
02166 }
02167 
02168 static int iax2_test_resync(int fd, int argc, char *argv[])
02169 {
02170    if (argc != 4)
02171       return RESULT_SHOWUSAGE;
02172 
02173    test_resync = atoi(argv[3]);
02174 
02175    return RESULT_SUCCESS;
02176 }
02177 
02178 static int iax2_test_jitter(int fd, int argc, char *argv[])
02179 {
02180    if (argc < 4 || argc > 5)
02181       return RESULT_SHOWUSAGE;
02182 
02183    test_jit = atoi(argv[3]);
02184    if (argc == 5) 
02185       test_jitpct = atoi(argv[4]);
02186 
02187    return RESULT_SUCCESS;
02188 }
02189 #endif /* IAXTESTS */
02190 
02191 /*! \brief  peer_status: Report Peer status in character string */
02192 /*    returns 1 if peer is online, -1 if unmonitored */
02193 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02194 {
02195    int res = 0;
02196    if (peer->maxms) {
02197       if (peer->lastms < 0) {
02198          ast_copy_string(status, "UNREACHABLE", statuslen);
02199       } else if (peer->lastms > peer->maxms) {
02200          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02201          res = 1;
02202       } else if (peer->lastms) {
02203          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02204          res = 1;
02205       } else {
02206          ast_copy_string(status, "UNKNOWN", statuslen);
02207       }
02208    } else { 
02209       ast_copy_string(status, "Unmonitored", statuslen);
02210       res = -1;
02211    }
02212    return res;
02213 }
02214 
02215 /*! \brief Show one peer in detail */
02216 static int iax2_show_peer(int fd, int argc, char *argv[])
02217 {
02218    char status[30];
02219    char cbuf[256];
02220    struct iax2_peer *peer;
02221    char codec_buf[512];
02222    int x = 0, codec = 0, load_realtime = 0;
02223 
02224    if (argc < 4)
02225       return RESULT_SHOWUSAGE;
02226 
02227    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02228 
02229    peer = find_peer(argv[3], load_realtime);
02230    if (peer) {
02231       ast_cli(fd,"\n\n");
02232       ast_cli(fd, "  * Name       : %s\n", peer->name);
02233       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02234       ast_cli(fd, "  Context      : %s\n", peer->context);
02235       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02236       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02237       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02238       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02239       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02240       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));
02241       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02242       ast_cli(fd, "  Username     : %s\n", peer->username);
02243       ast_cli(fd, "  Codecs       : ");
02244       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02245       ast_cli(fd, "%s\n", codec_buf);
02246 
02247       ast_cli(fd, "  Codec Order  : (");
02248       for(x = 0; x < 32 ; x++) {
02249          codec = ast_codec_pref_index(&peer->prefs,x);
02250          if(!codec)
02251             break;
02252          ast_cli(fd, "%s", ast_getformatname(codec));
02253          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02254             ast_cli(fd, "|");
02255       }
02256 
02257       if (!x)
02258          ast_cli(fd, "none");
02259       ast_cli(fd, ")\n");
02260 
02261       ast_cli(fd, "  Status       : ");
02262       peer_status(peer, status, sizeof(status));   
02263       ast_cli(fd, "%s\n",status);
02264       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02265       ast_cli(fd,"\n");
02266       peer_unref(peer);
02267    } else {
02268       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02269       ast_cli(fd,"\n");
02270    }
02271 
02272    return RESULT_SUCCESS;
02273 }
02274 
02275 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02276 {
02277    int which = 0;
02278    struct iax2_peer *peer;
02279    char *res = NULL;
02280    int wordlen = strlen(word);
02281    ao2_iterator i;
02282 
02283    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02284    if (pos != 3)
02285       return NULL;
02286 
02287    i = ao2_iterator_init(peers, 0);
02288    while ((peer = ao2_iterator_next(&i))) {
02289       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02290          res = ast_strdup(peer->name);
02291          peer_unref(peer);
02292          break;
02293       }
02294       peer_unref(peer);
02295    }
02296 
02297    return res;
02298 }
02299 
02300 static int iax2_show_stats(int fd, int argc, char *argv[])
02301 {
02302    struct iax_frame *cur;
02303    int cnt = 0, dead=0, final=0;
02304 
02305    if (argc != 3)
02306       return RESULT_SHOWUSAGE;
02307 
02308    AST_LIST_LOCK(&iaxq.queue);
02309    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02310       if (cur->retries < 0)
02311          dead++;
02312       if (cur->final)
02313          final++;
02314       cnt++;
02315    }
02316    AST_LIST_UNLOCK(&iaxq.queue);
02317 
02318    ast_cli(fd, "    IAX Statistics\n");
02319    ast_cli(fd, "---------------------\n");
02320    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02321    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02322    
02323    return RESULT_SUCCESS;
02324 }
02325 
02326 static int iax2_show_cache(int fd, int argc, char *argv[])
02327 {
02328    struct iax2_dpcache *dp;
02329    char tmp[1024], *pc;
02330    int s;
02331    int x,y;
02332    struct timeval tv;
02333    gettimeofday(&tv, NULL);
02334    ast_mutex_lock(&dpcache_lock);
02335    dp = dpcache;
02336    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02337    while(dp) {
02338       s = dp->expiry.tv_sec - tv.tv_sec;
02339       tmp[0] = '\0';
02340       if (dp->flags & CACHE_FLAG_EXISTS)
02341          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02342       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02343          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02344       if (dp->flags & CACHE_FLAG_CANEXIST)
02345          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02346       if (dp->flags & CACHE_FLAG_PENDING)
02347          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02348       if (dp->flags & CACHE_FLAG_TIMEOUT)
02349          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02350       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02351          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02352       if (dp->flags & CACHE_FLAG_MATCHMORE)
02353          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02354       if (dp->flags & CACHE_FLAG_UNKNOWN)
02355          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02356       /* Trim trailing pipe */
02357       if (!ast_strlen_zero(tmp))
02358          tmp[strlen(tmp) - 1] = '\0';
02359       else
02360          ast_copy_string(tmp, "(none)", sizeof(tmp));
02361       y=0;
02362       pc = strchr(dp->peercontext, '@');
02363       if (!pc)
02364          pc = dp->peercontext;
02365       else
02366          pc++;
02367       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02368          if (dp->waiters[x] > -1)
02369             y++;
02370       if (s > 0)
02371          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02372       else
02373          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02374       dp = dp->next;
02375    }
02376    ast_mutex_unlock(&dpcache_lock);
02377    return RESULT_SUCCESS;
02378 }
02379 
02380 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02381 
02382 static void unwrap_timestamp(struct iax_frame *fr)
02383 {
02384    int x;
02385 
02386    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02387       x = fr->ts - iaxs[fr->callno]->last;
02388       if (x < -50000) {
02389          /* Sudden big jump backwards in timestamp:
02390             What likely happened here is that miniframe timestamp has circled but we haven't
02391             gotten the update from the main packet.  We'll just pretend that we did, and
02392             update the timestamp appropriately. */
02393          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02394          if (option_debug && iaxdebug)
02395             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02396       }
02397       if (x > 50000) {
02398          /* Sudden apparent big jump forwards in timestamp:
02399             What's likely happened is this is an old miniframe belonging to the previous
02400             top-16-bit timestamp that has turned up out of order.
02401             Adjust the timestamp appropriately. */
02402          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02403          if (option_debug && iaxdebug)
02404             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02405       }
02406    }
02407 }
02408 
02409 static int get_from_jb(void *p);
02410 
02411 static void update_jbsched(struct chan_iax2_pvt *pvt)
02412 {
02413    int when;
02414    
02415    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02416    
02417    when = jb_next(pvt->jb) - when;
02418    
02419    if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02420    
02421    if(when <= 0) {
02422       /* XXX should really just empty until when > 0.. */
02423       when = 1;
02424    }
02425    
02426    pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02427    
02428    /* Signal scheduler thread */
02429    signal_condition(&sched_lock, &sched_cond);
02430 }
02431 
02432 static void __get_from_jb(void *p) 
02433 {
02434    int callno = PTR_TO_CALLNO(p);
02435    struct chan_iax2_pvt *pvt = NULL;
02436    struct iax_frame *fr;
02437    jb_frame frame;
02438    int ret;
02439    long now;
02440    long next;
02441    struct timeval tv;
02442    
02443    /* Make sure we have a valid private structure before going on */
02444    ast_mutex_lock(&iaxsl[callno]);
02445    pvt = iaxs[callno];
02446    if (!pvt) {
02447       /* No go! */
02448       ast_mutex_unlock(&iaxsl[callno]);
02449       return;
02450    }
02451     
02452     if( pvt->jb == NULL ) {
02453    ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" );
02454    ast_backtrace();
02455    return;
02456     }
02457 
02458    pvt->jbid = -1;
02459    
02460    gettimeofday(&tv,NULL);
02461    /* round up a millisecond since ast_sched_runq does; */
02462    /* prevents us from spinning while waiting for our now */
02463    /* to catch up with runq's now */
02464    tv.tv_usec += 1000;
02465    
02466    now = ast_tvdiff_ms(tv, pvt->rxcore);
02467    
02468    if(now >= (next = jb_next(pvt->jb))) {
02469       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02470       switch(ret) {
02471       case JB_OK:
02472          fr = frame.data;
02473          __do_deliver(fr);
02474          /* __do_deliver() can cause the call to disappear */
02475          pvt = iaxs[callno];
02476          break;
02477       case JB_INTERP:
02478       {
02479          struct ast_frame af = { 0, };
02480          
02481          /* create an interpolation frame */
02482          af.frametype = AST_FRAME_VOICE;
02483          af.subclass = pvt->voiceformat;
02484          af.samples  = frame.ms * 8;
02485          af.src  = "IAX2 JB interpolation";
02486          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02487          af.offset = AST_FRIENDLY_OFFSET;
02488          
02489          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02490           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02491          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02492             iax2_queue_frame(callno, &af);
02493             /* iax2_queue_frame() could cause the call to disappear */
02494             pvt = iaxs[callno];
02495          }
02496       }
02497          break;
02498       case JB_DROP:
02499          iax2_frame_free(frame.data);
02500          break;
02501       case JB_NOFRAME:
02502       case JB_EMPTY:
02503          /* do nothing */
02504          break;
02505       default:
02506          /* shouldn't happen */
02507          break;
02508       }
02509    }
02510    if (pvt)
02511       update_jbsched(pvt);
02512    ast_mutex_unlock(&iaxsl[callno]);
02513 }
02514 
02515 static int get_from_jb(void *data)
02516 {
02517 #ifdef SCHED_MULTITHREADED
02518    if (schedule_action(__get_from_jb, data))
02519 #endif      
02520       __get_from_jb(data);
02521    return 0;
02522 }
02523 
02524 /*!
02525  * \note This function assumes fr->callno is locked
02526  *
02527  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02528  * was valid before calling it, it may no longer be valid after calling it.
02529  */
02530 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02531 {
02532    int type, len;
02533    int ret;
02534    int needfree = 0;
02535 
02536    /* Attempt to recover wrapped timestamps */
02537    unwrap_timestamp(fr);
02538 
02539    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02540    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02541       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02542    else {
02543 #if 0
02544       ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02545 #endif
02546       fr->af.delivery = ast_tv(0,0);
02547    }
02548 
02549    type = JB_TYPE_CONTROL;
02550    len = 0;
02551 
02552    if(fr->af.frametype == AST_FRAME_VOICE) {
02553       type = JB_TYPE_VOICE;
02554       len = ast_codec_get_samples(&fr->af) / 8;
02555    } else if(fr->af.frametype == AST_FRAME_CNG) {
02556       type = JB_TYPE_SILENCE;
02557    }
02558 
02559    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02560       if (tsout)
02561          *tsout = fr->ts;
02562       __do_deliver(fr);
02563       return -1;
02564    }
02565 
02566    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02567     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02568    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
02569        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
02570        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
02571       jb_frame frame;
02572 
02573       /* deliver any frames in the jb */
02574       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02575          __do_deliver(frame.data);
02576          /* __do_deliver() can make the call disappear */
02577          if (!iaxs[fr->callno])
02578             return -1;
02579       }
02580 
02581       jb_reset(iaxs[fr->callno]->jb);
02582 
02583       if (iaxs[fr->callno]->jbid > -1)
02584          ast_sched_del(sched, iaxs[fr->callno]->jbid);
02585 
02586       iaxs[fr->callno]->jbid = -1;
02587 
02588       /* deliver this frame now */
02589       if (tsout)
02590          *tsout = fr->ts;
02591       __do_deliver(fr);
02592       return -1;
02593    }
02594 
02595    /* insert into jitterbuffer */
02596    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02597    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02598          calc_rxstamp(iaxs[fr->callno],fr->ts));
02599    if (ret == JB_DROP) {
02600       needfree++;
02601    } else if (ret == JB_SCHED) {
02602       update_jbsched(iaxs[fr->callno]);
02603    }
02604    if (tsout)
02605       *tsout = fr->ts;
02606    if (needfree) {
02607       /* Free our iax frame */
02608       iax2_frame_free(fr);
02609       return -1;
02610    }
02611    return 0;
02612 }
02613 
02614 static int iax2_transmit(struct iax_frame *fr)
02615 {
02616    /* Lock the queue and place this packet at the end */
02617    /* By setting this to 0, the network thread will send it for us, and
02618       queue retransmission if necessary */
02619    fr->sentyet = 0;
02620    AST_LIST_LOCK(&iaxq.queue);
02621    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02622    iaxq.count++;
02623    AST_LIST_UNLOCK(&iaxq.queue);
02624    /* Wake up the network and scheduler thread */
02625    if (netthreadid != AST_PTHREADT_NULL)
02626       pthread_kill(netthreadid, SIGURG);
02627    signal_condition(&sched_lock, &sched_cond);
02628    return 0;
02629 }
02630 
02631 
02632 
02633 static int iax2_digit_begin(struct ast_channel *c, char digit)
02634 {
02635    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02636 }
02637 
02638 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02639 {
02640    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02641 }
02642 
02643 static int iax2_sendtext(struct ast_channel *c, const char *text)
02644 {
02645    
02646    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02647       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02648 }
02649 
02650 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02651 {
02652    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02653 }
02654 
02655 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02656 {
02657    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02658 }
02659 
02660 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02661 {
02662    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02663    ast_mutex_lock(&iaxsl[callno]);
02664    if (iaxs[callno])
02665       iaxs[callno]->owner = newchan;
02666    else
02667       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02668    ast_mutex_unlock(&iaxsl[callno]);
02669    return 0;
02670 }
02671 
02672 /*!
02673  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02674  *       so do not call this with a pvt lock held.
02675  */
02676 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02677 {
02678    struct ast_variable *var;
02679    struct ast_variable *tmp;
02680    struct iax2_peer *peer=NULL;
02681    time_t regseconds = 0, nowtime;
02682    int dynamic=0;
02683 
02684    if (peername)
02685       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02686    else {
02687       char porta[25];
02688       sprintf(porta, "%d", ntohs(sin->sin_port));
02689       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02690       if (var) {
02691          /* We'll need the peer name in order to build the structure! */
02692          for (tmp = var; tmp; tmp = tmp->next) {
02693             if (!strcasecmp(tmp->name, "name"))
02694                peername = tmp->value;
02695          }
02696       }
02697    }
02698    if (!var)
02699       return NULL;
02700 
02701    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02702    
02703    if (!peer) {
02704       ast_variables_destroy(var);
02705       return NULL;
02706    }
02707 
02708    for (tmp = var; tmp; tmp = tmp->next) {
02709       /* Make sure it's not a user only... */
02710       if (!strcasecmp(tmp->name, "type")) {
02711          if (strcasecmp(tmp->value, "friend") &&
02712              strcasecmp(tmp->value, "peer")) {
02713             /* Whoops, we weren't supposed to exist! */
02714             peer = peer_unref(peer);
02715             break;
02716          } 
02717       } else if (!strcasecmp(tmp->name, "regseconds")) {
02718          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02719       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02720          inet_aton(tmp->value, &(peer->addr.sin_addr));
02721       } else if (!strcasecmp(tmp->name, "port")) {
02722          peer->addr.sin_port = htons(atoi(tmp->value));
02723       } else if (!strcasecmp(tmp->name, "host")) {
02724          if (!strcasecmp(tmp->value, "dynamic"))
02725             dynamic = 1;
02726       }
02727    }
02728 
02729    ast_variables_destroy(var);
02730 
02731    if (!peer)
02732       return NULL;
02733 
02734    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02735       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02736       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02737          if (peer->expire > -1)
02738             ast_sched_del(sched, peer->expire);
02739          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
02740       }
02741       ao2_link(peers, peer_ref(peer));
02742       if (ast_test_flag(peer, IAX_DYNAMIC))
02743          reg_source_db(peer);
02744    } else {
02745       ast_set_flag(peer, IAX_TEMPONLY);   
02746    }
02747 
02748    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02749       time(&nowtime);
02750       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02751          memset(&peer->addr, 0, sizeof(peer->addr));
02752          realtime_update_peer(peer->name, &peer->addr, 0);
02753          if (option_debug)
02754             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02755                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02756       }
02757       else {
02758          if (option_debug)
02759             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02760                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02761       }
02762    }
02763 
02764    return peer;
02765 }
02766 
02767 static struct iax2_user *realtime_user(const char *username)
02768 {
02769    struct ast_variable *var;
02770    struct ast_variable *tmp;
02771    struct iax2_user *user=NULL;
02772 
02773    var = ast_load_realtime("iaxusers", "name", username, NULL);
02774    if (!var)
02775       return NULL;
02776 
02777    tmp = var;
02778    while(tmp) {
02779       /* Make sure it's not a peer only... */
02780       if (!strcasecmp(tmp->name, "type")) {
02781          if (strcasecmp(tmp->value, "friend") &&
02782              strcasecmp(tmp->value, "user")) {
02783             return NULL;
02784          } 
02785       }
02786       tmp = tmp->next;
02787    }
02788 
02789    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02790 
02791    ast_variables_destroy(var);
02792 
02793    if (!user)
02794       return NULL;
02795 
02796    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02797       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02798       ao2_link(users, user_ref(user));
02799    } else {
02800       ast_set_flag(user, IAX_TEMPONLY);   
02801    }
02802 
02803    return user;
02804 }
02805 
02806 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02807 {
02808    char port[10];
02809    char regseconds[20];
02810    
02811    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02812    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02813    ast_update_realtime("iaxpeers", "name", peername, 
02814       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02815       "regseconds", regseconds, NULL);
02816 }
02817 
02818 struct create_addr_info {
02819    int capability;
02820    unsigned int flags;
02821    int maxtime;
02822    int encmethods;
02823    int found;
02824    int sockfd;
02825    int adsi;
02826    char username[80];
02827    char secret[80];
02828    char outkey[80];
02829    char timezone[80];
02830    char prefs[32];
02831    char context[AST_MAX_CONTEXT];
02832    char peercontext[AST_MAX_CONTEXT];
02833    char mohinterpret[MAX_MUSICCLASS];
02834    char mohsuggest[MAX_MUSICCLASS];
02835 };
02836 
02837 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02838 {
02839    struct ast_hostent ahp;
02840    struct hostent *hp;
02841    struct iax2_peer *peer;
02842    int res = -1;
02843 
02844    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02845    cai->sockfd = defaultsockfd;
02846    cai->maxtime = 0;
02847    sin->sin_family = AF_INET;
02848 
02849    if (!(peer = find_peer(peername, 1))) {
02850       cai->found = 0;
02851 
02852       hp = ast_gethostbyname(peername, &ahp);
02853       if (hp) {
02854          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02855          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02856          /* use global iax prefs for unknown peer/user */
02857          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02858          return 0;
02859       } else {
02860          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02861          return -1;
02862       }
02863    }
02864 
02865    cai->found = 1;
02866    
02867    /* if the peer has no address (current or default), return failure */
02868    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
02869       goto return_unref;
02870 
02871    /* if the peer is being monitored and is currently unreachable, return failure */
02872    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
02873       goto return_unref;
02874 
02875    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02876    cai->maxtime = peer->maxms;
02877    cai->capability = peer->capability;
02878    cai->encmethods = peer->encmethods;
02879    cai->sockfd = peer->sockfd;
02880    cai->adsi = peer->adsi;
02881    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02882    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02883    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02884    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02885    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02886    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02887    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02888    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02889    if (ast_strlen_zero(peer->dbsecret)) {
02890       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02891    } else {
02892       char *family;
02893       char *key = NULL;
02894 
02895       family = ast_strdupa(peer->dbsecret);
02896       key = strchr(family, '/');
02897       if (key)
02898          *key++ = '\0';
02899       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02900          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02901          goto return_unref;
02902       }
02903    }
02904 
02905    if (peer->addr.sin_addr.s_addr) {
02906       sin->sin_addr = peer->addr.sin_addr;
02907       sin->sin_port = peer->addr.sin_port;
02908    } else {
02909       sin->sin_addr = peer->defaddr.sin_addr;
02910       sin->sin_port = peer->defaddr.sin_port;
02911    }
02912 
02913    res = 0;
02914 
02915 return_unref:
02916    peer_unref(peer);
02917 
02918    return res;
02919 }
02920 
02921 static void __auto_congest(void *nothing)
02922 {
02923    int callno = PTR_TO_CALLNO(nothing);
02924    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02925    ast_mutex_lock(&iaxsl[callno]);
02926    if (iaxs[callno]) {
02927       iaxs[callno]->initid = -1;
02928       iax2_queue_frame(callno, &f);
02929       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02930    }
02931    ast_mutex_unlock(&iaxsl[callno]);
02932 }
02933 
02934 static int auto_congest(void *data)
02935 {
02936 #ifdef SCHED_MULTITHREADED
02937    if (schedule_action(__auto_congest, data))
02938 #endif      
02939       __auto_congest(data);
02940    return 0;
02941 }
02942 
02943 static unsigned int iax2_datetime(const char *tz)
02944 {
02945    time_t t;
02946    struct tm tm;
02947    unsigned int tmp;
02948    time(&t);
02949    if (!ast_strlen_zero(tz))
02950       ast_localtime(&t, &tm, tz);
02951    else
02952       ast_localtime(&t, &tm, NULL);
02953    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02954    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02955    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02956    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02957    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02958    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02959    return tmp;
02960 }
02961 
02962 struct parsed_dial_string {
02963    char *username;
02964    char *password;
02965    char *key;
02966    char *peer;
02967    char *port;
02968    char *exten;
02969    char *context;
02970    char *options;
02971 };
02972 
02973 /*!
02974  * \brief Parses an IAX dial string into its component parts.
02975  * \param data the string to be parsed
02976  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
02977  * \return nothing
02978  *
02979  * This function parses the string and fills the structure
02980  * with pointers to its component parts. The input string
02981  * will be modified.
02982  *
02983  * \note This function supports both plaintext passwords and RSA
02984  * key names; if the password string is formatted as '[keyname]',
02985  * then the keyname will be placed into the key field, and the
02986  * password field will be set to NULL.
02987  *
02988  * \note The dial string format is:
02989  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
02990  */
02991 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
02992 {
02993    if (ast_strlen_zero(data))
02994       return;
02995 
02996    pds->peer = strsep(&data, "/");
02997    pds->exten = strsep(&data, "/");
02998    pds->options = data;
02999 
03000    if (pds->exten) {
03001       data = pds->exten;
03002       pds->exten = strsep(&data, "@");
03003       pds->context = data;
03004    }
03005 
03006    if (strchr(pds->peer, '@')) {
03007       data = pds->peer;
03008       pds->username = strsep(&data, "@");
03009       pds->peer = data;
03010    }
03011 
03012    if (pds->username) {
03013       data = pds->username;
03014       pds->username = strsep(&data, ":");
03015       pds->password = data;
03016    }
03017 
03018    data = pds->peer;
03019    pds->peer = strsep(&data, ":");
03020    pds->port = data;
03021 
03022    /* check for a key name wrapped in [] in the secret position, if found,
03023       move it to the key field instead
03024    */
03025    if (pds->password && (pds->password[0] == '[')) {
03026       pds->key = ast_strip_quoted(pds->password, "[", "]");
03027       pds->password = NULL;
03028    }
03029 }
03030 
03031 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03032 {
03033    struct sockaddr_in sin;
03034    char *l=NULL, *n=NULL, *tmpstr;
03035    struct iax_ie_data ied;
03036    char *defaultrdest = "s";
03037    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03038    struct parsed_dial_string pds;
03039    struct create_addr_info cai;
03040 
03041    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03042       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03043       return -1;
03044    }
03045 
03046    memset(&cai, 0, sizeof(cai));
03047    cai.encmethods = iax2_encryption;
03048 
03049    memset(&pds, 0, sizeof(pds));
03050    tmpstr = ast_strdupa(dest);
03051    parse_dial_string(tmpstr, &pds);
03052 
03053    if (!pds.exten)
03054       pds.exten = defaultrdest;
03055 
03056    if (create_addr(pds.peer, &sin, &cai)) {
03057       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03058       return -1;
03059    }
03060 
03061    if (!pds.username && !ast_strlen_zero(cai.username))
03062       pds.username = cai.username;
03063    if (!pds.password && !ast_strlen_zero(cai.secret))
03064       pds.password = cai.secret;
03065    if (!pds.key && !ast_strlen_zero(cai.outkey))
03066       pds.key = cai.outkey;
03067    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03068       pds.context = cai.peercontext;
03069 
03070    /* Keep track of the context for outgoing calls too */
03071    ast_copy_string(c->context, cai.context, sizeof(c->context));
03072 
03073    if (pds.port)
03074       sin.sin_port = htons(atoi(pds.port));
03075 
03076    l = c->cid.cid_num;
03077    n = c->cid.cid_name;
03078 
03079    /* Now build request */ 
03080    memset(&ied, 0, sizeof(ied));
03081 
03082    /* On new call, first IE MUST be IAX version of caller */
03083    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03084    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03085    if (pds.options && strchr(pds.options, 'a')) {
03086       /* Request auto answer */
03087       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03088    }
03089 
03090    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03091 
03092    if (l) {
03093       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03094       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03095    } else {
03096       if (n)
03097          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03098       else
03099          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03100    }
03101 
03102    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03103    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03104 
03105    if (n)
03106       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03107    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03108       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03109 
03110    if (!ast_strlen_zero(c->language))
03111       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03112    if (!ast_strlen_zero(c->cid.cid_dnid))
03113       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03114    if (!ast_strlen_zero(c->cid.cid_rdnis))
03115       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03116 
03117    if (pds.context)
03118       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03119 
03120    if (pds.username)
03121       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03122 
03123    if (cai.encmethods)
03124       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03125 
03126    ast_mutex_lock(&iaxsl[callno]);
03127 
03128    if (!ast_strlen_zero(c->context))
03129       ast_string_field_set(iaxs[callno], context, c->context);
03130 
03131    if (pds.username)
03132       ast_string_field_set(iaxs[callno], username, pds.username);
03133 
03134    iaxs[callno]->encmethods = cai.encmethods;
03135 
03136    iaxs[callno]->adsi = cai.adsi;
03137    
03138    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03139    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03140 
03141    if (pds.key)
03142       ast_string_field_set(iaxs[callno], outkey, pds.key);
03143    if (pds.password)
03144       ast_string_field_set(iaxs[callno], secret, pds.password);
03145 
03146    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03147    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03148    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03149    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03150 
03151    if (iaxs[callno]->maxtime) {
03152       /* Initialize pingtime and auto-congest time */
03153       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03154       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03155    } else if (autokill) {
03156       iaxs[callno]->pingtime = autokill / 2;
03157       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03158    }
03159 
03160    /* send the command using the appropriate socket for this peer */
03161    iaxs[callno]->sockfd = cai.sockfd;
03162 
03163    /* Transmit the string in a "NEW" request */
03164    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03165 
03166    ast_mutex_unlock(&iaxsl[callno]);
03167    ast_setstate(c, AST_STATE_RINGING);
03168    
03169    return 0;
03170 }
03171 
03172 static int iax2_hangup(struct ast_channel *c) 
03173 {
03174    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03175    int alreadygone;
03176    struct iax_ie_data ied;
03177    memset(&ied, 0, sizeof(ied));
03178    ast_mutex_lock(&iaxsl[callno]);
03179    if (callno && iaxs[callno]) {
03180       ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03181       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03182       /* Send the hangup unless we have had a transmission error or are already gone */
03183       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03184       if (!iaxs[callno]->error && !alreadygone) {
03185          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03186          if (!iaxs[callno]) {
03187             ast_mutex_unlock(&iaxsl[callno]);
03188             return 0;
03189          }
03190       }
03191       /* Explicitly predestroy it */
03192       iax2_predestroy(callno);
03193       /* If we were already gone to begin with, destroy us now */
03194       if (alreadygone && iaxs[callno]) {
03195          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03196          iax2_destroy(callno);
03197       }
03198    }
03199    ast_mutex_unlock(&iaxsl[callno]);
03200    if (option_verbose > 2) 
03201       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03202    return 0;
03203 }
03204 
03205 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03206 {
03207    struct ast_option_header *h;
03208    int res;
03209 
03210    switch (option) {
03211    case AST_OPTION_TXGAIN:
03212    case AST_OPTION_RXGAIN:
03213       /* these two cannot be sent, because they require a result */
03214       errno = ENOSYS;
03215       return -1;
03216    default:
03217       if (!(h = ast_malloc(datalen + sizeof(*h))))
03218          return -1;
03219 
03220       h->flag = AST_OPTION_FLAG_REQUEST;
03221       h->option = htons(option);
03222       memcpy(h->data, data, datalen);
03223       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03224                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03225                  datalen + sizeof(*h), -1);
03226       free(h);
03227       return res;
03228    }
03229 }
03230 
03231 static struct ast_frame *iax2_read(struct ast_channel *c) 
03232 {
03233    ast_log(LOG_NOTICE, "I should never be called!\n");
03234    return &ast_null_frame;
03235 }
03236 
03237 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03238 {
03239    int res;
03240    struct iax_ie_data ied0;
03241    struct iax_ie_data ied1;
03242    unsigned int transferid = (unsigned int)ast_random();
03243    memset(&ied0, 0, sizeof(ied0));
03244    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03245    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03246    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03247 
03248    memset(&ied1, 0, sizeof(ied1));
03249    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03250    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03251    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03252    
03253    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03254    if (res)
03255       return -1;
03256    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03257    if (res)
03258       return -1;
03259    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03260    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03261    return 0;
03262 }
03263 
03264 static void lock_both(unsigned short callno0, unsigned short callno1)
03265 {
03266    ast_mutex_lock(&iaxsl[callno0]);
03267    while (ast_mutex_trylock(&iaxsl[callno1])) {
03268       ast_mutex_unlock(&iaxsl[callno0]);
03269       usleep(10);
03270       ast_mutex_lock(&iaxsl[callno0]);
03271    }
03272 }
03273 
03274 static void unlock_both(unsigned short callno0, unsigned short callno1)
03275 {
03276    ast_mutex_unlock(&iaxsl[callno1]);
03277    ast_mutex_unlock(&iaxsl[callno0]);
03278 }
03279 
03280 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)
03281 {
03282    struct ast_channel *cs[3];
03283    struct ast_channel *who, *other;
03284    int to = -1;
03285    int res = -1;
03286    int transferstarted=0;
03287    struct ast_frame *f;
03288    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03289    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03290    struct timeval waittimer = {0, 0}, tv;
03291 
03292    lock_both(callno0, callno1);
03293    if (!iaxs[callno0] || !iaxs[callno1]) {
03294       unlock_both(callno0, callno1);
03295       return AST_BRIDGE_FAILED;
03296    }
03297    /* Put them in native bridge mode */
03298    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03299       iaxs[callno0]->bridgecallno = callno1;
03300       iaxs[callno1]->bridgecallno = callno0;
03301    }
03302    unlock_both(callno0, callno1);
03303 
03304    /* If not, try to bridge until we can execute a transfer, if we can */
03305    cs[0] = c0;
03306    cs[1] = c1;
03307    for (/* ever */;;) {
03308       /* Check in case we got masqueraded into */
03309       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03310          if (option_verbose > 2)
03311             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03312          /* Remove from native mode */
03313          if (c0->tech == &iax2_tech) {
03314             ast_mutex_lock(&iaxsl[callno0]);
03315             iaxs[callno0]->bridgecallno = 0;
03316             ast_mutex_unlock(&iaxsl[callno0]);
03317          }
03318          if (c1->tech == &iax2_tech) {
03319             ast_mutex_lock(&iaxsl[callno1]);
03320             iaxs[callno1]->bridgecallno = 0;
03321             ast_mutex_unlock(&iaxsl[callno1]);
03322          }
03323          return AST_BRIDGE_FAILED_NOWARN;
03324       }
03325       if (c0->nativeformats != c1->nativeformats) {
03326          if (option_verbose > 2) {
03327             char buf0[255];
03328             char buf1[255];
03329             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03330             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03331             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03332          }
03333          /* Remove from native mode */
03334          lock_both(callno0, callno1);
03335          if (iaxs[callno0])
03336             iaxs[callno0]->bridgecallno = 0;
03337          if (iaxs[callno1])
03338             iaxs[callno1]->bridgecallno = 0;
03339          unlock_both(callno0, callno1);
03340          return AST_BRIDGE_FAILED_NOWARN;
03341       }
03342       /* check if transfered and if we really want native bridging */
03343       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03344          /* Try the transfer */
03345          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03346                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03347             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03348          transferstarted = 1;
03349       }
03350       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03351          /* Call has been transferred.  We're no longer involved */
03352          gettimeofday(&tv, NULL);
03353          if (ast_tvzero(waittimer)) {
03354             waittimer = tv;
03355          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03356             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03357             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03358             *fo = NULL;
03359             *rc = c0;
03360             res = AST_BRIDGE_COMPLETE;
03361             break;
03362          }
03363       }
03364       to = 1000;
03365       who = ast_waitfor_n(cs, 2, &to);
03366       if (timeoutms > -1) {
03367          timeoutms -= (1000 - to);
03368          if (timeoutms < 0)
03369             timeoutms = 0;
03370       }
03371       if (!who) {
03372          if (!timeoutms) {
03373             res = AST_BRIDGE_RETRY;
03374             break;
03375          }
03376          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03377             res = AST_BRIDGE_FAILED;
03378             break;
03379          }
03380          continue;
03381       }
03382       f = ast_read(who);
03383       if (!f) {
03384          *fo = NULL;
03385          *rc = who;
03386          res = AST_BRIDGE_COMPLETE;
03387          break;
03388       }
03389       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03390          *fo = f;
03391          *rc = who;
03392          res =  AST_BRIDGE_COMPLETE;
03393          break;
03394       }
03395       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03396       if ((f->frametype == AST_FRAME_VOICE) ||
03397           (f->frametype == AST_FRAME_TEXT) ||
03398           (f->frametype == AST_FRAME_VIDEO) || 
03399           (f->frametype == AST_FRAME_IMAGE) ||
03400           (f->frametype == AST_FRAME_DTMF)) {
03401          /* monitored dtmf take out of the bridge.
03402           * check if we monitor the specific source.
03403           */
03404          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03405          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03406             *rc = who;
03407             *fo = f;
03408             res = AST_BRIDGE_COMPLETE;
03409             /* Remove from native mode */
03410             break;
03411          }
03412          /* everything else goes to the other side */
03413          ast_write(other, f);
03414       }
03415       ast_frfree(f);
03416       /* Swap who gets priority */
03417       cs[2] = cs[0];
03418       cs[0] = cs[1];
03419       cs[1] = cs[2];
03420    }
03421    lock_both(callno0, callno1);
03422    if(iaxs[callno0])
03423       iaxs[callno0]->bridgecallno = 0;
03424    if(iaxs[callno1])
03425       iaxs[callno1]->bridgecallno = 0;
03426    unlock_both(callno0, callno1);
03427    return res;
03428 }
03429 
03430 static int iax2_answer(struct ast_channel *c)
03431 {
03432    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03433    if (option_debug)
03434       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03435    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03436 }
03437 
03438 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03439 {
03440    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03441    struct chan_iax2_pvt *pvt;
03442    int res = 0;
03443 
03444    if (option_debug && iaxdebug)
03445       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03446 
03447    ast_mutex_lock(&iaxsl[callno]);
03448    pvt = iaxs[callno];
03449 
03450    switch (condition) {
03451    case AST_CONTROL_HOLD:
03452       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03453          ast_moh_start(c, data, pvt->mohinterpret);
03454          goto done;
03455       }
03456       break;
03457    case AST_CONTROL_UNHOLD:
03458       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03459          ast_moh_stop(c);
03460          goto done;
03461       }
03462    }
03463 
03464    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03465 
03466 done:
03467    ast_mutex_unlock(&iaxsl[callno]);
03468 
03469    return res;
03470 }
03471    
03472 static int iax2_transfer(struct ast_channel *c, const char *dest)
03473 {
03474    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03475    struct iax_ie_data ied;
03476    char tmp[256], *context;
03477    ast_copy_string(tmp, dest, sizeof(tmp));
03478    context = strchr(tmp, '@');
03479    if (context) {
03480       *context = '\0';
03481       context++;
03482    }
03483    memset(&ied, 0, sizeof(ied));
03484    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03485    if (context)
03486       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03487    if (option_debug)
03488       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03489    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03490 }
03491    
03492 static int iax2_getpeertrunk(struct sockaddr_in sin)
03493 {
03494    struct iax2_peer *peer;
03495    int res = 0;
03496    ao2_iterator i;
03497 
03498    i = ao2_iterator_init(peers, 0);
03499    while ((peer = ao2_iterator_next(&i))) {
03500       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03501           (peer->addr.sin_port == sin.sin_port)) {
03502          res = ast_test_flag(peer, IAX_TRUNK);
03503          peer_unref(peer);
03504          break;
03505       }
03506       peer_unref(peer);
03507    }
03508 
03509    return res;
03510 }
03511 
03512 /*! \brief  Create new call, interface with the PBX core */
03513 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03514 {
03515    struct ast_channel *tmp;
03516    struct chan_iax2_pvt *i;
03517    struct ast_variable *v = NULL;
03518 
03519    if (!(i = iaxs[callno])) {
03520       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03521       return NULL;
03522    }
03523 
03524    /* Don't hold call lock */
03525    ast_mutex_unlock(&iaxsl[callno]);
03526    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);
03527    ast_mutex_lock(&iaxsl[callno]);
03528    if (!tmp)
03529       return NULL;
03530    tmp->tech = &iax2_tech;
03531    /* We can support any format by default, until we get restricted */
03532    tmp->nativeformats = capability;
03533    tmp->readformat = ast_best_codec(capability);
03534    tmp->writeformat = ast_best_codec(capability);
03535    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03536 
03537    /* Don't use ast_set_callerid() here because it will
03538     * generate a NewCallerID event before the NewChannel event */
03539    if (!ast_strlen_zero(i->ani))
03540       tmp->cid.cid_ani = ast_strdup(i->ani);
03541    else
03542       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03543    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03544    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03545    tmp->cid.cid_pres = i->calling_pres;
03546    tmp->cid.cid_ton = i->calling_ton;
03547    tmp->cid.cid_tns = i->calling_tns;
03548    if (!ast_strlen_zero(i->language))
03549       ast_string_field_set(tmp, language, i->language);
03550    if (!ast_strlen_zero(i->accountcode))
03551       ast_string_field_set(tmp, accountcode, i->accountcode);
03552    if (i->amaflags)
03553       tmp->amaflags = i->amaflags;
03554    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03555    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03556    if (i->adsi)
03557       tmp->adsicpe = i->peeradsicpe;
03558    else
03559       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03560    i->owner = tmp;
03561    i->capability = capability;
03562 
03563    for (v = i->vars ; v ; v = v->next)
03564       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03565 
03566    if (state != AST_STATE_DOWN) {
03567       if (ast_pbx_start(tmp)) {
03568          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03569          ast_hangup(tmp);
03570          i->owner = NULL;
03571          return NULL;
03572       }
03573    }
03574 
03575    ast_module_ref(ast_module_info->self);
03576    
03577    return tmp;
03578 }
03579 
03580 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03581 {
03582    unsigned long int mssincetx; /* unsigned to handle overflows */
03583    long int ms, pred;
03584 
03585    tpeer->trunkact = *tv;
03586    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03587    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03588       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03589       tpeer->txtrunktime = *tv;
03590       tpeer->lastsent = 999999;
03591    }
03592    /* Update last transmit time now */
03593    tpeer->lasttxtime = *tv;
03594    
03595    /* Calculate ms offset */
03596    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03597    /* Predict from last value */
03598    pred = tpeer->lastsent + sampms;
03599    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03600       ms = pred;
03601    
03602    /* We never send the same timestamp twice, so fudge a little if we must */
03603    if (ms == tpeer->lastsent)
03604       ms = tpeer->lastsent + 1;
03605    tpeer->lastsent = ms;
03606    return ms;
03607 }
03608 
03609 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03610 {
03611    long ms; /* NOT unsigned */
03612    if (ast_tvzero(iaxs[callno]->rxcore)) {
03613       /* Initialize rxcore time if appropriate */
03614       gettimeofday(&iaxs[callno]->rxcore, NULL);
03615       /* Round to nearest 20ms so traces look pretty */
03616       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03617    }
03618    /* Calculate difference between trunk and channel */
03619    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03620    /* Return as the sum of trunk time and the difference between trunk and real time */
03621    return ms + ts;
03622 }
03623 
03624 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03625 {
03626    int ms;
03627    int voice = 0;
03628    int genuine = 0;
03629    int adjust;
03630    struct timeval *delivery = NULL;
03631 
03632 
03633    /* What sort of frame do we have?: voice is self-explanatory
03634       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03635       non-genuine frames are CONTROL frames [ringing etc], DTMF
03636       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03637       the others need a timestamp slaved to the voice frames so that they go in sequence
03638    */
03639    if (f) {
03640       if (f->frametype == AST_FRAME_VOICE) {
03641          voice = 1;
03642          delivery = &f->delivery;
03643       } else if (f->frametype == AST_FRAME_IAX) {
03644          genuine = 1;
03645       } else if (f->frametype == AST_FRAME_CNG) {
03646          p->notsilenttx = 0;  
03647       }
03648    }
03649    if (ast_tvzero(p->offset)) {
03650       gettimeofday(&p->offset, NULL);
03651       /* Round to nearest 20ms for nice looking traces */
03652       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03653    }
03654    /* If the timestamp is specified, just send it as is */
03655    if (ts)
03656       return ts;
03657    /* If we have a time that the frame arrived, always use it to make our timestamp */
03658    if (delivery && !ast_tvzero(*delivery)) {
03659       ms = ast_tvdiff_ms(*delivery, p->offset);
03660       if (option_debug > 2 && iaxdebug)
03661          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03662    } else {
03663       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03664       if (ms < 0)
03665          ms = 0;
03666       if (voice) {
03667          /* On a voice frame, use predicted values if appropriate */
03668          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03669             /* Adjust our txcore, keeping voice and non-voice synchronized */
03670             /* AN EXPLANATION:
03671                When we send voice, we usually send "calculated" timestamps worked out
03672                on the basis of the number of samples sent. When we send other frames,
03673                we usually send timestamps worked out from the real clock.
03674                The problem is that they can tend to drift out of step because the 
03675                   source channel's clock and our clock may not be exactly at the same rate.
03676                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03677                for this call.  Moving it adjusts timestamps for non-voice frames.
03678                We make the adjustment in the style of a moving average.  Each time we
03679                adjust p->offset by 10% of the difference between our clock-derived
03680                timestamp and the predicted timestamp.  That's why you see "10000"
03681                below even though IAX2 timestamps are in milliseconds.
03682                The use of a moving average avoids offset moving too radically.
03683                Generally, "adjust" roams back and forth around 0, with offset hardly
03684                changing at all.  But if a consistent different starts to develop it
03685                will be eliminated over the course of 10 frames (200-300msecs) 
03686             */
03687             adjust = (ms - p->nextpred);
03688             if (adjust < 0)
03689                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03690             else if (adjust > 0)
03691                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03692 
03693             if (!p->nextpred) {
03694                p->nextpred = ms; /*f->samples / 8;*/
03695                if (p->nextpred <= p->lastsent)
03696                   p->nextpred = p->lastsent + 3;
03697             }
03698             ms = p->nextpred;
03699          } else {
03700                 /* in this case, just use the actual
03701             * time, since we're either way off
03702             * (shouldn't happen), or we're  ending a
03703             * silent period -- and seed the next
03704             * predicted time.  Also, round ms to the
03705             * next multiple of frame size (so our
03706             * silent periods are multiples of
03707             * frame size too) */
03708 
03709             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03710                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03711                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03712 
03713             if (f->samples >= 8) /* check to make sure we dont core dump */
03714             {
03715                int diff = ms % (f->samples / 8);
03716                if (diff)
03717                    ms += f->samples/8 - diff;
03718             }
03719 
03720             p->nextpred = ms;
03721             p->notsilenttx = 1;
03722          }
03723       } else {
03724          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03725             it's a genuine frame */
03726          if (genuine) {
03727             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03728             if (ms <= p->lastsent)
03729                ms = p->lastsent + 3;
03730          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03731             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03732             ms = p->lastsent + 3;
03733          }
03734       }
03735    }
03736    p->lastsent = ms;
03737    if (voice)
03738       p->nextpred = p->nextpred + f->samples / 8;
03739    return ms;
03740 }
03741 
03742 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03743 {
03744    /* Returns where in "receive time" we are.  That is, how many ms
03745       since we received (or would have received) the frame with timestamp 0 */
03746    int ms;
03747 #ifdef IAXTESTS
03748    int jit;
03749 #endif /* IAXTESTS */
03750    /* Setup rxcore if necessary */
03751    if (ast_tvzero(p->rxcore)) {
03752       p->rxcore = ast_tvnow();
03753       if (option_debug && iaxdebug)
03754          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03755                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03756       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03757 #if 1
03758       if (option_debug && iaxdebug)
03759          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03760                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03761 #endif
03762    }
03763 
03764    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03765 #ifdef IAXTESTS
03766    if (test_jit) {
03767       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03768          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03769          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03770             jit = -jit;
03771          ms += jit;
03772       }
03773    }
03774    if (test_late) {
03775       ms += test_late;
03776       test_late = 0;
03777    }
03778 #endif /* IAXTESTS */
03779    return ms;
03780 }
03781 
03782 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03783 {
03784    struct iax2_trunk_peer *tpeer;
03785    
03786    /* Finds and locks trunk peer */
03787    ast_mutex_lock(&tpeerlock);
03788    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03789       /* We don't lock here because tpeer->addr *never* changes */
03790       if (!inaddrcmp(&tpeer->addr, sin)) {
03791          ast_mutex_lock(&tpeer->lock);
03792          break;
03793       }
03794    }
03795    if (!tpeer) {
03796       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03797          ast_mutex_init(&tpeer->lock);
03798          tpeer->lastsent = 9999;
03799          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03800          tpeer->trunkact = ast_tvnow();
03801          ast_mutex_lock(&tpeer->lock);
03802          tpeer->next = tpeers;
03803          tpeer->sockfd = fd;
03804          tpeers = tpeer;
03805 #ifdef SO_NO_CHECK
03806          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03807 #endif
03808          ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03809       }
03810    }
03811    ast_mutex_unlock(&tpeerlock);
03812    return tpeer;
03813 }
03814 
03815 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03816 {
03817    struct ast_frame *f;
03818    struct iax2_trunk_peer *tpeer;
03819    void *tmp, *ptr;
03820    struct ast_iax2_meta_trunk_entry *met;
03821    struct ast_iax2_meta_trunk_mini *mtm;
03822 
03823    f = &fr->af;
03824    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03825    if (tpeer) {
03826       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03827          /* Need to reallocate space */
03828          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03829             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03830                ast_mutex_unlock(&tpeer->lock);
03831                return -1;
03832             }
03833             
03834             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03835             tpeer->trunkdata = tmp;
03836             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);
03837          } else {
03838             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));
03839             ast_mutex_unlock(&tpeer->lock);
03840             return -1;
03841          }
03842       }
03843 
03844       /* Append to meta frame */
03845       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03846       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03847          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03848          mtm->len = htons(f->datalen);
03849          mtm->mini.callno = htons(pvt->callno);
03850          mtm->mini.ts = htons(0xffff & fr->ts);
03851          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03852          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03853       } else {
03854          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03855          /* Store call number and length in meta header */
03856          met->callno = htons(pvt->callno);
03857          met->len = htons(f->datalen);
03858          /* Advance pointers/decrease length past trunk entry header */
03859          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03860          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03861       }
03862       /* Copy actual trunk data */
03863       memcpy(ptr, f->data, f->datalen);
03864       tpeer->trunkdatalen += f->datalen;
03865 
03866       tpeer->calls++;
03867       ast_mutex_unlock(&tpeer->lock);
03868    }
03869    return 0;
03870 }
03871 
03872 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03873 {
03874    aes_encrypt_key128(digest, ecx);
03875    aes_decrypt_key128(digest, dcx);
03876 }
03877 
03878 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03879 {
03880 #if 0
03881    /* Debug with "fake encryption" */
03882    int x;
03883    if (len % 16)
03884       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03885    for (x=0;x<len;x++)
03886       dst[x] = src[x] ^ 0xff;
03887 #else 
03888    unsigned char lastblock[16] = { 0 };
03889    int x;
03890    while(len > 0) {
03891       aes_decrypt(src, dst, dcx);
03892       for (x=0;x<16;x++)
03893          dst[x] ^= lastblock[x];
03894       memcpy(lastblock, src, sizeof(lastblock));
03895       dst += 16;
03896       src += 16;
03897       len -= 16;
03898    }
03899 #endif
03900 }
03901 
03902 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03903 {
03904 #if 0
03905    /* Debug with "fake encryption" */
03906    int x;
03907    if (len % 16)
03908       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03909    for (x=0;x<len;x++)
03910       dst[x] = src[x] ^ 0xff;
03911 #else
03912    unsigned char curblock[16] = { 0 };
03913    int x;
03914    while(len > 0) {
03915       for (x=0;x<16;x++)
03916          curblock[x] ^= src[x];
03917       aes_encrypt(curblock, dst, ecx);
03918       memcpy(curblock, dst, sizeof(curblock)); 
03919       dst += 16;
03920       src += 16;
03921       len -= 16;
03922    }
03923 #endif
03924 }
03925 
03926 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03927 {
03928    int padding;
03929    unsigned char *workspace;
03930 
03931    workspace = alloca(*datalen);
03932    memset(f, 0, sizeof(*f));
03933    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03934       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03935       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03936          return -1;
03937       /* Decrypt */
03938       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03939 
03940       padding = 16 + (workspace[15] & 0xf);
03941       if (option_debug && iaxdebug)
03942          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03943       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03944          return -1;
03945 
03946       *datalen -= padding;
03947       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03948       f->frametype = fh->type;
03949       if (f->frametype == AST_FRAME_VIDEO) {
03950          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03951       } else {
03952          f->subclass = uncompress_subclass(fh->csub);
03953       }
03954    } else {
03955       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03956       if (option_debug && iaxdebug)
03957          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03958       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03959          return -1;
03960       /* Decrypt */
03961       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03962       padding = 16 + (workspace[15] & 0x0f);
03963       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03964          return -1;
03965       *datalen -= padding;
03966       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03967    }
03968    return 0;
03969 }
03970 
03971 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
03972 {
03973    int padding;
03974    unsigned char *workspace;
03975    workspace = alloca(*datalen + 32);
03976    if (!workspace)
03977       return -1;
03978    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03979       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03980       if (option_debug && iaxdebug)
03981          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03982       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03983       padding = 16 + (padding & 0xf);
03984       memcpy(workspace, poo, padding);
03985       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03986       workspace[15] &= 0xf0;
03987       workspace[15] |= (padding & 0xf);
03988       if (option_debug && iaxdebug)
03989          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]);
03990       *datalen += padding;
03991       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03992       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03993          memcpy(poo, workspace + *datalen - 32, 32);
03994    } else {
03995       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03996       if (option_debug && iaxdebug)
03997          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03998       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03999       padding = 16 + (padding & 0xf);
04000       memcpy(workspace, poo, padding);
04001       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04002       workspace[15] &= 0xf0;
04003       workspace[15] |= (padding & 0x0f);
04004       *datalen += padding;
04005       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04006       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04007          memcpy(poo, workspace + *datalen - 32, 32);
04008    }
04009    return 0;
04010 }
04011 
04012 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04013 {
04014    int res=-1;
04015    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04016       /* Search for possible keys, given secrets */
04017       struct MD5Context md5;
04018       unsigned char digest[16];
04019       char *tmppw, *stringp;
04020       
04021       tmppw = ast_strdupa(iaxs[callno]->secret);
04022       stringp = tmppw;
04023       while ((tmppw = strsep(&stringp, ";"))) {
04024          MD5Init(&md5);
04025          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04026          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04027          MD5Final(digest, &md5);
04028          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04029          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04030          if (!res) {
04031             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04032             break;
04033          }
04034       }
04035    } else 
04036       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04037    return res;
04038 }
04039 
04040 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04041 {
04042    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04043       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04044       or delayed, with retransmission */
04045    struct ast_iax2_full_hdr *fh;
04046    struct ast_iax2_mini_hdr *mh;
04047    struct ast_iax2_video_hdr *vh;
04048    struct {
04049       struct iax_frame fr2;
04050       unsigned char buffer[4096];
04051    } frb;
04052    struct iax_frame *fr;
04053    int res;
04054    int sendmini=0;
04055    unsigned int lastsent;
04056    unsigned int fts;
04057 
04058    frb.fr2.afdatalen = sizeof(frb.buffer);
04059 
04060    if (!pvt) {
04061       ast_log(LOG_WARNING, "No private structure for packet?\n");
04062       return -1;
04063    }
04064    
04065    lastsent = pvt->lastsent;
04066 
04067    /* Calculate actual timestamp */
04068    fts = calc_timestamp(pvt, ts, f);
04069 
04070    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04071     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04072     * increment the "predicted timestamps" for voice, if we're predecting */
04073    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04074        return 0;
04075 
04076 
04077    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04078          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04079          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04080       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04081        (f->frametype == AST_FRAME_VOICE) 
04082       /* is a voice frame */ &&
04083       (f->subclass == pvt->svoiceformat) 
04084       /* is the same type */ ) {
04085          /* Force immediate rather than delayed transmission */
04086          now = 1;
04087          /* Mark that mini-style frame is appropriate */
04088          sendmini = 1;
04089    }
04090    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
04091       (f->frametype == AST_FRAME_VIDEO) &&
04092       ((f->subclass & ~0x1) == pvt->svideoformat)) {
04093          now = 1;
04094          sendmini = 1;
04095    }
04096    /* Allocate an iax_frame */
04097    if (now) {
04098       fr = &frb.fr2;
04099    } else
04100       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));
04101    if (!fr) {
04102       ast_log(LOG_WARNING, "Out of memory\n");
04103       return -1;
04104    }
04105    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04106    iax_frame_wrap(fr, f);
04107 
04108    fr->ts = fts;
04109    fr->callno = pvt->callno;
04110    fr->transfer = transfer;
04111    fr->final = final;
04112    if (!sendmini) {
04113       /* We need a full frame */
04114       if (seqno > -1)
04115          fr->oseqno = seqno;
04116       else
04117          fr->oseqno = pvt->oseqno++;
04118       fr->iseqno = pvt->iseqno;
04119       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04120       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04121       fh->ts = htonl(fr->ts);
04122       fh->oseqno = fr->oseqno;
04123       if (transfer) {
04124          fh->iseqno = 0;
04125       } else
04126          fh->iseqno = fr->iseqno;
04127       /* Keep track of the last thing we've acknowledged */
04128       if (!transfer)
04129          pvt->aseqno = fr->iseqno;
04130       fh->type = fr->af.frametype & 0xFF;
04131       if (fr->af.frametype == AST_FRAME_VIDEO)
04132          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04133       else
04134          fh->csub = compress_subclass(fr->af.subclass);
04135       if (transfer) {
04136          fr->dcallno = pvt->transfercallno;
04137       } else
04138          fr->dcallno = pvt->peercallno;
04139       fh->dcallno = htons(fr->dcallno);
04140       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04141       fr->data = fh;
04142       fr->retries = 0;
04143       /* Retry after 2x the ping time has passed */
04144       fr->retrytime = pvt->pingtime * 2;
04145       if (fr->retrytime < MIN_RETRY_TIME)
04146          fr->retrytime = MIN_RETRY_TIME;
04147       if (fr->retrytime > MAX_RETRY_TIME)
04148          fr->retrytime = MAX_RETRY_TIME;
04149       /* Acks' don't get retried */
04150       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04151          fr->retries = -1;
04152       else if (f->frametype == AST_FRAME_VOICE)
04153          pvt->svoiceformat = f->subclass;
04154       else if (f->frametype == AST_FRAME_VIDEO)
04155          pvt->svideoformat = f->subclass & ~0x1;
04156       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04157          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04158             if (iaxdebug) {
04159                if (fr->transfer)
04160                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04161                else
04162                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04163             }
04164             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04165          } else
04166             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04167       }
04168    
04169       if (now) {
04170          res = send_packet(fr);
04171       } else
04172          res = iax2_transmit(fr);
04173    } else {
04174       if (ast_test_flag(pvt, IAX_TRUNK)) {
04175          iax2_trunk_queue(pvt, fr);
04176          res = 0;
04177       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04178          /* Video frame have no sequence number */
04179          fr->oseqno = -1;
04180          fr->iseqno = -1;
04181          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04182          vh->zeros = 0;
04183          vh->callno = htons(0x8000 | fr->callno);
04184          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04185          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04186          fr->data = vh;
04187          fr->retries = -1;
04188          res = send_packet(fr);        
04189       } else {
04190          /* Mini-frames have no sequence number */
04191          fr->oseqno = -1;
04192          fr->iseqno = -1;
04193          /* Mini frame will do */
04194          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04195          mh->callno = htons(fr->callno);
04196          mh->ts = htons(fr->ts & 0xFFFF);
04197          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04198          fr->data = mh;
04199          fr->retries = -1;
04200          if (pvt->transferring == TRANSFER_MEDIAPASS)
04201             fr->transfer = 1;
04202          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04203             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04204                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04205             } else
04206                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04207          }
04208          res = send_packet(fr);
04209       }
04210    }
04211    return res;
04212 }
04213 
04214 static int iax2_show_users(int fd, int argc, char *argv[])
04215 {
04216    regex_t regexbuf;
04217    int havepattern = 0;
04218 
04219 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04220 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04221 
04222    struct iax2_user *user = NULL;
04223    char auth[90];
04224    char *pstr = "";
04225    ao2_iterator i;
04226 
04227    switch (argc) {
04228    case 5:
04229       if (!strcasecmp(argv[3], "like")) {
04230          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04231             return RESULT_SHOWUSAGE;
04232          havepattern = 1;
04233       } else
04234          return RESULT_SHOWUSAGE;
04235    case 3:
04236       break;
04237    default:
04238       return RESULT_SHOWUSAGE;
04239    }
04240 
04241    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04242    i = ao2_iterator_init(users, 0);
04243    for (user = ao2_iterator_next(&i); user; 
04244       user_unref(user), user = ao2_iterator_next(&i)) {
04245       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04246          continue;
04247       
04248       if (!ast_strlen_zero(user->secret)) {
04249          ast_copy_string(auth,user->secret,sizeof(auth));
04250       } else if (!ast_strlen_zero(user->inkeys)) {
04251          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04252       } else
04253          ast_copy_string(auth, "-no secret-", sizeof(auth));
04254       
04255       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04256          pstr = "REQ Only";
04257       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04258          pstr = "Disabled";
04259       else
04260          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04261       
04262       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04263          user->contexts ? user->contexts->context : context,
04264          user->ha ? "Yes" : "No", pstr);
04265    }
04266 
04267    if (havepattern)
04268       regfree(&regexbuf);
04269 
04270    return RESULT_SUCCESS;
04271 #undef FORMAT
04272 #undef FORMAT2
04273 }
04274 
04275 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04276 {
04277    regex_t regexbuf;
04278    int havepattern = 0;
04279    int total_peers = 0;
04280    int online_peers = 0;
04281    int offline_peers = 0;
04282    int unmonitored_peers = 0;
04283    ao2_iterator i;
04284 
04285 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04286 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04287 
04288    struct iax2_peer *peer = NULL;
04289    char name[256];
04290    int registeredonly=0;
04291    char *term = manager ? "\r\n" : "\n";
04292 
04293    switch (argc) {
04294    case 6:
04295       if (!strcasecmp(argv[3], "registered"))
04296          registeredonly = 1;
04297       else
04298          return RESULT_SHOWUSAGE;
04299       if (!strcasecmp(argv[4], "like")) {
04300          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04301             return RESULT_SHOWUSAGE;
04302          havepattern = 1;
04303       } else
04304          return RESULT_SHOWUSAGE;
04305       break;
04306    case 5:
04307       if (!strcasecmp(argv[3], "like")) {
04308          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04309             return RESULT_SHOWUSAGE;
04310          havepattern = 1;
04311       } else
04312          return RESULT_SHOWUSAGE;
04313       break;
04314    case 4:
04315       if (!strcasecmp(argv[3], "registered"))
04316          registeredonly = 1;
04317       else
04318          return RESULT_SHOWUSAGE;
04319       break;
04320    case 3:
04321       break;
04322    default:
04323       return RESULT_SHOWUSAGE;
04324    }
04325 
04326 
04327    if (s)
04328       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04329    else
04330       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04331 
04332    i = ao2_iterator_init(peers, 0);
04333    for (peer = ao2_iterator_next(&i); peer; 
04334       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04335       char nm[20];
04336       char status[20];
04337       char srch[2000];
04338       int retstatus;
04339 
04340       if (registeredonly && !peer->addr.sin_addr.s_addr)
04341          continue;
04342       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04343          continue;
04344 
04345       if (!ast_strlen_zero(peer->username))
04346          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04347       else
04348          ast_copy_string(name, peer->name, sizeof(name));
04349       
04350       retstatus = peer_status(peer, status, sizeof(status));
04351       if (retstatus > 0)
04352          online_peers++;
04353       else if (!retstatus)
04354          offline_peers++;
04355       else
04356          unmonitored_peers++;
04357       
04358       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04359       
04360       snprintf(srch, sizeof(srch), FORMAT, name, 
04361           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04362           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04363           nm,
04364           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04365           peer->encmethods ? "(E)" : "   ", status, term);
04366       
04367       if (s)
04368          astman_append(s, FORMAT, name, 
04369                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04370                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04371                   nm,
04372                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04373                   peer->encmethods ? "(E)" : "   ", status, term);
04374       else
04375          ast_cli(fd, FORMAT, name, 
04376             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04377             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04378             nm,
04379             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04380             peer->encmethods ? "(E)" : "   ", status, term);
04381       total_peers++;
04382    }
04383 
04384    if (s)
04385       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04386    else
04387       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04388 
04389    if (havepattern)
04390       regfree(&regexbuf);
04391 
04392    return RESULT_SUCCESS;
04393 #undef FORMAT
04394 #undef FORMAT2
04395 }
04396 
04397 static int iax2_show_threads(int fd, int argc, char *argv[])
04398 {
04399    struct iax2_thread *thread = NULL;
04400    time_t t;
04401    int threadcount = 0, dynamiccount = 0;
04402    char type;
04403 
04404    if (argc != 3)
04405       return RESULT_SHOWUSAGE;
04406       
04407    ast_cli(fd, "IAX2 Thread Information\n");
04408    time(&t);
04409    ast_cli(fd, "Idle Threads:\n");
04410    AST_LIST_LOCK(&idle_list);
04411    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04412 #ifdef DEBUG_SCHED_MULTITHREAD
04413       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04414          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04415 #else
04416       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04417          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04418 #endif
04419       threadcount++;
04420    }
04421    AST_LIST_UNLOCK(&idle_list);
04422    ast_cli(fd, "Active Threads:\n");
04423    AST_LIST_LOCK(&active_list);
04424    AST_LIST_TRAVERSE(&active_list, thread, list) {
04425       if (thread->type == IAX_TYPE_DYNAMIC)
04426          type = 'D';
04427       else
04428          type = 'P';
04429 #ifdef DEBUG_SCHED_MULTITHREAD
04430       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04431          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04432 #else
04433       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04434          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04435 #endif
04436       threadcount++;
04437    }
04438    AST_LIST_UNLOCK(&active_list);
04439    ast_cli(fd, "Dynamic Threads:\n");
04440         AST_LIST_LOCK(&dynamic_list);
04441         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04442 #ifdef DEBUG_SCHED_MULTITHREAD
04443                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04444                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04445 #else
04446                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04447                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04448 #endif
04449       dynamiccount++;
04450         }
04451         AST_LIST_UNLOCK(&dynamic_list);
04452    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04453    return RESULT_SUCCESS;
04454 }
04455 
04456 static int iax2_show_peers(int fd, int argc, char *argv[])
04457 {
04458    return __iax2_show_peers(0, fd, NULL, argc, argv);
04459 }
04460 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04461 {
04462    ast_cli_netstats(s, -1, 0);
04463    astman_append(s, "\r\n");
04464    return RESULT_SUCCESS;
04465 }
04466 
04467 static int iax2_show_firmware(int fd, int argc, char *argv[])
04468 {
04469 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04470 #if !defined(__FreeBSD__)
04471 #define FORMAT "%-15.15s  %-15d %-15d\n"
04472 #else /* __FreeBSD__ */
04473 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04474 #endif /* __FreeBSD__ */
04475    struct iax_firmware *cur;
04476    if ((argc != 3) && (argc != 4))
04477       return RESULT_SHOWUSAGE;
04478    ast_mutex_lock(&waresl.lock);
04479    
04480    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04481    for (cur = waresl.wares;cur;cur = cur->next) {
04482       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04483          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04484             (int)ntohl(cur->fwh->datalen));
04485    }
04486    ast_mutex_unlock(&waresl.lock);
04487    return RESULT_SUCCESS;
04488 #undef FORMAT
04489 #undef FORMAT2
04490 }
04491 
04492 /* JDG: callback to display iax peers in manager */
04493 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04494 {
04495    char *a[] = { "iax2", "show", "users" };
04496    int ret;
04497    const char *id = astman_get_header(m,"ActionID");
04498 
04499    if (!ast_strlen_zero(id))
04500       astman_append(s, "ActionID: %s\r\n",id);
04501    ret = __iax2_show_peers(1, -1, s, 3, a );
04502    astman_append(s, "\r\n\r\n" );
04503    return ret;
04504 } /* /JDG */
04505 
04506 static char *regstate2str(int regstate)
04507 {
04508    switch(regstate) {
04509    case REG_STATE_UNREGISTERED:
04510       return "Unregistered";
04511    case REG_STATE_REGSENT:
04512       return "Request Sent";
04513    case REG_STATE_AUTHSENT:
04514       return "Auth. Sent";
04515    case REG_STATE_REGISTERED:
04516       return "Registered";
04517    case REG_STATE_REJECTED:
04518       return "Rejected";
04519    case REG_STATE_TIMEOUT:
04520       return "Timeout";
04521    case REG_STATE_NOAUTH:
04522       return "No Authentication";
04523    default:
04524       return "Unknown";
04525    }
04526 }
04527 
04528 static int iax2_show_registry(int fd, int argc, char *argv[])
04529 {
04530 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04531 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04532    struct iax2_registry *reg = NULL;
04533 
04534    char host[80];
04535    char perceived[80];
04536    if (argc != 3)
04537       return RESULT_SHOWUSAGE;
04538    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04539    AST_LIST_LOCK(&registrations);
04540    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04541       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04542       if (reg->us.sin_addr.s_addr) 
04543          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04544       else
04545          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04546       ast_cli(fd, FORMAT, host, 
04547                (reg->dnsmgr) ? "Y" : "N", 
04548                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04549    }
04550    AST_LIST_UNLOCK(&registrations);
04551    return RESULT_SUCCESS;
04552 #undef FORMAT
04553 #undef FORMAT2
04554 }
04555 
04556 static int iax2_show_channels(int fd, int argc, char *argv[])
04557 {
04558 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04559 #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"
04560 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04561    int x;
04562    int numchans = 0;
04563 
04564    if (argc != 3)
04565       return RESULT_SHOWUSAGE;
04566    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04567    for (x=0;x<IAX_MAX_CALLS;x++) {
04568       ast_mutex_lock(&iaxsl[x]);
04569       if (iaxs[x]) {
04570          int lag, jitter, localdelay;
04571          jb_info jbinfo;
04572          
04573          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04574             jb_getinfo(iaxs[x]->jb, &jbinfo);
04575             jitter = jbinfo.jitter;
04576             localdelay = jbinfo.current - jbinfo.min;
04577          } else {
04578             jitter = -1;
04579             localdelay = 0;
04580          }
04581          lag = iaxs[x]->remote_rr.delay;
04582          ast_cli(fd, FORMAT,
04583             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04584             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04585             S_OR(iaxs[x]->username, "(None)"),
04586             iaxs[x]->callno, iaxs[x]->peercallno,
04587             iaxs[x]->oseqno, iaxs[x]->iseqno,
04588             lag,
04589             jitter,
04590             localdelay,
04591             ast_getformatname(iaxs[x]->voiceformat) );
04592          numchans++;
04593       }
04594       ast_mutex_unlock(&iaxsl[x]);
04595    }
04596    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04597    return RESULT_SUCCESS;
04598 #undef FORMAT
04599 #undef FORMAT2
04600 #undef FORMATB
04601 }
04602 
04603 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04604 {
04605    int x;
04606    int numchans = 0;
04607    for (x=0;x<IAX_MAX_CALLS;x++) {
04608       ast_mutex_lock(&iaxsl[x]);
04609       if (iaxs[x]) {
04610          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04611          char *fmt;
04612          jb_info jbinfo;
04613          
04614          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04615             jb_getinfo(iaxs[x]->jb, &jbinfo);
04616             localjitter = jbinfo.jitter;
04617             localdelay = jbinfo.current - jbinfo.min;
04618             locallost = jbinfo.frames_lost;
04619             locallosspct = jbinfo.losspct/1000;
04620             localdropped = jbinfo.frames_dropped;
04621             localooo = jbinfo.frames_ooo;
04622          } else {
04623             localjitter = -1;
04624             localdelay = 0;
04625             locallost = -1;
04626             locallosspct = -1;
04627             localdropped = 0;
04628             localooo = -1;
04629          }
04630          if (limit_fmt)
04631             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04632          else
04633             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04634          if (s)
04635             
04636             astman_append(s, fmt,
04637                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04638                      iaxs[x]->pingtime,
04639                      localjitter, 
04640                      localdelay,
04641                      locallost,
04642                      locallosspct,
04643                      localdropped,
04644                      localooo,
04645                      iaxs[x]->frames_received/1000,
04646                      iaxs[x]->remote_rr.jitter,
04647                      iaxs[x]->remote_rr.delay,
04648                      iaxs[x]->remote_rr.losscnt,
04649                      iaxs[x]->remote_rr.losspct,
04650                      iaxs[x]->remote_rr.dropped,
04651                      iaxs[x]->remote_rr.ooo,
04652                      iaxs[x]->remote_rr.packets/1000);
04653          else
04654             ast_cli(fd, fmt,
04655                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04656                iaxs[x]->pingtime,
04657                localjitter, 
04658                localdelay,
04659                locallost,
04660                locallosspct,
04661                localdropped,
04662                localooo,
04663                iaxs[x]->frames_received/1000,
04664                iaxs[x]->remote_rr.jitter,
04665                iaxs[x]->remote_rr.delay,
04666                iaxs[x]->remote_rr.losscnt,
04667                iaxs[x]->remote_rr.losspct,
04668                iaxs[x]->remote_rr.dropped,
04669                iaxs[x]->remote_rr.ooo,
04670                iaxs[x]->remote_rr.packets/1000
04671                );
04672          numchans++;
04673       }
04674       ast_mutex_unlock(&iaxsl[x]);
04675    }
04676    return numchans;
04677 }
04678 
04679 static int iax2_show_netstats(int fd, int argc, char *argv[])
04680 {
04681    int numchans = 0;
04682    if (argc != 3)
04683       return RESULT_SHOWUSAGE;
04684    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04685    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04686    numchans = ast_cli_netstats(NULL, fd, 1);
04687    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04688    return RESULT_SUCCESS;
04689 }
04690 
04691 static int iax2_do_debug(int fd, int argc, char *argv[])
04692 {
04693    if (argc < 2 || argc > 3)
04694       return RESULT_SHOWUSAGE;
04695    iaxdebug = 1;
04696    ast_cli(fd, "IAX2 Debugging Enabled\n");
04697    return RESULT_SUCCESS;
04698 }
04699 
04700 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04701 {
04702    if (argc < 3 || argc > 4)
04703       return RESULT_SHOWUSAGE;
04704    iaxtrunkdebug = 1;
04705    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04706    return RESULT_SUCCESS;
04707 }
04708 
04709 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04710 {
04711    if (argc < 3 || argc > 4)
04712       return RESULT_SHOWUSAGE;
04713    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04714    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04715    return RESULT_SUCCESS;
04716 }
04717 
04718 static int iax2_no_debug(int fd, int argc, char *argv[])
04719 {
04720    if (argc < 3 || argc > 4)
04721       return RESULT_SHOWUSAGE;
04722    iaxdebug = 0;
04723    ast_cli(fd, "IAX2 Debugging Disabled\n");
04724    return RESULT_SUCCESS;
04725 }
04726 
04727 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04728 {
04729    if (argc < 4 || argc > 5)
04730       return RESULT_SHOWUSAGE;
04731    iaxtrunkdebug = 0;
04732    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04733    return RESULT_SUCCESS;
04734 }
04735 
04736 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04737 {
04738    if (argc < 4 || argc > 5)
04739       return RESULT_SHOWUSAGE;
04740    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04741    jb_debug_output("\n");
04742    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04743    return RESULT_SUCCESS;
04744 }
04745 
04746 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04747 {
04748    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04749    int res = -1;
04750    ast_mutex_lock(&iaxsl[callno]);
04751    if (iaxs[callno]) {
04752    /* If there's an outstanding error, return failure now */
04753       if (!iaxs[callno]->error) {
04754          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04755             res = 0;
04756             /* Don't waste bandwidth sending null frames */
04757          else if (f->frametype == AST_FRAME_NULL)
04758             res = 0;
04759          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04760             res = 0;
04761          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04762             res = 0;
04763          else
04764          /* Simple, just queue for transmission */
04765             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04766       } else {
04767          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04768       }
04769    }
04770    /* If it's already gone, just return */
04771    ast_mutex_unlock(&iaxsl[callno]);
04772    return res;
04773 }
04774 
04775 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04776       int now, int transfer, int final)
04777 {
04778    struct ast_frame f = { 0, };
04779 
04780    f.frametype = type;
04781    f.subclass = command;
04782    f.datalen = datalen;
04783    f.src = __FUNCTION__;
04784    f.data = (void *) data;
04785 
04786    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04787 }
04788 
04789 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04790 {
04791    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04792 }
04793 
04794 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04795 {
04796    int res;
04797    ast_mutex_lock(&iaxsl[callno]);
04798    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04799    ast_mutex_unlock(&iaxsl[callno]);
04800    return res;
04801 }
04802 
04803 /*!
04804  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
04805  *       the pvt struct for the given call number may disappear during its 
04806  *       execution.
04807  */
04808 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)
04809 {
04810    int call_num = i->callno;
04811    /* It is assumed that the callno has already been locked */
04812    iax2_predestroy(i->callno);
04813    if (!iaxs[call_num])
04814       return -1;
04815    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04816 }
04817 
04818 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)
04819 {
04820    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04821 }
04822 
04823 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04824 {
04825    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04826 }
04827 
04828 static int apply_context(struct iax2_context *con, const char *context)
04829 {
04830    while(con) {
04831       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04832          return -1;
04833       con = con->next;
04834    }
04835    return 0;
04836 }
04837 
04838 
04839 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04840 {
04841    /* Start pessimistic */
04842    int res = -1;
04843    int version = 2;
04844    struct iax2_user *user = NULL, *best = NULL;
04845    int bestscore = 0;
04846    int gotcapability = 0;
04847    struct ast_variable *v = NULL, *tmpvar = NULL;
04848    ao2_iterator i;
04849 
04850    if (!iaxs[callno])
04851       return res;
04852    if (ies->called_number)
04853       ast_string_field_set(iaxs[callno], exten, ies->called_number);
04854    if (ies->calling_number) {
04855       ast_shrink_phone_number(ies->calling_number);
04856       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04857    }
04858    if (ies->calling_name)
04859       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04860    if (ies->calling_ani)
04861       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04862    if (ies->dnid)
04863       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04864    if (ies->rdnis)
04865       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04866    if (ies->called_context)
04867       ast_string_field_set(iaxs[callno], context, ies->called_context);
04868    if (ies->language)
04869       ast_string_field_set(iaxs[callno], language, ies->language);
04870    if (ies->username)
04871       ast_string_field_set(iaxs[callno], username, ies->username);
04872    if (ies->calling_ton > -1)
04873       iaxs[callno]->calling_ton = ies->calling_ton;
04874    if (ies->calling_tns > -1)
04875       iaxs[callno]->calling_tns = ies->calling_tns;
04876    if (ies->calling_pres > -1)
04877       iaxs[callno]->calling_pres = ies->calling_pres;
04878    if (ies->format)
04879       iaxs[callno]->peerformat = ies->format;
04880    if (ies->adsicpe)
04881       iaxs[callno]->peeradsicpe = ies->adsicpe;
04882    if (ies->capability) {
04883       gotcapability = 1;
04884       iaxs[callno]->peercapability = ies->capability;
04885    } 
04886    if (ies->version)
04887       version = ies->version;
04888 
04889    /* Use provided preferences until told otherwise for actual preferences */
04890    if(ies->codec_prefs) {
04891       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04892       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04893    }
04894 
04895    if (!gotcapability) 
04896       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04897    if (version > IAX_PROTO_VERSION) {
04898       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04899          ast_inet_ntoa(sin->sin_addr), version);
04900       return res;
04901    }
04902    /* Search the userlist for a compatible entry, and fill in the rest */
04903    i = ao2_iterator_init(users, 0);
04904    while ((user = ao2_iterator_next(&i))) {
04905       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04906          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04907          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04908          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04909               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04910          if (!ast_strlen_zero(iaxs[callno]->username)) {
04911             /* Exact match, stop right now. */
04912             if (best)
04913                user_unref(best);
04914             best = user;
04915             break;
04916          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04917             /* No required authentication */
04918             if (user->ha) {
04919                /* There was host authentication and we passed, bonus! */
04920                if (bestscore < 4) {
04921                   bestscore = 4;
04922                   if (best)
04923                      user_unref(best);
04924                   best = user;
04925                   continue;
04926                }
04927             } else {
04928                /* No host access, but no secret, either, not bad */
04929                if (bestscore < 3) {
04930                   bestscore = 3;
04931                   if (best)
04932                      user_unref(best);
04933                   best = user;
04934                   continue;
04935                }
04936             }
04937          } else {
04938             if (user->ha) {
04939                /* Authentication, but host access too, eh, it's something.. */
04940                if (bestscore < 2) {
04941                   bestscore = 2;
04942                   if (best)
04943                      user_unref(best);
04944                   best = user;
04945                   continue;
04946                }
04947             } else {
04948                /* Authentication and no host access...  This is our baseline */
04949                if (bestscore < 1) {
04950                   bestscore = 1;
04951                   if (best)
04952                      user_unref(best);
04953                   best = user;
04954                   continue;
04955                }
04956             }
04957          }
04958       }
04959       user_unref(user);
04960    }
04961    user = best;
04962    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04963       user = realtime_user(iaxs[callno]->username);
04964       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
04965           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
04966          user = user_unref(user);
04967       }
04968    }
04969    if (user) {
04970       /* We found our match (use the first) */
04971       /* copy vars */
04972       for (v = user->vars ; v ; v = v->next) {
04973          if((tmpvar = ast_variable_new(v->name, v->value))) {
04974             tmpvar->next = iaxs[callno]->vars; 
04975             iaxs[callno]->vars = tmpvar;
04976          }
04977       }
04978       /* If a max AUTHREQ restriction is in place, activate it */
04979       if (user->maxauthreq > 0)
04980          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04981       iaxs[callno]->prefs = user->prefs;
04982       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04983       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04984       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04985       iaxs[callno]->encmethods = user->encmethods;
04986       /* Store the requested username if not specified */
04987       if (ast_strlen_zero(iaxs[callno]->username))
04988          ast_string_field_set(iaxs[callno], username, user->name);
04989       /* Store whether this is a trunked call, too, of course, and move if appropriate */
04990       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04991       iaxs[callno]->capability = user->capability;
04992       /* And use the default context */
04993       if (ast_strlen_zero(iaxs[callno]->context)) {
04994          if (user->contexts)
04995             ast_string_field_set(iaxs[callno], context, user->contexts->context);
04996          else
04997             ast_string_field_set(iaxs[callno], context, context);
04998       }
04999       /* And any input keys */
05000       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05001       /* And the permitted authentication methods */
05002       iaxs[callno]->authmethods = user->authmethods;
05003       iaxs[callno]->adsi = user->adsi;
05004       /* If they have callerid, override the given caller id.  Always store the ANI */
05005       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05006          if (ast_test_flag(user, IAX_HASCALLERID)) {
05007             iaxs[callno]->calling_tns = 0;
05008             iaxs[callno]->calling_ton = 0;
05009             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05010             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05011             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05012          }
05013          if (ast_strlen_zero(iaxs[callno]->ani))
05014             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05015       } else {
05016          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05017       }
05018       if (!ast_strlen_zero(user->accountcode))
05019          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05020       if (!ast_strlen_zero(user->mohinterpret))
05021          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05022       if (!ast_strlen_zero(user->mohsuggest))
05023          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05024       if (user->amaflags)
05025          iaxs[callno]->amaflags = user->amaflags;
05026       if (!ast_strlen_zero(user->language))
05027          ast_string_field_set(iaxs[callno], language, user->language);
05028       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05029       /* Keep this check last */
05030       if (!ast_strlen_zero(user->dbsecret)) {
05031          char *family, *key=NULL;
05032          char buf[80];
05033          family = ast_strdupa(user->dbsecret);
05034          key = strchr(family, '/');
05035          if (key) {
05036             *key = '\0';
05037             key++;
05038          }
05039          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05040             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05041          else
05042             ast_string_field_set(iaxs[callno], secret, buf);
05043       } else
05044          ast_string_field_set(iaxs[callno], secret, user->secret);
05045       res = 0;
05046       user = user_unref(user);
05047    }
05048    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05049    return res;
05050 }
05051 
05052 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05053 {
05054    struct ast_iax2_full_hdr fh;
05055    fh.scallno = htons(src | IAX_FLAG_FULL);
05056    fh.dcallno = htons(dst);
05057    fh.ts = 0;
05058    fh.oseqno = 0;
05059    fh.iseqno = 0;
05060    fh.type = AST_FRAME_IAX;
05061    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05062    if (iaxdebug)
05063        iax_showframe(NULL, &fh, 0, sin, 0);
05064 #if 0
05065    if (option_debug)
05066 #endif   
05067       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05068          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05069    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05070 }
05071 
05072 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05073 {
05074    /* Select exactly one common encryption if there are any */
05075    p->encmethods &= enc;
05076    if (p->encmethods) {
05077       if (p->encmethods & IAX_ENCRYPT_AES128)
05078          p->encmethods = IAX_ENCRYPT_AES128;
05079       else
05080          p->encmethods = 0;
05081    }
05082 }
05083 
05084 /*!
05085  * \pre iaxsl[call_num] is locked
05086  *
05087  * \note Since this function calls send_command_final(), the pvt struct for the given
05088  *       call number may disappear while executing this function.
05089  */
05090 static int authenticate_request(int call_num)
05091 {
05092    struct iax_ie_data ied;
05093    int res = -1, authreq_restrict = 0;
05094    char challenge[10];
05095    struct chan_iax2_pvt *p = iaxs[call_num];
05096 
05097    memset(&ied, 0, sizeof(ied));
05098 
05099    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05100    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05101       struct iax2_user *user, tmp_user = {
05102          .name = p->username, 
05103       };
05104 
05105       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05106       if (user) {
05107          if (user->curauthreq == user->maxauthreq)
05108             authreq_restrict = 1;
05109          else
05110             user->curauthreq++;
05111          user = user_unref(user);
05112       }
05113    }
05114 
05115    /* If the AUTHREQ limit test failed, send back an error */
05116    if (authreq_restrict) {
05117       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05118       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05119       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05120       return 0;
05121    }
05122 
05123    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05124    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05125       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05126       ast_string_field_set(p, challenge, challenge);
05127       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05128       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05129    }
05130    if (p->encmethods)
05131       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05132 
05133    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05134 
05135    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05136 
05137    if (p->encmethods)
05138       ast_set_flag(p, IAX_ENCRYPTED);
05139 
05140    return res;
05141 }
05142 
05143 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05144 {
05145    char requeststr[256];
05146    char md5secret[256] = "";
05147    char secret[256] = "";
05148    char rsasecret[256] = "";
05149    int res = -1; 
05150    int x;
05151    struct iax2_user *user, tmp_user = {
05152       .name = p->username, 
05153    };
05154 
05155    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05156    if (user) {
05157       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05158          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05159          ast_clear_flag(p, IAX_MAXAUTHREQ);
05160       }
05161       ast_string_field_set(p, host, user->name);
05162       user = user_unref(user);
05163    }
05164 
05165    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05166       return res;
05167    if (ies->password)
05168       ast_copy_string(secret, ies->password, sizeof(secret));
05169    if (ies->md5_result)
05170       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05171    if (ies->rsa_result)
05172       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05173    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05174       struct ast_key *key;
05175       char *keyn;
05176       char tmpkey[256];
05177       char *stringp=NULL;
05178       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05179       stringp=tmpkey;
05180       keyn = strsep(&stringp, ":");
05181       while(keyn) {
05182          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05183          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05184             res = 0;
05185             break;
05186          } else if (!key)
05187             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05188          keyn = strsep(&stringp, ":");
05189       }
05190    } else if (p->authmethods & IAX_AUTH_MD5) {
05191       struct MD5Context md5;
05192       unsigned char digest[16];
05193       char *tmppw, *stringp;
05194       
05195       tmppw = ast_strdupa(p->secret);
05196       stringp = tmppw;
05197       while((tmppw = strsep(&stringp, ";"))) {
05198          MD5Init(&md5);
05199          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05200          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05201          MD5Final(digest, &md5);
05202          /* If they support md5, authenticate with it.  */
05203          for (x=0;x<16;x++)
05204             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05205          if (!strcasecmp(requeststr, md5secret)) {
05206             res = 0;
05207             break;
05208          }
05209       }
05210    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05211       if (!strcmp(secret, p->secret))
05212          res = 0;
05213    }
05214    return res;
05215 }
05216 
05217 /*! \brief Verify inbound registration */
05218 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05219 {
05220    char requeststr[256] = "";
05221    char peer[256] = "";
05222    char md5secret[256] = "";
05223    char rsasecret[256] = "";
05224    char secret[256] = "";
05225    struct iax2_peer *p = NULL;
05226    struct ast_key *key;
05227    char *keyn;
05228    int x;
05229    int expire = 0;
05230    int res = -1;
05231 
05232    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05233    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05234    if (ies->username)
05235       ast_copy_string(peer, ies->username, sizeof(peer));
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 (ies->refresh)
05243       expire = ies->refresh;
05244 
05245    if (ast_strlen_zero(peer)) {
05246       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05247       return -1;
05248    }
05249 
05250    /* SLD: first call to lookup peer during registration */
05251    ast_mutex_unlock(&iaxsl[callno]);
05252    p = find_peer(peer, 1);
05253    ast_mutex_lock(&iaxsl[callno]);
05254    if (!p || !iaxs[callno]) {
05255       if (authdebug && !p)
05256          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05257       goto return_unref;
05258    }
05259 
05260    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05261       if (authdebug)
05262          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05263       goto return_unref;
05264    }
05265 
05266    if (!ast_apply_ha(p->ha, sin)) {
05267       if (authdebug)
05268          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05269       goto return_unref;
05270    }
05271    if (!inaddrcmp(&p->addr, sin))
05272       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05273    ast_string_field_set(iaxs[callno], secret, p->secret);
05274    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05275    /* Check secret against what we have on file */
05276    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05277       if (!ast_strlen_zero(p->inkeys)) {
05278          char tmpkeys[256];
05279          char *stringp=NULL;
05280          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05281          stringp=tmpkeys;
05282          keyn = strsep(&stringp, ":");
05283          while(keyn) {
05284             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05285             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05286                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05287                break;
05288             } else if (!key) 
05289                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05290             keyn = strsep(&stringp, ":");
05291          }
05292          if (!keyn) {
05293             if (authdebug)
05294                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05295             goto return_unref;
05296          }
05297       } else {
05298          if (authdebug)
05299             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05300          goto return_unref;
05301       }
05302    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05303       struct MD5Context md5;
05304       unsigned char digest[16];
05305       char *tmppw, *stringp;
05306       
05307       tmppw = ast_strdupa(p->secret);
05308       stringp = tmppw;
05309       while((tmppw = strsep(&stringp, ";"))) {
05310          MD5Init(&md5);
05311          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05312          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05313          MD5Final(digest, &md5);
05314          for (x=0;x<16;x++)
05315             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05316          if (!strcasecmp(requeststr, md5secret)) 
05317             break;
05318       }
05319       if (tmppw) {
05320          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05321       } else {
05322          if (authdebug)
05323             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05324          goto return_unref;
05325       }
05326    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05327       /* They've provided a plain text password and we support that */
05328       if (strcmp(secret, p->secret)) {
05329          if (authdebug)
05330             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05331          goto return_unref;
05332       } else
05333          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05334    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05335       if (authdebug)
05336          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05337       goto return_unref;
05338    }
05339    ast_string_field_set(iaxs[callno], peer, peer);
05340    /* Choose lowest expiry number */
05341    if (expire && (expire < iaxs[callno]->expiry)) 
05342       iaxs[callno]->expiry = expire;
05343 
05344    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05345 
05346    res = 0;
05347 
05348 return_unref:
05349    if (p)
05350       peer_unref(p);
05351 
05352    return res;
05353 }
05354 
05355 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)
05356 {
05357    int res = -1;
05358    int x;
05359    if (!ast_strlen_zero(keyn)) {
05360       if (!(authmethods & IAX_AUTH_RSA)) {
05361          if (ast_strlen_zero(secret)) 
05362             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));
05363       } else if (ast_strlen_zero(challenge)) {
05364          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05365       } else {
05366          char sig[256];
05367          struct ast_key *key;
05368          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05369          if (!key) {
05370             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05371          } else {
05372             if (ast_sign(key, (char*)challenge, sig)) {
05373                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05374                res = -1;
05375             } else {
05376                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05377                res = 0;
05378             }
05379          }
05380       }
05381    } 
05382    /* Fall back */
05383    if (res && !ast_strlen_zero(secret)) {
05384       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05385          struct MD5Context md5;
05386          unsigned char digest[16];
05387          char digres[128];
05388          MD5Init(&md5);
05389          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05390          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05391          MD5Final(digest, &md5);
05392          /* If they support md5, authenticate with it.  */
05393          for (x=0;x<16;x++)
05394             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05395          if (ecx && dcx)
05396             build_enc_keys(digest, ecx, dcx);
05397          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05398          res = 0;
05399       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05400          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05401          res = 0;
05402       } else
05403          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05404    }
05405    return res;
05406 }
05407 
05408 /*!
05409  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05410  *       so do not call this function with a pvt lock held.
05411  */
05412 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05413 {
05414    struct iax2_peer *peer = NULL;
05415    /* Start pessimistic */
05416    int res = -1;
05417    int authmethods = 0;
05418    struct iax_ie_data ied;
05419    uint16_t callno = p->callno;
05420 
05421    memset(&ied, 0, sizeof(ied));
05422    
05423    if (ies->username)
05424       ast_string_field_set(p, username, ies->username);
05425    if (ies->challenge)
05426       ast_string_field_set(p, challenge, ies->challenge);
05427    if (ies->authmethods)
05428       authmethods = ies->authmethods;
05429    if (authmethods & IAX_AUTH_MD5)
05430       merge_encryption(p, ies->encmethods);
05431    else
05432       p->encmethods = 0;
05433 
05434    /* Check for override RSA authentication first */
05435    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05436       /* Normal password authentication */
05437       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05438    } else {
05439       ao2_iterator i = ao2_iterator_init(peers, 0);
05440       while ((peer = ao2_iterator_next(&i))) {
05441          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05442              /* No peer specified at our end, or this is the peer */
05443              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05444              /* No username specified in peer rule, or this is the right username */
05445              && (!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)))
05446              /* No specified host, or this is our host */
05447             ) {
05448             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05449             if (!res) {
05450                peer_unref(peer);
05451                break;
05452             }
05453          }
05454          peer_unref(peer);
05455       }
05456       if (!peer) {
05457          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05458             that we're trying to authenticate *to* a realtime peer */
05459          const char *peer_name = ast_strdupa(p->peer);
05460          ast_mutex_unlock(&iaxsl[callno]);
05461          if ((peer = realtime_peer(peer_name, NULL))) {
05462             ast_mutex_lock(&iaxsl[callno]);
05463             if (!(p = iaxs[callno])) {
05464                peer_unref(peer);
05465                return -1;
05466             }
05467             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05468             peer_unref(peer);
05469          }
05470          if (!peer) {
05471             ast_mutex_lock(&iaxsl[callno]);
05472             if (!(p = iaxs[callno]))
05473                return -1;
05474          }
05475       }
05476    }
05477    if (ies->encmethods)
05478       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05479    if (!res)
05480       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05481    return res;
05482 }
05483 
05484 static int iax2_do_register(struct iax2_registry *reg);
05485 
05486 static void __iax2_do_register_s(void *data)
05487 {
05488    struct iax2_registry *reg = data;
05489    reg->expire = -1;
05490    iax2_do_register(reg);
05491 }
05492 
05493 static int iax2_do_register_s(void *data)
05494 {
05495 #ifdef SCHED_MULTITHREADED
05496    if (schedule_action(__iax2_do_register_s, data))
05497 #endif      
05498       __iax2_do_register_s(data);
05499    return 0;
05500 }
05501 
05502 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05503 {
05504    int newcall = 0;
05505    char newip[256];
05506    struct iax_ie_data ied;
05507    struct sockaddr_in new;
05508    
05509    
05510    memset(&ied, 0, sizeof(ied));
05511    if (ies->apparent_addr)
05512       bcopy(ies->apparent_addr, &new, sizeof(new));
05513    if (ies->callno)
05514       newcall = ies->callno;
05515    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05516       ast_log(LOG_WARNING, "Invalid transfer request\n");
05517       return -1;
05518    }
05519    pvt->transfercallno = newcall;
05520    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05521    inet_aton(newip, &pvt->transfer.sin_addr);
05522    pvt->transfer.sin_family = AF_INET;
05523    pvt->transferring = TRANSFER_BEGIN;
05524    pvt->transferid = ies->transferid;
05525    if (ies->transferid)
05526       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05527    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05528    return 0; 
05529 }
05530 
05531 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05532 {
05533    char exten[256] = "";
05534    int status = CACHE_FLAG_UNKNOWN;
05535    int expiry = iaxdefaultdpcache;
05536    int x;
05537    int matchmore = 0;
05538    struct iax2_dpcache *dp, *prev;
05539    
05540    if (ies->called_number)
05541       ast_copy_string(exten, ies->called_number, sizeof(exten));
05542 
05543    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05544       status = CACHE_FLAG_EXISTS;
05545    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05546       status = CACHE_FLAG_CANEXIST;
05547    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05548       status = CACHE_FLAG_NONEXISTENT;
05549 
05550    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05551       /* Don't really do anything with this */
05552    }
05553    if (ies->refresh)
05554       expiry = ies->refresh;
05555    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05556       matchmore = CACHE_FLAG_MATCHMORE;
05557    ast_mutex_lock(&dpcache_lock);
05558    prev = NULL;
05559    dp = pvt->dpentries;
05560    while(dp) {
05561       if (!strcmp(dp->exten, exten)) {
05562          /* Let them go */
05563          if (prev)
05564             prev->peer = dp->peer;
05565          else
05566             pvt->dpentries = dp->peer;
05567          dp->peer = NULL;
05568          dp->callno = 0;
05569          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05570          if (dp->flags & CACHE_FLAG_PENDING) {
05571             dp->flags &= ~CACHE_FLAG_PENDING;
05572             dp->flags |= status;
05573             dp->flags |= matchmore;
05574          }
05575          /* Wake up waiters */
05576          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05577             if (dp->waiters[x] > -1)
05578                write(dp->waiters[x], "asdf", 4);
05579       }
05580       prev = dp;
05581       dp = dp->peer;
05582    }
05583    ast_mutex_unlock(&dpcache_lock);
05584    return 0;
05585 }
05586 
05587 static int complete_transfer(int callno, struct iax_ies *ies)
05588 {
05589    int peercallno = 0;
05590    struct chan_iax2_pvt *pvt = iaxs[callno];
05591    struct iax_frame *cur;
05592    jb_frame frame;
05593 
05594    if (ies->callno)
05595       peercallno = ies->callno;
05596 
05597    if (peercallno < 1) {
05598       ast_log(LOG_WARNING, "Invalid transfer request\n");
05599       return -1;
05600    }
05601    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05602    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05603    /* Reset sequence numbers */
05604    pvt->oseqno = 0;
05605    pvt->rseqno = 0;
05606    pvt->iseqno = 0;
05607    pvt->aseqno = 0;
05608    pvt->peercallno = peercallno;
05609    pvt->transferring = TRANSFER_NONE;
05610    pvt->svoiceformat = -1;
05611    pvt->voiceformat = 0;
05612    pvt->svideoformat = -1;
05613    pvt->videoformat = 0;
05614    pvt->transfercallno = -1;
05615    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05616    memset(&pvt->offset, 0, sizeof(pvt->offset));
05617    /* reset jitterbuffer */
05618    while(jb_getall(pvt->jb,&frame) == JB_OK)
05619       iax2_frame_free(frame.data);
05620    jb_reset(pvt->jb);
05621    pvt->lag = 0;
05622    pvt->last = 0;
05623    pvt->lastsent = 0;
05624    pvt->nextpred = 0;
05625    pvt->pingtime = DEFAULT_RETRY_TIME;
05626    AST_LIST_LOCK(&iaxq.queue);
05627    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05628       /* We must cancel any packets that would have been transmitted
05629          because now we're talking to someone new.  It's okay, they
05630          were transmitted to someone that didn't care anyway. */
05631       if (callno == cur->callno) 
05632          cur->retries = -1;
05633    }
05634    AST_LIST_UNLOCK(&iaxq.queue);
05635    return 0; 
05636 }
05637 
05638 /*! \brief Acknowledgment received for OUR registration */
05639 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05640 {
05641    struct iax2_registry *reg;
05642    /* Start pessimistic */
05643    char peer[256] = "";
05644    char msgstatus[60];
05645    int refresh = 60;
05646    char ourip[256] = "<Unspecified>";
05647    struct sockaddr_in oldus;
05648    struct sockaddr_in us;
05649    int oldmsgs;
05650 
05651    memset(&us, 0, sizeof(us));
05652    if (ies->apparent_addr)
05653       bcopy(ies->apparent_addr, &us, sizeof(us));
05654    if (ies->username)
05655       ast_copy_string(peer, ies->username, sizeof(peer));
05656    if (ies->refresh)
05657       refresh = ies->refresh;
05658    if (ies->calling_number) {
05659       /* We don't do anything with it really, but maybe we should */
05660    }
05661    reg = iaxs[callno]->reg;
05662    if (!reg) {
05663       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05664       return -1;
05665    }
05666    memcpy(&oldus, &reg->us, sizeof(oldus));
05667    oldmsgs = reg->messages;
05668    if (inaddrcmp(&reg->addr, sin)) {
05669       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05670       return -1;
05671    }
05672    memcpy(&reg->us, &us, sizeof(reg->us));
05673    if (ies->msgcount >= 0)
05674       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05675    /* always refresh the registration at the interval requested by the server
05676       we are registering to
05677    */
05678    reg->refresh = refresh;
05679    if (reg->expire > -1)
05680       ast_sched_del(sched, reg->expire);
05681    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05682    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05683       if (option_verbose > 2) {
05684          if (reg->messages > 255)
05685             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05686          else if (reg->messages > 1)
05687             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05688          else if (reg->messages > 0)
05689             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05690          else
05691             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05692          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05693          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05694       }
05695       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05696    }
05697    reg->regstate = REG_STATE_REGISTERED;
05698    return 0;
05699 }
05700 
05701 static int iax2_register(char *value, int lineno)
05702 {
05703    struct iax2_registry *reg;
05704    char copy[256];
05705    char *username, *hostname, *secret;
05706    char *porta;
05707    char *stringp=NULL;
05708    
05709    if (!value)
05710       return -1;
05711    ast_copy_string(copy, value, sizeof(copy));
05712    stringp=copy;
05713    username = strsep(&stringp, "@");
05714    hostname = strsep(&stringp, "@");
05715    if (!hostname) {
05716       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05717       return -1;
05718    }
05719    stringp=username;
05720    username = strsep(&stringp, ":");
05721    secret = strsep(&stringp, ":");
05722    stringp=hostname;
05723    hostname = strsep(&stringp, ":");
05724    porta = strsep(&stringp, ":");
05725    
05726    if (porta && !atoi(porta)) {
05727       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05728       return -1;
05729    }
05730    if (!(reg = ast_calloc(1, sizeof(*reg))))
05731       return -1;
05732    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05733       free(reg);
05734       return -1;
05735    }
05736    ast_copy_string(reg->username, username, sizeof(reg->username));
05737    if (secret)
05738       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05739    reg->expire = -1;
05740    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05741    reg->addr.sin_family = AF_INET;
05742    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05743    AST_LIST_LOCK(&registrations);
05744    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05745    AST_LIST_UNLOCK(&registrations);
05746    
05747    return 0;
05748 }
05749 
05750 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05751 {
05752    char multi[256];
05753    char *stringp, *ext;
05754    if (!ast_strlen_zero(regcontext)) {
05755       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05756       stringp = multi;
05757       while((ext = strsep(&stringp, "&"))) {
05758          if (onoff) {
05759             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05760                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05761                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05762          } else
05763             ast_context_remove_extension(regcontext, ext, 1, NULL);
05764       }
05765    }
05766 }
05767 static void prune_peers(void);
05768 
05769 static void __expire_registry(void *data)
05770 {
05771    char *name = data;
05772    struct iax2_peer *peer = NULL;
05773    struct iax2_peer tmp_peer = {
05774       .name = name,
05775    };
05776 
05777    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
05778    if (!peer)
05779       return;
05780 
05781    peer->expire = -1;
05782 
05783    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
05784    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05785       realtime_update_peer(peer->name, &peer->addr, 0);
05786    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05787    /* Reset the address */
05788    memset(&peer->addr, 0, sizeof(peer->addr));
05789    /* Reset expiry value */
05790    peer->expiry = min_reg_expire;
05791    if (!ast_test_flag(peer, IAX_TEMPONLY))
05792       ast_db_del("IAX/Registry", peer->name);
05793    register_peer_exten(peer, 0);
05794    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
05795    if (iax2_regfunk)
05796       iax2_regfunk(peer->name, 0);
05797 
05798    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
05799       ao2_unlink(peers, peer);
05800 
05801    peer_unref(peer);
05802 }
05803 
05804 static int expire_registry(void *data)
05805 {
05806 #ifdef SCHED_MULTITHREADED
05807    if (schedule_action(__expire_registry, data))
05808 #endif      
05809       __expire_registry(data);
05810    return 0;
05811 }
05812 
05813 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05814 
05815 static void reg_source_db(struct iax2_peer *p)
05816 {
05817    char data[80];
05818    struct in_addr in;
05819    char *c, *d;
05820    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05821       c = strchr(data, ':');
05822       if (c) {
05823          *c = '\0';
05824          c++;
05825          if (inet_aton(data, &in)) {
05826             d = strchr(c, ':');
05827             if (d) {
05828                *d = '\0';
05829                d++;
05830                if (option_verbose > 2)
05831                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05832                   ast_inet_ntoa(in), atoi(c), atoi(d));
05833                iax2_poke_peer(p, 0);
05834                p->expiry = atoi(d);
05835                memset(&p->addr, 0, sizeof(p->addr));
05836                p->addr.sin_family = AF_INET;
05837                p->addr.sin_addr = in;
05838                p->addr.sin_port = htons(atoi(c));
05839                if (p->expire > -1)
05840                   ast_sched_del(sched, p->expire);
05841                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05842                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05843                if (iax2_regfunk)
05844                   iax2_regfunk(p->name, 1);
05845                register_peer_exten(p, 1);
05846             }              
05847                
05848          }
05849       }
05850    }
05851 }
05852 
05853 /*!
05854  * \pre iaxsl[callno] is locked
05855  *
05856  * \note Since this function calls send_command_final(), the pvt struct for
05857  *       the given call number may disappear while executing this function.
05858  */
05859 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05860 {
05861    /* Called from IAX thread only, with proper iaxsl lock */
05862    struct iax_ie_data ied;
05863    struct iax2_peer *p;
05864    int msgcount;
05865    char data[80];
05866    int version;
05867    const char *peer_name;
05868    int res = -1;
05869 
05870    memset(&ied, 0, sizeof(ied));
05871 
05872    peer_name = ast_strdupa(iaxs[callno]->peer);
05873 
05874    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05875    ast_mutex_unlock(&iaxsl[callno]);
05876    if (!(p = find_peer(peer_name, 1))) {
05877       ast_mutex_lock(&iaxsl[callno]);
05878       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
05879       return -1;
05880    }
05881    ast_mutex_lock(&iaxsl[callno]);
05882    if (!iaxs[callno])
05883       goto return_unref;
05884 
05885    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05886       if (sin->sin_addr.s_addr) {
05887          time_t nowtime;
05888          time(&nowtime);
05889          realtime_update_peer(peer_name, sin, nowtime);
05890       } else {
05891          realtime_update_peer(peer_name, sin, 0);
05892       }
05893    }
05894    if (inaddrcmp(&p->addr, sin)) {
05895       if (iax2_regfunk)
05896          iax2_regfunk(p->name, 1);
05897       /* Stash the IP address from which they registered */
05898       memcpy(&p->addr, sin, sizeof(p->addr));
05899       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05900       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05901          ast_db_put("IAX/Registry", p->name, data);
05902          if  (option_verbose > 2)
05903             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05904                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
05905          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05906          register_peer_exten(p, 1);
05907          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05908       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05909          if  (option_verbose > 2)
05910             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05911                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05912          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05913          register_peer_exten(p, 0);
05914          ast_db_del("IAX/Registry", p->name);
05915          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05916       }
05917       /* Update the host */
05918       /* Verify that the host is really there */
05919       iax2_poke_peer(p, callno);
05920    }     
05921 
05922    /* Make sure our call still exists, an INVAL at the right point may make it go away */
05923    if (!iaxs[callno]) {
05924       res = 0;
05925       goto return_unref;
05926    }
05927 
05928    /* Store socket fd */
05929    p->sockfd = fd;
05930    /* Setup the expiry */
05931    if (p->expire > -1)
05932       ast_sched_del(sched, p->expire);
05933    /* treat an unspecified refresh interval as the minimum */
05934    if (!refresh)
05935       refresh = min_reg_expire;
05936    if (refresh > max_reg_expire) {
05937       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05938          p->name, max_reg_expire, refresh);
05939       p->expiry = max_reg_expire;
05940    } else if (refresh < min_reg_expire) {
05941       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05942          p->name, min_reg_expire, refresh);
05943       p->expiry = min_reg_expire;
05944    } else {
05945       p->expiry = refresh;
05946    }
05947    if (p->expiry && sin->sin_addr.s_addr)
05948       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05949    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05950    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05951    if (sin->sin_addr.s_addr) {
05952       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05953       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05954       if (!ast_strlen_zero(p->mailbox)) {
05955          int new, old;
05956          ast_app_inboxcount(p->mailbox, &new, &old);
05957          if (new > 255)
05958             new = 255;
05959          if (old > 255)
05960             old = 255;
05961          msgcount = (old << 8) | new;
05962          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05963       }
05964       if (ast_test_flag(p, IAX_HASCALLERID)) {
05965          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05966          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05967       }
05968    }
05969    version = iax_check_version(devtype);
05970    if (version) 
05971       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05972 
05973    res = 0;
05974 
05975 return_unref:
05976    peer_unref(p);
05977 
05978    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05979 }
05980 
05981 static int registry_authrequest(int callno)
05982 {
05983    struct iax_ie_data ied;
05984    struct iax2_peer *p;
05985    char challenge[10];
05986    const char *peer_name;
05987    int res = -1;
05988 
05989    peer_name = ast_strdupa(iaxs[callno]->peer);
05990 
05991    /* SLD: third call to find_peer in registration */
05992    ast_mutex_unlock(&iaxsl[callno]);
05993    p = find_peer(peer_name, 1);
05994    ast_mutex_lock(&iaxsl[callno]);
05995    if (!iaxs[callno])
05996       goto return_unref;
05997    if (!p) {
05998       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
05999       goto return_unref;
06000    }
06001    
06002    memset(&ied, 0, sizeof(ied));
06003    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06004    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06005       /* Build the challenge */
06006       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06007       ast_string_field_set(iaxs[callno], challenge, challenge);
06008       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06009    }
06010    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06011 
06012    res = 0;
06013 
06014 return_unref:
06015    peer_unref(p);
06016 
06017    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06018 }
06019 
06020 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06021 {
06022    struct iax2_registry *reg;
06023    /* Start pessimistic */
06024    struct iax_ie_data ied;
06025    char peer[256] = "";
06026    char challenge[256] = "";
06027    int res;
06028    int authmethods = 0;
06029    if (ies->authmethods)
06030       authmethods = ies->authmethods;
06031    if (ies->username)
06032       ast_copy_string(peer, ies->username, sizeof(peer));
06033    if (ies->challenge)
06034       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06035    memset(&ied, 0, sizeof(ied));
06036    reg = iaxs[callno]->reg;
06037    if (reg) {
06038          if (inaddrcmp(&reg->addr, sin)) {
06039             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06040             return -1;
06041          }
06042          if (ast_strlen_zero(reg->secret)) {
06043             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06044             reg->regstate = REG_STATE_NOAUTH;
06045             return -1;
06046          }
06047          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06048          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06049          if (reg->secret[0] == '[') {
06050             char tmpkey[256];
06051             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06052             tmpkey[strlen(tmpkey) - 1] = '\0';
06053             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06054          } else
06055             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06056          if (!res) {
06057             reg->regstate = REG_STATE_AUTHSENT;
06058             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06059          } else
06060             return -1;
06061          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06062    } else   
06063       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06064    return -1;
06065 }
06066 
06067 static void stop_stuff(int callno)
06068 {
06069    iax2_destroy_helper(iaxs[callno]);
06070 }
06071 
06072 static void __auth_reject(void *nothing)
06073 {
06074    /* Called from IAX thread only, without iaxs lock */
06075    int callno = (int)(long)(nothing);
06076    struct iax_ie_data ied;
06077    ast_mutex_lock(&iaxsl[callno]);
06078    if (iaxs[callno]) {
06079       memset(&ied, 0, sizeof(ied));
06080       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06081          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06082          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06083       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06084          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06085          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06086       }
06087       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06088    }
06089    ast_mutex_unlock(&iaxsl[callno]);
06090 }
06091 
06092 static int auth_reject(void *data)
06093 {
06094    int callno = (int)(long)(data);
06095    ast_mutex_lock(&iaxsl[callno]);
06096    if (iaxs[callno])
06097       iaxs[callno]->authid = -1;
06098    ast_mutex_unlock(&iaxsl[callno]);
06099 #ifdef SCHED_MULTITHREADED
06100    if (schedule_action(__auth_reject, data))
06101 #endif      
06102       __auth_reject(data);
06103    return 0;
06104 }
06105 
06106 static int auth_fail(int callno, int failcode)
06107 {
06108    /* Schedule sending the authentication failure in one second, to prevent
06109       guessing */
06110    if (iaxs[callno]) {
06111       iaxs[callno]->authfail = failcode;
06112       if (delayreject) {
06113          if (iaxs[callno]->authid > -1)
06114             ast_sched_del(sched, iaxs[callno]->authid);
06115          iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06116       } else
06117          auth_reject((void *)(long)callno);
06118    }
06119    return 0;
06120 }
06121 
06122 static void __auto_hangup(void *nothing)
06123 {
06124    /* Called from IAX thread only, without iaxs lock */
06125    int callno = (int)(long)(nothing);
06126    struct iax_ie_data ied;
06127    ast_mutex_lock(&iaxsl[callno]);
06128    if (iaxs[callno]) {
06129       memset(&ied, 0, sizeof(ied));
06130       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06131       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06132       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06133    }
06134    ast_mutex_unlock(&iaxsl[callno]);
06135 }
06136 
06137 static int auto_hangup(void *data)
06138 {
06139    int callno = (int)(long)(data);
06140    ast_mutex_lock(&iaxsl[callno]);
06141    if (iaxs[callno]) {
06142       iaxs[callno]->autoid = -1;
06143    }
06144    ast_mutex_unlock(&iaxsl[callno]);
06145 #ifdef SCHED_MULTITHREADED
06146    if (schedule_action(__auto_hangup, data))
06147 #endif      
06148       __auto_hangup(data);
06149    return 0;
06150 }
06151 
06152 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06153 {
06154    struct iax_ie_data ied;
06155    /* Auto-hangup with 30 seconds of inactivity */
06156    if (iaxs[callno]->autoid > -1)
06157       ast_sched_del(sched, iaxs[callno]->autoid);
06158    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06159    memset(&ied, 0, sizeof(ied));
06160    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06161    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06162    dp->flags |= CACHE_FLAG_TRANSMITTED;
06163 }
06164 
06165 static int iax2_vnak(int callno)
06166 {
06167    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06168 }
06169 
06170 static void vnak_retransmit(int callno, int last)
06171 {
06172    struct iax_frame *f;
06173 
06174    AST_LIST_LOCK(&iaxq.queue);
06175    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06176       /* Send a copy immediately */
06177       if ((f->callno == callno) && iaxs[f->callno] &&
06178          ((unsigned char ) (f->oseqno - last) < 128) &&
06179          (f->retries >= 0)) {
06180          send_packet(f);
06181       }
06182    }
06183    AST_LIST_UNLOCK(&iaxq.queue);
06184 }
06185 
06186 static void __iax2_poke_peer_s(void *data)
06187 {
06188    struct iax2_peer *peer = data;
06189    iax2_poke_peer(peer, 0);
06190 }
06191 
06192 static int iax2_poke_peer_s(void *data)
06193 {
06194    struct iax2_peer *peer = data;
06195    peer->pokeexpire = -1;
06196 #ifdef SCHED_MULTITHREADED
06197    if (schedule_action(__iax2_poke_peer_s, data))
06198 #endif      
06199       __iax2_poke_peer_s(data);
06200    return 0;
06201 }
06202 
06203 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06204 {
06205    int res = 0;
06206    struct iax_frame *fr;
06207    struct ast_iax2_meta_hdr *meta;
06208    struct ast_iax2_meta_trunk_hdr *mth;
06209    int calls = 0;
06210    
06211    /* Point to frame */
06212    fr = (struct iax_frame *)tpeer->trunkdata;
06213    /* Point to meta data */
06214    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06215    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06216    if (tpeer->trunkdatalen) {
06217       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06218       meta->zeros = 0;
06219       meta->metacmd = IAX_META_TRUNK;
06220       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06221          meta->cmddata = IAX_META_TRUNK_MINI;
06222       else
06223          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06224       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06225       /* And the rest of the ast_iax2 header */
06226       fr->direction = DIRECTION_OUTGRESS;
06227       fr->retrans = -1;
06228       fr->transfer = 0;
06229       /* Any appropriate call will do */
06230       fr->data = fr->afdata;
06231       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06232       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06233       calls = tpeer->calls;
06234 #if 0
06235       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));
06236 #endif      
06237       /* Reset transmit trunk side data */
06238       tpeer->trunkdatalen = 0;
06239       tpeer->calls = 0;
06240    }
06241    if (res < 0)
06242       return res;
06243    return calls;
06244 }
06245 
06246 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06247 {
06248    /* Drop when trunk is about 5 seconds idle */
06249    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06250       return 1;
06251    return 0;
06252 }
06253 
06254 static int timing_read(int *id, int fd, short events, void *cbdata)
06255 {
06256    char buf[1024];
06257    int res;
06258    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06259    int processed = 0;
06260    int totalcalls = 0;
06261 #ifdef ZT_TIMERACK
06262    int x = 1;
06263 #endif
06264    struct timeval now;
06265    if (iaxtrunkdebug)
06266       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06267    gettimeofday(&now, NULL);
06268    if (events & AST_IO_PRI) {
06269 #ifdef ZT_TIMERACK
06270       /* Great, this is a timing interface, just call the ioctl */
06271       if (ioctl(fd, ZT_TIMERACK, &x)) 
06272          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06273       res = 0;
06274 #endif      
06275    } else {
06276       /* Read and ignore from the pseudo channel for timing */
06277       res = read(fd, buf, sizeof(buf));
06278       if (res < 1) {
06279          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06280          return 1;
06281       }
06282    }
06283    /* For each peer that supports trunking... */
06284    ast_mutex_lock(&tpeerlock);
06285    tpeer = tpeers;
06286    while(tpeer) {
06287       processed++;
06288       res = 0;
06289       ast_mutex_lock(&tpeer->lock);
06290       /* We can drop a single tpeer per pass.  That makes all this logic
06291          substantially easier */
06292       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06293          /* Take it out of the list, but don't free it yet, because it
06294             could be in use */
06295          if (prev)
06296             prev->next = tpeer->next;
06297          else
06298             tpeers = tpeer->next;
06299          drop = tpeer;
06300       } else {
06301          res = send_trunk(tpeer, &now);
06302          if (iaxtrunkdebug)
06303             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);
06304       }     
06305       totalcalls += res;   
06306       res = 0;
06307       ast_mutex_unlock(&tpeer->lock);
06308       prev = tpeer;
06309       tpeer = tpeer->next;
06310    }
06311    ast_mutex_unlock(&tpeerlock);
06312    if (drop) {
06313       ast_mutex_lock(&drop->lock);
06314       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06315          because by the time they could get tpeerlock, we've already grabbed it */
06316       ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06317       free(drop->trunkdata);
06318       ast_mutex_unlock(&drop->lock);
06319       ast_mutex_destroy(&drop->lock);
06320       free(drop);
06321       
06322    }
06323    if (iaxtrunkdebug)
06324       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06325    iaxtrunkdebug =0;
06326    return 1;
06327 }
06328 
06329 struct dpreq_data {
06330    int callno;
06331    char context[AST_MAX_EXTENSION];
06332    char callednum[AST_MAX_EXTENSION];
06333    char *callerid;
06334 };
06335 
06336 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06337 {
06338    unsigned short dpstatus = 0;
06339    struct iax_ie_data ied1;
06340    int mm;
06341 
06342    memset(&ied1, 0, sizeof(ied1));
06343    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06344    /* Must be started */
06345    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06346       dpstatus = IAX_DPSTATUS_EXISTS;
06347    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06348       dpstatus = IAX_DPSTATUS_CANEXIST;
06349    } else {
06350       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06351    }
06352    if (ast_ignore_pattern(context, callednum))
06353       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06354    if (mm)
06355       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06356    if (!skiplock)
06357       ast_mutex_lock(&iaxsl[callno]);
06358    if (iaxs[callno]) {
06359       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06360       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06361       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06362       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06363    }
06364    if (!skiplock)
06365       ast_mutex_unlock(&iaxsl[callno]);
06366 }
06367 
06368 static void *dp_lookup_thread(void *data)
06369 {
06370    /* Look up for dpreq */
06371    struct dpreq_data *dpr = data;
06372    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06373    if (dpr->callerid)
06374       free(dpr->callerid);
06375    free(dpr);
06376    return NULL;
06377 }
06378 
06379 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06380 {
06381    pthread_t newthread;
06382    struct dpreq_data *dpr;
06383    pthread_attr_t attr;
06384    
06385    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06386       return;
06387 
06388    pthread_attr_init(&attr);
06389    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06390 
06391    dpr->callno = callno;
06392    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06393    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06394    if (callerid)
06395       dpr->callerid = ast_strdup(callerid);
06396    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06397       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06398    }
06399 
06400    pthread_attr_destroy(&attr);
06401 }
06402 
06403 struct iax_dual {
06404    struct ast_channel *chan1;
06405    struct ast_channel *chan2;
06406 };
06407 
06408 static void *iax_park_thread(void *stuff)
06409 {
06410    struct ast_channel *chan1, *chan2;
06411    struct iax_dual *d;
06412    struct ast_frame *f;
06413    int ext;
06414    int res;
06415    d = stuff;
06416    chan1 = d->chan1;
06417    chan2 = d->chan2;
06418    free(d);
06419    f = ast_read(chan1);
06420    if (f)
06421       ast_frfree(f);
06422    res = ast_park_call(chan1, chan2, 0, &ext);
06423    ast_hangup(chan2);
06424    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06425    return NULL;
06426 }
06427 
06428 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06429 {
06430    struct iax_dual *d;
06431    struct ast_channel *chan1m, *chan2m;
06432    pthread_t th;
06433    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06434    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06435    if (chan2m && chan1m) {
06436       /* Make formats okay */
06437       chan1m->readformat = chan1->readformat;
06438       chan1m->writeformat = chan1->writeformat;
06439       ast_channel_masquerade(chan1m, chan1);
06440       /* Setup the extensions and such */
06441       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06442       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06443       chan1m->priority = chan1->priority;
06444       
06445       /* We make a clone of the peer channel too, so we can play
06446          back the announcement */
06447       /* Make formats okay */
06448       chan2m->readformat = chan2->readformat;
06449       chan2m->writeformat = chan2->writeformat;
06450       ast_channel_masquerade(chan2m, chan2);
06451       /* Setup the extensions and such */
06452       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06453       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06454       chan2m->priority = chan2->priority;
06455       if (ast_do_masquerade(chan2m)) {
06456          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06457          ast_hangup(chan2m);
06458          return -1;
06459       }
06460    } else {
06461       if (chan1m)
06462          ast_hangup(chan1m);
06463       if (chan2m)
06464          ast_hangup(chan2m);
06465       return -1;
06466    }
06467    if ((d = ast_calloc(1, sizeof(*d)))) {
06468       pthread_attr_t attr;
06469 
06470       pthread_attr_init(&attr);
06471       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06472 
06473       d->chan1 = chan1m;
06474       d->chan2 = chan2m;
06475       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06476          pthread_attr_destroy(&attr);
06477          return 0;
06478       }
06479       pthread_attr_destroy(&attr);
06480       free(d);
06481    }
06482    return -1;
06483 }
06484 
06485 
06486 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06487 
06488 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06489 {
06490    unsigned int ourver;
06491    char rsi[80];
06492    snprintf(rsi, sizeof(rsi), "si-%s", si);
06493    if (iax_provision_version(&ourver, rsi, 1))
06494       return 0;
06495    if (option_debug)
06496       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06497    if (ourver != ver) 
06498       iax2_provision(sin, sockfd, NULL, rsi, 1);
06499    return 0;
06500 }
06501 
06502 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06503 {
06504    jb_info stats;
06505    jb_getinfo(pvt->jb, &stats);
06506    
06507    memset(iep, 0, sizeof(*iep));
06508 
06509    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06510    if(stats.frames_in == 0) stats.frames_in = 1;
06511    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06512    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06513    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06514    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06515    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06516 }
06517 
06518 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06519 {
06520    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06521    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06522    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06523    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06524    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06525    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06526    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06527 }
06528 
06529 static int socket_process(struct iax2_thread *thread);
06530 
06531 /*!
06532  * \brief Handle any deferred full frames for this thread
06533  */
06534 static void handle_deferred_full_frames(struct iax2_thread *thread)
06535 {
06536    struct iax2_pkt_buf *pkt_buf;
06537 
06538    ast_mutex_lock(&thread->lock);
06539 
06540    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06541       ast_mutex_unlock(&thread->lock);
06542 
06543       thread->buf = pkt_buf->buf;
06544       thread->buf_len = pkt_buf->len;
06545       thread->buf_size = pkt_buf->len + 1;
06546       
06547       socket_process(thread);
06548 
06549       thread->buf = NULL;
06550       ast_free(pkt_buf);
06551 
06552       ast_mutex_lock(&thread->lock);
06553    }
06554 
06555    ast_mutex_unlock(&thread->lock);
06556 }
06557 
06558 /*!
06559  * \brief Queue the last read full frame for processing by a certain thread
06560  *
06561  * If there are already any full frames queued, they are sorted
06562  * by sequence number.
06563  */
06564 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06565 {
06566    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06567    struct ast_iax2_full_hdr *fh, *cur_fh;
06568 
06569    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06570       return;
06571 
06572    pkt_buf->len = from_here->buf_len;
06573    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06574 
06575    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06576    ast_mutex_lock(&to_here->lock);
06577    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06578       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06579       if (fh->oseqno < cur_fh->oseqno) {
06580          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06581          break;
06582       }
06583    }
06584    AST_LIST_TRAVERSE_SAFE_END
06585 
06586    if (!cur_pkt_buf)
06587       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06588    
06589    ast_mutex_unlock(&to_here->lock);
06590 }
06591 
06592 static int socket_read(int *id, int fd, short events, void *cbdata)
06593 {
06594    struct iax2_thread *thread;
06595    socklen_t len;
06596    time_t t;
06597    static time_t last_errtime = 0;
06598    struct ast_iax2_full_hdr *fh;
06599 
06600    if (!(thread = find_idle_thread())) {
06601       time(&t);
06602       if (t != last_errtime)
06603          ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
06604       last_errtime = t;
06605       usleep(1);
06606       return 1;
06607    }
06608 
06609    len = sizeof(thread->iosin);
06610    thread->iofd = fd;
06611    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06612    thread->buf_size = sizeof(thread->readbuf);
06613    thread->buf = thread->readbuf;
06614    if (thread->buf_len < 0) {
06615       if (errno != ECONNREFUSED && errno != EAGAIN)
06616          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06617       handle_error();
06618       thread->iostate = IAX_IOSTATE_IDLE;
06619       signal_condition(&thread->lock, &thread->cond);
06620       return 1;
06621    }
06622    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06623       thread->iostate = IAX_IOSTATE_IDLE;
06624       signal_condition(&thread->lock, &thread->cond);
06625       return 1;
06626    }
06627    
06628    /* Determine if this frame is a full frame; if so, and any thread is currently
06629       processing a full frame for the same callno from this peer, then drop this
06630       frame (and the peer will retransmit it) */
06631    fh = (struct ast_iax2_full_hdr *) thread->buf;
06632    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06633       struct iax2_thread *cur = NULL;
06634       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06635       
06636       AST_LIST_LOCK(&active_list);
06637       AST_LIST_TRAVERSE(&active_list, cur, list) {
06638          if ((cur->ffinfo.callno == callno) &&
06639              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06640             break;
06641       }
06642       if (cur) {
06643          /* we found another thread processing a full frame for this call,
06644             so queue it up for processing later. */
06645          defer_full_frame(thread, cur);
06646          AST_LIST_UNLOCK(&active_list);
06647          thread->iostate = IAX_IOSTATE_IDLE;
06648          signal_condition(&thread->lock, &thread->cond);
06649          return 1;
06650       } else {
06651          /* this thread is going to process this frame, so mark it */
06652          thread->ffinfo.callno = callno;
06653          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06654          thread->ffinfo.type = fh->type;
06655          thread->ffinfo.csub = fh->csub;
06656       }
06657       AST_LIST_UNLOCK(&active_list);
06658    }
06659    
06660    /* Mark as ready and send on its way */
06661    thread->iostate = IAX_IOSTATE_READY;
06662 #ifdef DEBUG_SCHED_MULTITHREAD
06663    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06664 #endif
06665    signal_condition(&thread->lock, &thread->cond);
06666 
06667    return 1;
06668 }
06669 
06670 static int socket_process(struct iax2_thread *thread)
06671 {
06672    struct sockaddr_in sin;
06673    int res;
06674    int updatehistory=1;
06675    int new = NEW_PREVENT;
06676    void *ptr;
06677    int dcallno = 0;
06678    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06679    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06680    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06681    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06682    struct ast_iax2_meta_trunk_hdr *mth;
06683    struct ast_iax2_meta_trunk_entry *mte;
06684    struct ast_iax2_meta_trunk_mini *mtm;
06685    struct iax_frame *fr;
06686    struct iax_frame *cur;
06687    struct ast_frame f = { 0, };
06688    struct ast_channel *c;
06689    struct iax2_dpcache *dp;
06690    struct iax2_peer *peer;
06691    struct iax2_trunk_peer *tpeer;
06692    struct timeval rxtrunktime;
06693    struct iax_ies ies;
06694    struct iax_ie_data ied0, ied1;
06695    int format;
06696    int fd;
06697    int exists;
06698    int minivid = 0;
06699    unsigned int ts;
06700    char empty[32]="";      /* Safety measure */
06701    struct iax_frame *duped_fr;
06702    char host_pref_buf[128];
06703    char caller_pref_buf[128];
06704    struct ast_codec_pref pref;
06705    char *using_prefs = "mine";
06706 
06707    /* allocate an iax_frame with 4096 bytes of data buffer */
06708    fr = alloca(sizeof(*fr) + 4096);
06709    fr->callno = 0;
06710    fr->afdatalen = 4096; /* From alloca() above */
06711 
06712    /* Copy frequently used parameters to the stack */
06713    res = thread->buf_len;
06714    fd = thread->iofd;
06715    memcpy(&sin, &thread->iosin, sizeof(sin));
06716 
06717    if (res < sizeof(*mh)) {
06718       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06719       return 1;
06720    }
06721    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06722       if (res < sizeof(*vh)) {
06723          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));
06724          return 1;
06725       }
06726 
06727       /* This is a video frame, get call number */
06728       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd);
06729       minivid = 1;
06730    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06731       unsigned char metatype;
06732 
06733       if (res < sizeof(*meta)) {
06734          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));
06735          return 1;
06736       }
06737 
06738       /* This is a meta header */
06739       switch(meta->metacmd) {
06740       case IAX_META_TRUNK:
06741          if (res < (sizeof(*meta) + sizeof(*mth))) {
06742             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06743                sizeof(*meta) + sizeof(*mth));
06744             return 1;
06745          }
06746          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06747          ts = ntohl(mth->ts);
06748          metatype = meta->cmddata;
06749          res -= (sizeof(*meta) + sizeof(*mth));
06750          ptr = mth->data;
06751          tpeer = find_tpeer(&sin, fd);
06752          if (!tpeer) {
06753             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));
06754             return 1;
06755          }
06756          tpeer->trunkact = ast_tvnow();
06757          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06758             tpeer->rxtrunktime = tpeer->trunkact;
06759          rxtrunktime = tpeer->rxtrunktime;
06760          ast_mutex_unlock(&tpeer->lock);
06761          while(res >= sizeof(*mte)) {
06762             /* Process channels */
06763             unsigned short callno, trunked_ts, len;
06764 
06765             if (metatype == IAX_META_TRUNK_MINI) {
06766                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06767                ptr += sizeof(*mtm);
06768                res -= sizeof(*mtm);
06769                len = ntohs(mtm->len);
06770                callno = ntohs(mtm->mini.callno);
06771                trunked_ts = ntohs(mtm->mini.ts);
06772             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06773                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06774                ptr += sizeof(*mte);
06775                res -= sizeof(*mte);
06776                len = ntohs(mte->len);
06777                callno = ntohs(mte->callno);
06778                trunked_ts = 0;
06779             } else {
06780                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06781                break;
06782             }
06783             /* Stop if we don't have enough data */
06784             if (len > res)
06785                break;
06786             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd);
06787             if (fr->callno) {
06788                ast_mutex_lock(&iaxsl[fr->callno]);
06789                /* If it's a valid call, deliver the contents.  If not, we
06790                   drop it, since we don't have a scallno to use for an INVAL */
06791                /* Process as a mini frame */
06792                memset(&f, 0, sizeof(f));
06793                f.frametype = AST_FRAME_VOICE;
06794                if (iaxs[fr->callno]) {
06795                   if (iaxs[fr->callno]->voiceformat > 0) {
06796                      f.subclass = iaxs[fr->callno]->voiceformat;
06797                      f.datalen = len;
06798                      if (f.datalen >= 0) {
06799                         if (f.datalen)
06800                            f.data = ptr;
06801                         if(trunked_ts) {
06802                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06803                         } else
06804                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06805                         /* Don't pass any packets until we're started */
06806                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06807                            /* Common things */
06808                            f.src = "IAX2";
06809                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06810                               f.samples = ast_codec_get_samples(&f);
06811                            iax_frame_wrap(fr, &f);
06812                            duped_fr = iaxfrdup2(fr);
06813                            if (duped_fr) {
06814                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06815                            }
06816                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
06817                            if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06818                               iaxs[fr->callno]->last = fr->ts;
06819 #if 1
06820                               if (option_debug && iaxdebug)
06821                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06822 #endif
06823                            }
06824                         }
06825                      } else {
06826                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06827                      }
06828                   } else {
06829                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06830                      iax2_vnak(fr->callno);
06831                   }
06832                }
06833                ast_mutex_unlock(&iaxsl[fr->callno]);
06834             }
06835             ptr += len;
06836             res -= len;
06837          }
06838          
06839       }
06840       return 1;
06841    }
06842 
06843 #ifdef DEBUG_SUPPORT
06844    if (iaxdebug && (res >= sizeof(*fh)))
06845       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06846 #endif
06847    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06848       if (res < sizeof(*fh)) {
06849          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));
06850          return 1;
06851       }
06852 
06853       /* Get the destination call number */
06854       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06855       /* Retrieve the type and subclass */
06856       f.frametype = fh->type;
06857       if (f.frametype == AST_FRAME_VIDEO) {
06858          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06859       } else {
06860          f.subclass = uncompress_subclass(fh->csub);
06861       }
06862       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06863                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06864                          (f.subclass == IAX_COMMAND_REGREL)))
06865          new = NEW_ALLOW;
06866    } else {
06867       /* Don't know anything about it yet */
06868       f.frametype = AST_FRAME_NULL;
06869       f.subclass = 0;
06870    }
06871 
06872    if (!fr->callno)
06873       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd);
06874 
06875    if (fr->callno > 0)
06876       ast_mutex_lock(&iaxsl[fr->callno]);
06877 
06878    if (!fr->callno || !iaxs[fr->callno]) {
06879       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06880          frame, reply with an inval */
06881       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06882          /* We can only raw hangup control frames */
06883          if (((f.subclass != IAX_COMMAND_INVAL) &&
06884              (f.subclass != IAX_COMMAND_TXCNT) &&
06885              (f.subclass != IAX_COMMAND_TXACC) &&
06886              (f.subclass != IAX_COMMAND_FWDOWNL))||
06887              (f.frametype != AST_FRAME_IAX))
06888             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06889             fd);
06890       }
06891       if (fr->callno > 0) 
06892          ast_mutex_unlock(&iaxsl[fr->callno]);
06893       return 1;
06894    }
06895    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06896       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06897          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06898          ast_mutex_unlock(&iaxsl[fr->callno]);
06899          return 1;
06900       }
06901 #ifdef DEBUG_SUPPORT
06902       else if (iaxdebug)
06903          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06904 #endif
06905    }
06906 
06907    /* count this frame */
06908    iaxs[fr->callno]->frames_received++;
06909 
06910    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06911       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06912       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06913       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06914    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06915       if (option_debug  && iaxdebug)
06916          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06917       /* Check if it's out of order (and not an ACK or INVAL) */
06918       fr->oseqno = fh->oseqno;
06919       fr->iseqno = fh->iseqno;
06920       fr->ts = ntohl(fh->ts);
06921 #ifdef IAXTESTS
06922       if (test_resync) {
06923          if (option_debug)
06924             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06925          fr->ts += test_resync;
06926       }
06927 #endif /* IAXTESTS */
06928 #if 0
06929       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06930            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06931                         (f.subclass == IAX_COMMAND_NEW ||
06932                          f.subclass == IAX_COMMAND_AUTHREQ ||
06933                          f.subclass == IAX_COMMAND_ACCEPT ||
06934                          f.subclass == IAX_COMMAND_REJECT))      ) )
06935 #endif
06936       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06937          updatehistory = 0;
06938       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06939          (iaxs[fr->callno]->iseqno ||
06940             ((f.subclass != IAX_COMMAND_TXCNT) &&
06941             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06942             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06943             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06944             (f.subclass != IAX_COMMAND_TXACC)) ||
06945             (f.frametype != AST_FRAME_IAX))) {
06946          if (
06947           ((f.subclass != IAX_COMMAND_ACK) &&
06948            (f.subclass != IAX_COMMAND_INVAL) &&
06949            (f.subclass != IAX_COMMAND_TXCNT) &&
06950            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06951            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06952            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06953            (f.subclass != IAX_COMMAND_TXACC) &&
06954            (f.subclass != IAX_COMMAND_VNAK)) ||
06955            (f.frametype != AST_FRAME_IAX)) {
06956             /* If it's not an ACK packet, it's out of order. */
06957             if (option_debug)
06958                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06959                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06960             /* Check to see if we need to request retransmission,
06961              * and take sequence number wraparound into account */
06962             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
06963                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06964                if ((f.frametype != AST_FRAME_IAX) || 
06965                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06966                   if (option_debug)
06967                      ast_log(LOG_DEBUG, "Acking anyway\n");
06968                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06969                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06970                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06971                }
06972             } else {
06973                /* Send a VNAK requesting retransmission */
06974                iax2_vnak(fr->callno);
06975             }
06976             ast_mutex_unlock(&iaxsl[fr->callno]);
06977             return 1;
06978          }
06979       } else {
06980          /* Increment unless it's an ACK or VNAK */
06981          if (((f.subclass != IAX_COMMAND_ACK) &&
06982              (f.subclass != IAX_COMMAND_INVAL) &&
06983              (f.subclass != IAX_COMMAND_TXCNT) &&
06984              (f.subclass != IAX_COMMAND_TXACC) &&
06985             (f.subclass != IAX_COMMAND_VNAK)) ||
06986              (f.frametype != AST_FRAME_IAX))
06987             iaxs[fr->callno]->iseqno++;
06988       }
06989       /* A full frame */
06990       if (res < sizeof(*fh)) {
06991          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06992          ast_mutex_unlock(&iaxsl[fr->callno]);
06993          return 1;
06994       }
06995       /* Ensure text frames are NULL-terminated */
06996       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
06997          if (res < thread->buf_size)
06998             thread->buf[res++] = '\0';
06999          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07000             thread->buf[res - 1] = '\0';
07001       }
07002       f.datalen = res - sizeof(*fh);
07003 
07004       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07005          from the real peer, not the transfer peer */
07006       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07007           ((f.subclass != IAX_COMMAND_INVAL) ||
07008            (f.frametype != AST_FRAME_IAX))) {
07009          unsigned char x;
07010          int call_to_destroy;
07011          /* XXX This code is not very efficient.  Surely there is a better way which still
07012                 properly handles boundary conditions? XXX */
07013          /* First we have to qualify that the ACKed value is within our window */
07014          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07015             if (fr->iseqno == x)
07016                break;
07017          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07018             /* The acknowledgement is within our window.  Time to acknowledge everything
07019                that it says to */
07020             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07021                /* Ack the packet with the given timestamp */
07022                if (option_debug && iaxdebug)
07023                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07024                call_to_destroy = 0;
07025                AST_LIST_LOCK(&iaxq.queue);
07026                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07027                   /* If it's our call, and our timestamp, mark -1 retries */
07028                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07029                      cur->retries = -1;
07030                      /* Destroy call if this is the end */
07031                      if (cur->final)
07032                         call_to_destroy = fr->callno;
07033                   }
07034                }
07035                AST_LIST_UNLOCK(&iaxq.queue);
07036                if (call_to_destroy) {
07037                   if (iaxdebug && option_debug)
07038                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07039                   iax2_destroy(call_to_destroy);
07040                }
07041             }
07042             /* Note how much we've received acknowledgement for */
07043             if (iaxs[fr->callno])
07044                iaxs[fr->callno]->rseqno = fr->iseqno;
07045             else {
07046                /* Stop processing now */
07047                ast_mutex_unlock(&iaxsl[fr->callno]);
07048                return 1;
07049             }
07050          } else
07051             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07052       }
07053       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07054          ((f.frametype != AST_FRAME_IAX) || 
07055           ((f.subclass != IAX_COMMAND_TXACC) &&
07056            (f.subclass != IAX_COMMAND_TXCNT)))) {
07057          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07058          ast_mutex_unlock(&iaxsl[fr->callno]);
07059          return 1;
07060       }
07061 
07062       if (f.datalen) {
07063          if (f.frametype == AST_FRAME_IAX) {
07064             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07065                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07066                ast_mutex_unlock(&iaxsl[fr->callno]);
07067                return 1;
07068             }
07069             f.data = NULL;
07070             f.datalen = 0;
07071          } else
07072             f.data = thread->buf + sizeof(*fh);
07073       } else {
07074          if (f.frametype == AST_FRAME_IAX)
07075             f.data = NULL;
07076          else
07077             f.data = empty;
07078          memset(&ies, 0, sizeof(ies));
07079       }
07080 
07081       /* when we receive the first full frame for a new incoming channel,
07082          it is safe to start the PBX on the channel because we have now
07083          completed a 3-way handshake with the peer */
07084       if ((f.frametype == AST_FRAME_VOICE) ||
07085           (f.frametype == AST_FRAME_VIDEO) ||
07086           (f.frametype == AST_FRAME_IAX)) {
07087          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07088             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07089             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07090                ast_mutex_unlock(&iaxsl[fr->callno]);
07091                return 1;
07092             }
07093          }
07094       }
07095 
07096       if (f.frametype == AST_FRAME_VOICE) {
07097          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07098                iaxs[fr->callno]->voiceformat = f.subclass;
07099                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07100                if (iaxs[fr->callno]->owner) {
07101                   int orignative;
07102 retryowner:
07103                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07104                      ast_mutex_unlock(&iaxsl[fr->callno]);
07105                      usleep(1);
07106                      ast_mutex_lock(&iaxsl[fr->callno]);
07107                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07108                   }
07109                   if (iaxs[fr->callno]) {
07110                      if (iaxs[fr->callno]->owner) {
07111                         orignative = iaxs[fr->callno]->owner->nativeformats;
07112                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07113                         if (iaxs[fr->callno]->owner->readformat)
07114                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07115                         iaxs[fr->callno]->owner->nativeformats = orignative;
07116                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07117                      }
07118                   } else {
07119                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07120                      ast_mutex_unlock(&iaxsl[fr->callno]);
07121                      return 1;
07122                   }
07123                }
07124          }
07125       }
07126       if (f.frametype == AST_FRAME_VIDEO) {
07127          if (f.subclass != iaxs[fr->callno]->videoformat) {
07128             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07129             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07130          }
07131       }
07132       if (f.frametype == AST_FRAME_IAX) {
07133          if (iaxs[fr->callno]->initid > -1) {
07134             /* Don't auto congest anymore since we've gotten something usefulb ack */
07135             ast_sched_del(sched, iaxs[fr->callno]->initid);
07136             iaxs[fr->callno]->initid = -1;
07137          }
07138          /* Handle the IAX pseudo frame itself */
07139          if (option_debug && iaxdebug)
07140             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07141 
07142                         /* Update last ts unless the frame's timestamp originated with us. */
07143          if (iaxs[fr->callno]->last < fr->ts &&
07144                             f.subclass != IAX_COMMAND_ACK &&
07145                             f.subclass != IAX_COMMAND_PONG &&
07146                             f.subclass != IAX_COMMAND_LAGRP) {
07147             iaxs[fr->callno]->last = fr->ts;
07148             if (option_debug && iaxdebug)
07149                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07150          }
07151 
07152          switch(f.subclass) {
07153          case IAX_COMMAND_ACK:
07154             /* Do nothing */
07155             break;
07156          case IAX_COMMAND_QUELCH:
07157             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07158                     /* Generate Manager Hold event, if necessary*/
07159                if (iaxs[fr->callno]->owner) {
07160                   manager_event(EVENT_FLAG_CALL, "Hold",
07161                      "Channel: %s\r\n"
07162                      "Uniqueid: %s\r\n",
07163                      iaxs[fr->callno]->owner->name, 
07164                      iaxs[fr->callno]->owner->uniqueid);
07165                }
07166 
07167                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07168                if (ies.musiconhold) {
07169                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07170                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07171                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07172                         S_OR(mohsuggest, NULL),
07173                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07174                      if (!iaxs[fr->callno]) {
07175                         ast_mutex_unlock(&iaxsl[fr->callno]);
07176                         return 1;
07177                      }
07178                   }
07179                }
07180             }
07181             break;
07182          case IAX_COMMAND_UNQUELCH:
07183             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07184                     /* Generate Manager Unhold event, if necessary*/
07185                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07186                   manager_event(EVENT_FLAG_CALL, "Unhold",
07187                      "Channel: %s\r\n"
07188                      "Uniqueid: %s\r\n",
07189                      iaxs[fr->callno]->owner->name, 
07190                      iaxs[fr->callno]->owner->uniqueid);
07191                }
07192 
07193                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07194                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07195                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07196                   if (!iaxs[fr->callno]) {
07197                      ast_mutex_unlock(&iaxsl[fr->callno]);
07198                      return 1;
07199                   }
07200                }
07201             }
07202             break;
07203          case IAX_COMMAND_TXACC:
07204             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07205                /* Ack the packet with the given timestamp */
07206                AST_LIST_LOCK(&iaxq.queue);
07207                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07208                   /* Cancel any outstanding txcnt's */
07209                   if ((fr->callno == cur->callno) && (cur->transfer))
07210                      cur->retries = -1;
07211                }
07212                AST_LIST_UNLOCK(&iaxq.queue);
07213                memset(&ied1, 0, sizeof(ied1));
07214                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07215                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07216                iaxs[fr->callno]->transferring = TRANSFER_READY;
07217             }
07218             break;
07219          case IAX_COMMAND_NEW:
07220             /* Ignore if it's already up */
07221             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07222                break;
07223             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07224                ast_mutex_unlock(&iaxsl[fr->callno]);
07225                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07226                ast_mutex_lock(&iaxsl[fr->callno]);
07227                if (!iaxs[fr->callno]) {
07228                   ast_mutex_unlock(&iaxsl[fr->callno]);
07229                   return 1;
07230                }
07231             }
07232             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07233             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07234                int new_callno;
07235                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07236                   fr->callno = new_callno;
07237             }
07238             /* For security, always ack immediately */
07239             if (delayreject)
07240                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07241             if (check_access(fr->callno, &sin, &ies)) {
07242                /* They're not allowed on */
07243                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07244                if (authdebug)
07245                   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);
07246                break;
07247             }
07248             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07249                const char *context, *exten, *cid_num;
07250 
07251                context = ast_strdupa(iaxs[fr->callno]->context);
07252                exten = ast_strdupa(iaxs[fr->callno]->exten);
07253                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07254 
07255                /* This might re-enter the IAX code and need the lock */
07256                ast_mutex_unlock(&iaxsl[fr->callno]);
07257                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07258                ast_mutex_lock(&iaxsl[fr->callno]);
07259 
07260                if (!iaxs[fr->callno]) {
07261                   ast_mutex_unlock(&iaxsl[fr->callno]);
07262                   return 1;
07263                }
07264             } else
07265                exists = 0;
07266             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07267                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07268                   memset(&ied0, 0, sizeof(ied0));
07269                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07270                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07271                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07272                   if (!iaxs[fr->callno]) {
07273                      ast_mutex_unlock(&iaxsl[fr->callno]);
07274                      return 1;
07275                   }
07276                   if (authdebug)
07277                      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);
07278                } else {
07279                   /* Select an appropriate format */
07280 
07281                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07282                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07283                         using_prefs = "reqonly";
07284                      } else {
07285                         using_prefs = "disabled";
07286                      }
07287                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07288                      memset(&pref, 0, sizeof(pref));
07289                      strcpy(caller_pref_buf, "disabled");
07290                      strcpy(host_pref_buf, "disabled");
07291                   } else {
07292                      using_prefs = "mine";
07293                      /* If the information elements are in here... use them */
07294                      if (ies.codec_prefs)
07295                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07296                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07297                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07298                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07299                            pref = iaxs[fr->callno]->rprefs;
07300                            using_prefs = "caller";
07301                         } else {
07302                            pref = iaxs[fr->callno]->prefs;
07303                         }
07304                      } else
07305                         pref = iaxs[fr->callno]->prefs;
07306                      
07307                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07308                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07309                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07310                   }
07311                   if (!format) {
07312                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07313                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07314                      if (!format) {
07315                         memset(&ied0, 0, sizeof(ied0));
07316                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07317                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07318                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07319                         if (!iaxs[fr->callno]) {
07320                            ast_mutex_unlock(&iaxsl[fr->callno]);
07321                            return 1;
07322                         }
07323                         if (authdebug) {
07324                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07325                               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);
07326                            else 
07327                               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);
07328                         }
07329                      } else {
07330                         /* Pick one... */
07331                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07332                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07333                               format = 0;
07334                         } else {
07335                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07336                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07337                               memset(&pref, 0, sizeof(pref));
07338                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07339                               strcpy(caller_pref_buf,"disabled");
07340                               strcpy(host_pref_buf,"disabled");
07341                            } else {
07342                               using_prefs = "mine";
07343                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07344                                  /* Do the opposite of what we tried above. */
07345                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07346                                     pref = iaxs[fr->callno]->prefs;                       
07347                                  } else {
07348                                     pref = iaxs[fr->callno]->rprefs;
07349                                     using_prefs = "caller";
07350                                  }
07351                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07352                            
07353                               } else /* if no codec_prefs IE do it the old way */
07354                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07355                            }
07356                         }
07357 
07358                         if (!format) {
07359                            memset(&ied0, 0, sizeof(ied0));
07360                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07361                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07362                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07363                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07364                            if (!iaxs[fr->callno]) {
07365                               ast_mutex_unlock(&iaxsl[fr->callno]);
07366                               return 1;
07367                            }
07368                            if (authdebug)
07369                               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);
07370                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07371                            break;
07372                         }
07373                      }
07374                   }
07375                   if (format) {
07376                      /* No authentication required, let them in */
07377                      memset(&ied1, 0, sizeof(ied1));
07378                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07379                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07380                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07381                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07382                         if (option_verbose > 2) 
07383                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07384                                     "%srequested format = %s,\n"
07385                                     "%srequested prefs = %s,\n"
07386                                     "%sactual format = %s,\n"
07387                                     "%shost prefs = %s,\n"
07388                                     "%spriority = %s\n",
07389                                     ast_inet_ntoa(sin.sin_addr), 
07390                                     VERBOSE_PREFIX_4,
07391                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07392                                     VERBOSE_PREFIX_4,
07393                                     caller_pref_buf,
07394                                     VERBOSE_PREFIX_4,
07395                                     ast_getformatname(format), 
07396                                     VERBOSE_PREFIX_4,
07397                                     host_pref_buf, 
07398                                     VERBOSE_PREFIX_4,
07399                                     using_prefs);
07400                         
07401                         iaxs[fr->callno]->chosenformat = format;
07402                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07403                      } else {
07404                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07405                         /* If this is a TBD call, we're ready but now what...  */
07406                         if (option_verbose > 2)
07407                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07408                      }
07409                   }
07410                }
07411                break;
07412             }
07413             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07414                merge_encryption(iaxs[fr->callno],ies.encmethods);
07415             else
07416                iaxs[fr->callno]->encmethods = 0;
07417             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07418                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07419             if (!iaxs[fr->callno]) {
07420                ast_mutex_unlock(&iaxsl[fr->callno]);
07421                return 1;
07422             }
07423             break;
07424          case IAX_COMMAND_DPREQ:
07425             /* Request status in the dialplan */
07426             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07427                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07428                if (iaxcompat) {
07429                   /* Spawn a thread for the lookup */
07430                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07431                } else {
07432                   /* Just look it up */
07433                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07434                }
07435             }
07436             break;
07437          case IAX_COMMAND_HANGUP:
07438             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07439             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07440             /* Set hangup cause according to remote */
07441             if (ies.causecode && iaxs[fr->callno]->owner)
07442                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07443             /* Send ack immediately, before we destroy */
07444             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07445             iax2_destroy(fr->callno);
07446             break;
07447          case IAX_COMMAND_REJECT:
07448             /* Set hangup cause according to remote */
07449             if (ies.causecode && iaxs[fr->callno]->owner)
07450                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07451 
07452             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07453                if (iaxs[fr->callno]->owner && authdebug)
07454                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07455                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07456                      ies.cause ? ies.cause : "<Unknown>");
07457                ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07458                   fr->callno);
07459             }
07460             /* Send ack immediately, before we destroy */
07461             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07462                          fr->ts, NULL, 0, fr->iseqno);
07463             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07464                iaxs[fr->callno]->error = EPERM;
07465             iax2_destroy(fr->callno);
07466             break;
07467          case IAX_COMMAND_TRANSFER:
07468             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07469                /* Set BLINDTRANSFER channel variables */
07470                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07471                pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07472                if (!strcmp(ies.called_number, ast_parking_ext())) {
07473                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07474                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07475                   } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
07476                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07477                } else {
07478                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07479                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07480                         ies.called_number, iaxs[fr->callno]->context);
07481                   else
07482                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07483                         ies.called_number, iaxs[fr->callno]->context);
07484                }
07485             } else
07486                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07487             break;
07488          case IAX_COMMAND_ACCEPT:
07489             /* Ignore if call is already up or needs authentication or is a TBD */
07490             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07491                break;
07492             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07493                /* Send ack immediately, before we destroy */
07494                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07495                iax2_destroy(fr->callno);
07496                break;
07497             }
07498             if (ies.format) {
07499                iaxs[fr->callno]->peerformat = ies.format;
07500             } else {
07501                if (iaxs[fr->callno]->owner)
07502                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07503                else
07504                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07505             }
07506             if (option_verbose > 2)
07507                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));
07508             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07509                memset(&ied0, 0, sizeof(ied0));
07510                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07511                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07512                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07513                if (!iaxs[fr->callno]) {
07514                   ast_mutex_unlock(&iaxsl[fr->callno]);
07515                   return 1;
07516                }
07517                if (authdebug)
07518                   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);
07519             } else {
07520                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07521                if (iaxs[fr->callno]->owner) {
07522                   /* Switch us to use a compatible format */
07523                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07524                   if (option_verbose > 2)
07525                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07526 retryowner2:
07527                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07528                      ast_mutex_unlock(&iaxsl[fr->callno]);
07529                      usleep(1);
07530                      ast_mutex_lock(&iaxsl[fr->callno]);
07531                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07532                   }
07533                   
07534                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07535                      /* Setup read/write formats properly. */
07536                      if (iaxs[fr->callno]->owner->writeformat)
07537                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07538                      if (iaxs[fr->callno]->owner->readformat)
07539                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07540                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07541                   }
07542                }
07543             }
07544             if (iaxs[fr->callno]) {
07545                ast_mutex_lock(&dpcache_lock);
07546                dp = iaxs[fr->callno]->dpentries;
07547                while(dp) {
07548                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07549                      iax2_dprequest(dp, fr->callno);
07550                   }
07551                   dp = dp->peer;
07552                }
07553                ast_mutex_unlock(&dpcache_lock);
07554             }
07555             break;
07556          case IAX_COMMAND_POKE:
07557             /* Send back a pong packet with the original timestamp */
07558             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07559             if (!iaxs[fr->callno]) {
07560                ast_mutex_unlock(&iaxsl[fr->callno]);
07561                return 1;
07562             }
07563             break;
07564          case IAX_COMMAND_PING:
07565          {
07566             struct iax_ie_data pingied;
07567             construct_rr(iaxs[fr->callno], &pingied);
07568             /* Send back a pong packet with the original timestamp */
07569             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07570          }
07571             break;
07572          case IAX_COMMAND_PONG:
07573             /* Calculate ping time */
07574             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07575             /* save RR info */
07576             save_rr(fr, &ies);
07577 
07578             if (iaxs[fr->callno]->peerpoke) {
07579                peer = iaxs[fr->callno]->peerpoke;
07580                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07581                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07582                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07583                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07584                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07585                   }
07586                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07587                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07588                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07589                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07590                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07591                   }
07592                }
07593                peer->lastms = iaxs[fr->callno]->pingtime;
07594                if (peer->smoothing && (peer->lastms > -1))
07595                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07596                else if (peer->smoothing && peer->lastms < 0)
07597                   peer->historicms = (0 + peer->historicms) / 2;
07598                else              
07599                   peer->historicms = iaxs[fr->callno]->pingtime;
07600 
07601                /* Remove scheduled iax2_poke_noanswer */
07602                if (peer->pokeexpire > -1)
07603                   ast_sched_del(sched, peer->pokeexpire);
07604                /* Schedule the next cycle */
07605                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07606                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07607                else
07608                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07609                /* and finally send the ack */
07610                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07611                /* And wrap up the qualify call */
07612                iax2_destroy(fr->callno);
07613                peer->callno = 0;
07614                if (option_debug)
07615                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07616             }
07617             break;
07618          case IAX_COMMAND_LAGRQ:
07619          case IAX_COMMAND_LAGRP:
07620             f.src = "LAGRQ";
07621             f.mallocd = 0;
07622             f.offset = 0;
07623             f.samples = 0;
07624             /* f.data should never be NULL before a iax_frame_wrap call.
07625              * -- wad@google.com, 9 July 2007 */
07626             if (!f.data) {
07627                ast_log(LOG_ERROR,
07628                   "Non-zero data length for NULL data in LAGRP from peer %s.\n",
07629                   ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07630                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP,
07631                   fr->ts, NULL, 0, fr->iseqno);
07632                iax2_destroy(fr->callno);
07633                break;
07634             }
07635             iax_frame_wrap(fr, &f);
07636             if(f.subclass == IAX_COMMAND_LAGRQ) {
07637                /* Received a LAGRQ - echo back a LAGRP */
07638                fr->af.subclass = IAX_COMMAND_LAGRP;
07639                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07640             } else {
07641                /* Received LAGRP in response to our LAGRQ */
07642                unsigned int ts;
07643                /* This is a reply we've been given, actually measure the difference */
07644                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07645                iaxs[fr->callno]->lag = ts - fr->ts;
07646                if (option_debug && iaxdebug)
07647                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07648                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07649             }
07650             break;
07651          case IAX_COMMAND_AUTHREQ:
07652             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07653                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>");
07654                break;
07655             }
07656             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07657                ast_log(LOG_WARNING, 
07658                   "I don't know how to authenticate %s to %s\n", 
07659                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07660             }
07661             if (!iaxs[fr->callno]) {
07662                ast_mutex_unlock(&iaxsl[fr->callno]);
07663                return 1;
07664             }
07665             break;
07666          case IAX_COMMAND_AUTHREP:
07667             /* For security, always ack immediately */
07668             if (delayreject)
07669                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07670             /* Ignore once we've started */
07671             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07672                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>");
07673                break;
07674             }
07675             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07676                if (authdebug)
07677                   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);
07678                memset(&ied0, 0, sizeof(ied0));
07679                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07680                break;
07681             }
07682             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07683                /* This might re-enter the IAX code and need the lock */
07684                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07685             } else
07686                exists = 0;
07687             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07688                if (authdebug)
07689                   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);
07690                memset(&ied0, 0, sizeof(ied0));
07691                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07692                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07693                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07694                if (!iaxs[fr->callno]) {
07695                   ast_mutex_unlock(&iaxsl[fr->callno]);
07696                   return 1;
07697                }
07698             } else {
07699                /* Select an appropriate format */
07700                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07701                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07702                      using_prefs = "reqonly";
07703                   } else {
07704                      using_prefs = "disabled";
07705                   }
07706                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07707                   memset(&pref, 0, sizeof(pref));
07708                   strcpy(caller_pref_buf, "disabled");
07709                   strcpy(host_pref_buf, "disabled");
07710                } else {
07711                   using_prefs = "mine";
07712                   if (ies.codec_prefs)
07713                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07714                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07715                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07716                         pref = iaxs[fr->callno]->rprefs;
07717                         using_prefs = "caller";
07718                      } else {
07719                         pref = iaxs[fr->callno]->prefs;
07720                      }
07721                   } else /* if no codec_prefs IE do it the old way */
07722                      pref = iaxs[fr->callno]->prefs;
07723                
07724                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07725                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07726                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07727                }
07728                if (!format) {
07729                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07730                      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);
07731                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07732                   }
07733                   if (!format) {
07734                      if (authdebug) {
07735                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07736                            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);
07737                         else
07738                            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);
07739                      }
07740                      memset(&ied0, 0, sizeof(ied0));
07741                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07742                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07743                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07744                      if (!iaxs[fr->callno]) {
07745                         ast_mutex_unlock(&iaxsl[fr->callno]);
07746                         return 1;
07747                      }
07748                   } else {
07749                      /* Pick one... */
07750                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07751                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07752                            format = 0;
07753                      } else {
07754                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07755                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07756                            memset(&pref, 0, sizeof(pref));
07757                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07758                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07759                            strcpy(caller_pref_buf,"disabled");
07760                            strcpy(host_pref_buf,"disabled");
07761                         } else {
07762                            using_prefs = "mine";
07763                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07764                               /* Do the opposite of what we tried above. */
07765                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07766                                  pref = iaxs[fr->callno]->prefs;                 
07767                               } else {
07768                                  pref = iaxs[fr->callno]->rprefs;
07769                                  using_prefs = "caller";
07770                               }
07771                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07772                            } else /* if no codec_prefs IE do it the old way */
07773                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07774                         }
07775                      }
07776                      if (!format) {
07777                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07778                         if (authdebug) {
07779                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07780                               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);
07781                            else
07782                               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);
07783                         }
07784                         memset(&ied0, 0, sizeof(ied0));
07785                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07786                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07787                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07788                         if (!iaxs[fr->callno]) {
07789                            ast_mutex_unlock(&iaxsl[fr->callno]);
07790                            return 1;
07791                         }
07792                      }
07793                   }
07794                }
07795                if (format) {
07796                   /* Authentication received */
07797                   memset(&ied1, 0, sizeof(ied1));
07798                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07799                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07800                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07801                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07802                      if (option_verbose > 2) 
07803                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07804                                  "%srequested format = %s,\n"
07805                                  "%srequested prefs = %s,\n"
07806                                  "%sactual format = %s,\n"
07807                                  "%shost prefs = %s,\n"
07808                                  "%spriority = %s\n", 
07809                                  ast_inet_ntoa(sin.sin_addr), 
07810                                  VERBOSE_PREFIX_4,
07811                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07812                                  VERBOSE_PREFIX_4,
07813                                  caller_pref_buf,
07814                                  VERBOSE_PREFIX_4,
07815                                  ast_getformatname(format),
07816                                  VERBOSE_PREFIX_4,
07817                                  host_pref_buf,
07818                                  VERBOSE_PREFIX_4,
07819                                  using_prefs);
07820 
07821                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07822                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07823                         iax2_destroy(fr->callno);
07824                   } else {
07825                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07826                      /* If this is a TBD call, we're ready but now what...  */
07827                      if (option_verbose > 2)
07828                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07829                   }
07830                }
07831             }
07832             break;
07833          case IAX_COMMAND_DIAL:
07834             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07835                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07836                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07837                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07838                   if (authdebug)
07839                      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);
07840                   memset(&ied0, 0, sizeof(ied0));
07841                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07842                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07843                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07844                   if (!iaxs[fr->callno]) {
07845                      ast_mutex_unlock(&iaxsl[fr->callno]);
07846                      return 1;
07847                   }
07848                } else {
07849                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07850                   if (option_verbose > 2) 
07851                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
07852                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07853                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07854                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07855                      iax2_destroy(fr->callno);
07856                }
07857             }
07858             break;
07859          case IAX_COMMAND_INVAL:
07860             iaxs[fr->callno]->error = ENOTCONN;
07861             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07862             iax2_destroy(fr->callno);
07863             if (option_debug)
07864                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07865             break;
07866          case IAX_COMMAND_VNAK:
07867             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07868             /* Force retransmission */
07869             vnak_retransmit(fr->callno, fr->iseqno);
07870             break;
07871          case IAX_COMMAND_REGREQ:
07872          case IAX_COMMAND_REGREL:
07873             /* For security, always ack immediately */
07874             if (delayreject)
07875                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07876             if (register_verify(fr->callno, &sin, &ies)) {
07877                if (!iaxs[fr->callno]) {
07878                   ast_mutex_unlock(&iaxsl[fr->callno]);
07879                   return 1;
07880                }
07881                /* Send delayed failure */
07882                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07883                break;
07884             }
07885             if (!iaxs[fr->callno]) {
07886                ast_mutex_unlock(&iaxsl[fr->callno]);
07887                return 1;
07888             }
07889             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
07890                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
07891                if (f.subclass == IAX_COMMAND_REGREL)
07892                   memset(&sin, 0, sizeof(sin));
07893                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
07894                   ast_log(LOG_WARNING, "Registry error\n");
07895                if (!iaxs[fr->callno]) {
07896                   ast_mutex_unlock(&iaxsl[fr->callno]);
07897                   return 1;
07898                }
07899                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07900                   ast_mutex_unlock(&iaxsl[fr->callno]);
07901                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07902                   ast_mutex_lock(&iaxsl[fr->callno]);
07903                   if (!iaxs[fr->callno]) {
07904                      ast_mutex_unlock(&iaxsl[fr->callno]);
07905                      return 1;
07906                   }
07907                }
07908                break;
07909             }
07910             registry_authrequest(fr->callno);
07911             if (!iaxs[fr->callno]) {
07912                ast_mutex_unlock(&iaxsl[fr->callno]);
07913                return 1;
07914             }
07915             break;
07916          case IAX_COMMAND_REGACK:
07917             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
07918                ast_log(LOG_WARNING, "Registration failure\n");
07919             /* Send ack immediately, before we destroy */
07920             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07921             iax2_destroy(fr->callno);
07922             break;
07923          case IAX_COMMAND_REGREJ:
07924             if (iaxs[fr->callno]->reg) {
07925                if (authdebug) {
07926                   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));
07927                   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>");
07928                }
07929                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07930             }
07931             /* Send ack immediately, before we destroy */
07932             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07933             iax2_destroy(fr->callno);
07934             break;
07935          case IAX_COMMAND_REGAUTH:
07936             /* Authentication request */
07937             if (registry_rerequest(&ies, fr->callno, &sin)) {
07938                memset(&ied0, 0, sizeof(ied0));
07939                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07940                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07941                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07942                if (!iaxs[fr->callno]) {
07943                   ast_mutex_unlock(&iaxsl[fr->callno]);
07944                   return 1;
07945                }
07946             }
07947             break;
07948          case IAX_COMMAND_TXREJ:
07949             iaxs[fr->callno]->transferring = 0;
07950             if (option_verbose > 2) 
07951                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07952             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07953             if (iaxs[fr->callno]->bridgecallno) {
07954                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07955                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07956                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07957                }
07958             }
07959             break;
07960          case IAX_COMMAND_TXREADY:
07961             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
07962                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
07963                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
07964                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
07965                else
07966                   iaxs[fr->callno]->transferring = TRANSFER_READY;
07967                if (option_verbose > 2) 
07968                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07969                if (iaxs[fr->callno]->bridgecallno) {
07970                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
07971                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
07972                      /* They're both ready, now release them. */
07973                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
07974                         if (option_verbose > 2) 
07975                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07976                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07977 
07978                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
07979                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
07980 
07981                         memset(&ied0, 0, sizeof(ied0));
07982                         memset(&ied1, 0, sizeof(ied1));
07983                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07984                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07985                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
07986                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
07987                      } else {
07988                         if (option_verbose > 2) 
07989                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07990                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07991 
07992                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07993                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07994                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07995                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07996 
07997                         /* Stop doing lag & ping requests */
07998                         stop_stuff(fr->callno);
07999                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08000 
08001                         memset(&ied0, 0, sizeof(ied0));
08002                         memset(&ied1, 0, sizeof(ied1));
08003                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08004                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08005                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08006                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08007                      }
08008 
08009                   }
08010                }
08011             }
08012             break;
08013          case IAX_COMMAND_TXREQ:
08014             try_transfer(iaxs[fr->callno], &ies);
08015             break;
08016          case IAX_COMMAND_TXCNT:
08017             if (iaxs[fr->callno]->transferring)
08018                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08019             break;
08020          case IAX_COMMAND_TXREL:
08021             /* Send ack immediately, rather than waiting until we've changed addresses */
08022             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08023             complete_transfer(fr->callno, &ies);
08024             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08025             break;   
08026          case IAX_COMMAND_TXMEDIA:
08027             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08028                                         AST_LIST_LOCK(&iaxq.queue);
08029                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08030                                                 /* Cancel any outstanding frames and start anew */
08031                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08032                                                         cur->retries = -1;
08033                                                 }
08034                                         }
08035                                         AST_LIST_UNLOCK(&iaxq.queue);
08036                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08037                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08038             }
08039             break;   
08040          case IAX_COMMAND_DPREP:
08041             complete_dpreply(iaxs[fr->callno], &ies);
08042             break;
08043          case IAX_COMMAND_UNSUPPORT:
08044             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08045             break;
08046          case IAX_COMMAND_FWDOWNL:
08047             /* Firmware download */
08048             memset(&ied0, 0, sizeof(ied0));
08049             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08050             if (res < 0)
08051                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08052             else if (res > 0)
08053                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08054             else
08055                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08056             if (!iaxs[fr->callno]) {
08057                ast_mutex_unlock(&iaxsl[fr->callno]);
08058                return 1;
08059             }
08060             break;
08061          default:
08062             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08063             memset(&ied0, 0, sizeof(ied0));
08064             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08065             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08066          }
08067          /* Don't actually pass these frames along */
08068          if ((f.subclass != IAX_COMMAND_ACK) && 
08069            (f.subclass != IAX_COMMAND_TXCNT) && 
08070            (f.subclass != IAX_COMMAND_TXACC) && 
08071            (f.subclass != IAX_COMMAND_INVAL) &&
08072            (f.subclass != IAX_COMMAND_VNAK)) { 
08073             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08074                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08075          }
08076          ast_mutex_unlock(&iaxsl[fr->callno]);
08077          return 1;
08078       }
08079       /* Unless this is an ACK or INVAL frame, ack it */
08080       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08081          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08082    } else if (minivid) {
08083       f.frametype = AST_FRAME_VIDEO;
08084       if (iaxs[fr->callno]->videoformat > 0) 
08085          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08086       else {
08087          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08088          iax2_vnak(fr->callno);
08089          ast_mutex_unlock(&iaxsl[fr->callno]);
08090          return 1;
08091       }
08092       f.datalen = res - sizeof(*vh);
08093       if (f.datalen)
08094          f.data = thread->buf + sizeof(*vh);
08095       else
08096          f.data = NULL;
08097 #ifdef IAXTESTS
08098       if (test_resync) {
08099          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08100       } else
08101 #endif /* IAXTESTS */
08102          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08103    } else {
08104       /* A mini frame */
08105       f.frametype = AST_FRAME_VOICE;
08106       if (iaxs[fr->callno]->voiceformat > 0)
08107          f.subclass = iaxs[fr->callno]->voiceformat;
08108       else {
08109          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
08110          iax2_vnak(fr->callno);
08111          ast_mutex_unlock(&iaxsl[fr->callno]);
08112          return 1;
08113       }
08114       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08115       if (f.datalen < 0) {
08116          ast_log(LOG_WARNING, "Datalen < 0?\n");
08117          ast_mutex_unlock(&iaxsl[fr->callno]);
08118          return 1;
08119       }
08120       if (f.datalen)
08121          f.data = thread->buf + sizeof(*mh);
08122       else
08123          f.data = NULL;
08124 #ifdef IAXTESTS
08125       if (test_resync) {
08126          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08127       } else
08128 #endif /* IAXTESTS */
08129       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08130       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08131    }
08132    /* Don't pass any packets until we're started */
08133    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08134       ast_mutex_unlock(&iaxsl[fr->callno]);
08135       return 1;
08136    }
08137    /* Common things */
08138    f.src = "IAX2";
08139    f.mallocd = 0;
08140    f.offset = 0;
08141    f.len = 0;
08142    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08143       f.samples = ast_codec_get_samples(&f);
08144       /* We need to byteswap incoming slinear samples from network byte order */
08145       if (f.subclass == AST_FORMAT_SLINEAR)
08146          ast_frame_byteswap_be(&f);
08147    } else
08148       f.samples = 0;
08149    iax_frame_wrap(fr, &f);
08150 
08151    /* If this is our most recent packet, use it as our basis for timestamping */
08152    if (iaxs[fr->callno]->last < fr->ts) {
08153       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08154       fr->outoforder = 0;
08155    } else {
08156       if (option_debug && iaxdebug)
08157          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);
08158       fr->outoforder = -1;
08159    }
08160    duped_fr = iaxfrdup2(fr);
08161    if (duped_fr) {
08162       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08163    }
08164    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08165       iaxs[fr->callno]->last = fr->ts;
08166 #if 1
08167       if (option_debug && iaxdebug)
08168          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08169 #endif
08170    }
08171 
08172    /* Always run again */
08173    ast_mutex_unlock(&iaxsl[fr->callno]);
08174    return 1;
08175 }
08176 
08177 /* Function to clean up process thread if it is cancelled */
08178 static void iax2_process_thread_cleanup(void *data)
08179 {
08180    struct iax2_thread *thread = data;
08181    ast_mutex_destroy(&thread->lock);
08182    ast_cond_destroy(&thread->cond);
08183    free(thread);
08184    ast_atomic_dec_and_test(&iaxactivethreadcount);
08185 }
08186 
08187 static void *iax2_process_thread(void *data)
08188 {
08189    struct iax2_thread *thread = data;
08190    struct timeval tv;
08191    struct timespec ts;
08192    int put_into_idle = 0;
08193 
08194    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08195    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08196    for(;;) {
08197       /* Wait for something to signal us to be awake */
08198       ast_mutex_lock(&thread->lock);
08199 
08200       /* Flag that we're ready to accept signals */
08201       thread->ready_for_signal = 1;
08202       
08203       /* Put into idle list if applicable */
08204       if (put_into_idle)
08205          insert_idle_thread(thread);
08206 
08207       if (thread->type == IAX_TYPE_DYNAMIC) {
08208          struct iax2_thread *t = NULL;
08209          /* Wait to be signalled or time out */
08210          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08211          ts.tv_sec = tv.tv_sec;
08212          ts.tv_nsec = tv.tv_usec * 1000;
08213          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08214             /* This thread was never put back into the available dynamic
08215              * thread list, so just go away. */
08216             if (!put_into_idle) {
08217                ast_mutex_unlock(&thread->lock);
08218                break;
08219             }
08220             AST_LIST_LOCK(&dynamic_list);
08221             /* Account for the case where this thread is acquired *right* after a timeout */
08222             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08223                iaxdynamicthreadcount--;
08224             AST_LIST_UNLOCK(&dynamic_list);
08225             if (t) {
08226                /* This dynamic thread timed out waiting for a task and was
08227                 * not acquired immediately after the timeout, 
08228                 * so it's time to go away. */
08229                ast_mutex_unlock(&thread->lock);
08230                break;
08231             }
08232             /* Someone grabbed our thread *right* after we timed out.
08233              * Wait for them to set us up with something to do and signal
08234              * us to continue. */
08235             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08236             ts.tv_sec = tv.tv_sec;
08237             ts.tv_nsec = tv.tv_usec * 1000;
08238             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08239             {
08240                ast_mutex_unlock(&thread->lock);
08241                break;
08242             }
08243          }
08244       } else {
08245          ast_cond_wait(&thread->cond, &thread->lock);
08246       }
08247 
08248       /* Go back into our respective list */
08249       put_into_idle = 1;
08250 
08251       ast_mutex_unlock(&thread->lock);
08252 
08253       if (thread->iostate == IAX_IOSTATE_IDLE)
08254          continue;
08255 
08256       /* Add ourselves to the active list now */
08257       AST_LIST_LOCK(&active_list);
08258       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08259       AST_LIST_UNLOCK(&active_list);
08260 
08261       /* See what we need to do */
08262       switch(thread->iostate) {
08263       case IAX_IOSTATE_READY:
08264          thread->actions++;
08265          thread->iostate = IAX_IOSTATE_PROCESSING;
08266          socket_process(thread);
08267          handle_deferred_full_frames(thread);
08268          break;
08269       case IAX_IOSTATE_SCHEDREADY:
08270          thread->actions++;
08271          thread->iostate = IAX_IOSTATE_PROCESSING;
08272 #ifdef SCHED_MULTITHREADED
08273          thread->schedfunc(thread->scheddata);
08274 #endif      
08275          break;
08276       }
08277       time(&thread->checktime);
08278       thread->iostate = IAX_IOSTATE_IDLE;
08279 #ifdef DEBUG_SCHED_MULTITHREAD
08280       thread->curfunc[0]='\0';
08281 #endif      
08282 
08283       /* Now... remove ourselves from the active list, and return to the idle list */
08284       AST_LIST_LOCK(&active_list);
08285       AST_LIST_REMOVE(&active_list, thread, list);
08286       AST_LIST_UNLOCK(&active_list);
08287 
08288       /* Make sure another frame didn't sneak in there after we thought we were done. */
08289       handle_deferred_full_frames(thread);
08290    }
08291 
08292    /* I am exiting here on my own volition, I need to clean up my own data structures
08293    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08294    */
08295    pthread_cleanup_pop(1);
08296 
08297    return NULL;
08298 }
08299 
08300 static int iax2_do_register(struct iax2_registry *reg)
08301 {
08302    struct iax_ie_data ied;
08303    if (option_debug && iaxdebug)
08304       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08305 
08306    if (reg->dnsmgr && 
08307        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08308       /* Maybe the IP has changed, force DNS refresh */
08309       ast_dnsmgr_refresh(reg->dnsmgr);
08310    }
08311    
08312    /*
08313     * if IP has Changed, free allocated call to create a new one with new IP
08314     * call has the pointer to IP and must be updated to the new one
08315     */
08316    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08317       ast_mutex_lock(&iaxsl[reg->callno]);
08318       iax2_destroy(reg->callno);
08319       ast_mutex_unlock(&iaxsl[reg->callno]);
08320       reg->callno = 0;
08321    }
08322    if (!reg->addr.sin_addr.s_addr) {
08323       if (option_debug && iaxdebug)
08324          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08325       /* Setup the next registration attempt */
08326       if (reg->expire > -1)
08327          ast_sched_del(sched, reg->expire);
08328       reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08329       return -1;
08330    }
08331 
08332    if (!reg->callno) {
08333       if (option_debug)
08334          ast_log(LOG_DEBUG, "Allocate call number\n");
08335       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, defaultsockfd);
08336       if (reg->callno < 1) {
08337          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08338          return -1;
08339       } else if (option_debug)
08340          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08341       iaxs[reg->callno]->reg = reg;
08342    }
08343    /* Schedule the next registration attempt */
08344    if (reg->expire > -1)
08345       ast_sched_del(sched, reg->expire);
08346    /* Setup the next registration a little early */
08347    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08348    /* Send the request */
08349    memset(&ied, 0, sizeof(ied));
08350    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08351    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08352    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08353    reg->regstate = REG_STATE_REGSENT;
08354    return 0;
08355 }
08356 
08357 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08358 {
08359    if (pos != 3)
08360       return NULL;
08361    return iax_prov_complete_template(line, word, pos, state);
08362 }
08363 
08364 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08365 {
08366    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08367       is found for template */
08368    struct iax_ie_data provdata;
08369    struct iax_ie_data ied;
08370    unsigned int sig;
08371    struct sockaddr_in sin;
08372    int callno;
08373    struct create_addr_info cai;
08374 
08375    memset(&cai, 0, sizeof(cai));
08376 
08377    if (option_debug)
08378       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08379 
08380    if (iax_provision_build(&provdata, &sig, template, force)) {
08381       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08382       return 0;
08383    }
08384 
08385    if (end) {
08386       memcpy(&sin, end, sizeof(sin));
08387       cai.sockfd = sockfd;
08388    } else if (create_addr(dest, &sin, &cai))
08389       return -1;
08390 
08391    /* Build the rest of the message */
08392    memset(&ied, 0, sizeof(ied));
08393    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08394 
08395    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08396    if (!callno)
08397       return -1;
08398 
08399    ast_mutex_lock(&iaxsl[callno]);
08400    if (iaxs[callno]) {
08401       /* Schedule autodestruct in case they don't ever give us anything back */
08402       if (iaxs[callno]->autoid > -1)
08403          ast_sched_del(sched, iaxs[callno]->autoid);
08404       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08405       ast_set_flag(iaxs[callno], IAX_PROVISION);
08406       /* Got a call number now, so go ahead and send the provisioning information */
08407       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08408    }
08409    ast_mutex_unlock(&iaxsl[callno]);
08410 
08411    return 1;
08412 }
08413 
08414 static char *papp = "IAX2Provision";
08415 static char *psyn = "Provision a calling IAXy with a given template";
08416 static char *pdescrip = 
08417 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08418 "the calling entity is in fact an IAXy) with the given template or\n"
08419 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08420 
08421 /*! iax2provision
08422 \ingroup applications
08423 */
08424 static int iax2_prov_app(struct ast_channel *chan, void *data)
08425 {
08426    int res;
08427    char *sdata;
08428    char *opts;
08429    int force =0;
08430    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08431    if (ast_strlen_zero(data))
08432       data = "default";
08433    sdata = ast_strdupa(data);
08434    opts = strchr(sdata, '|');
08435    if (opts)
08436       *opts='\0';
08437 
08438    if (chan->tech != &iax2_tech) {
08439       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08440       return -1;
08441    } 
08442    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08443       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08444       return -1;
08445    }
08446    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08447    if (option_verbose > 2)
08448       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08449       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08450       sdata, res);
08451    return res;
08452 }
08453 
08454 
08455 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08456 {
08457    int force = 0;
08458    int res;
08459    if (argc < 4)
08460       return RESULT_SHOWUSAGE;
08461    if ((argc > 4)) {
08462       if (!strcasecmp(argv[4], "forced"))
08463          force = 1;
08464       else
08465          return RESULT_SHOWUSAGE;
08466    }
08467    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08468    if (res < 0)
08469       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08470    else if (res < 1)
08471       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08472    else
08473       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08474    return RESULT_SUCCESS;
08475 }
08476 
08477 static void __iax2_poke_noanswer(void *data)
08478 {
08479    struct iax2_peer *peer = data;
08480    if (peer->lastms > -1) {
08481       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08482       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08483       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08484    }
08485    if (peer->callno > 0) {
08486       ast_mutex_lock(&iaxsl[peer->callno]);
08487       iax2_destroy(peer->callno);
08488       ast_mutex_unlock(&iaxsl[peer->callno]);
08489    }
08490    peer->callno = 0;
08491    peer->lastms = -1;
08492    /* Try again quickly */
08493    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
08494 }
08495 
08496 static int iax2_poke_noanswer(void *data)
08497 {
08498    struct iax2_peer *peer = data;
08499    peer->pokeexpire = -1;
08500 #ifdef SCHED_MULTITHREADED
08501    if (schedule_action(__iax2_poke_noanswer, data))
08502 #endif      
08503       __iax2_poke_noanswer(data);
08504    return 0;
08505 }
08506 
08507 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08508 {
08509    struct iax2_peer *peer = obj;
08510 
08511    iax2_poke_peer(peer, 0);
08512 
08513    return 0;
08514 }
08515 
08516 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08517 {
08518    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
08519       /* IF we have no IP, or this isn't to be monitored, return
08520         immediately after clearing things out */
08521       peer->lastms = 0;
08522       peer->historicms = 0;
08523       peer->pokeexpire = -1;
08524       peer->callno = 0;
08525       return 0;
08526    }
08527    if (peer->callno > 0) {
08528       ast_log(LOG_NOTICE, "Still have a callno...\n");
08529       ast_mutex_lock(&iaxsl[peer->callno]);
08530       iax2_destroy(peer->callno);
08531       ast_mutex_unlock(&iaxsl[peer->callno]);
08532    }
08533    if (heldcall)
08534       ast_mutex_unlock(&iaxsl[heldcall]);
08535    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd);
08536    if (heldcall)
08537       ast_mutex_lock(&iaxsl[heldcall]);
08538    if (peer->callno < 1) {
08539       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08540       return -1;
08541    }
08542 
08543    /* Speed up retransmission times for this qualify call */
08544    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08545    iaxs[peer->callno]->peerpoke = peer;
08546    
08547    /* Remove any pending pokeexpire task */
08548    if (peer->pokeexpire > -1)
08549       ast_sched_del(sched, peer->pokeexpire);
08550 
08551    /* Queue up a new task to handle no reply */
08552    /* If the host is already unreachable then use the unreachable interval instead */
08553    if (peer->lastms < 0) {
08554       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
08555    } else
08556       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
08557 
08558    /* And send the poke */
08559    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08560 
08561    return 0;
08562 }
08563 
08564 static void free_context(struct iax2_context *con)
08565 {
08566    struct iax2_context *conl;
08567    while(con) {
08568       conl = con;
08569       con = con->next;
08570       free(conl);
08571    }
08572 }
08573 
08574 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08575 {
08576    int callno;
08577    int res;
08578    int fmt, native;
08579    struct sockaddr_in sin;
08580    struct ast_channel *c;
08581    struct parsed_dial_string pds;
08582    struct create_addr_info cai;
08583    char *tmpstr;
08584 
08585    memset(&pds, 0, sizeof(pds));
08586    tmpstr = ast_strdupa(data);
08587    parse_dial_string(tmpstr, &pds);
08588 
08589    memset(&cai, 0, sizeof(cai));
08590    cai.capability = iax2_capability;
08591 
08592    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08593 
08594    if (!pds.peer) {
08595       ast_log(LOG_WARNING, "No peer given\n");
08596       return NULL;
08597    }
08598           
08599    
08600    /* Populate our address from the given */
08601    if (create_addr(pds.peer, &sin, &cai)) {
08602       *cause = AST_CAUSE_UNREGISTERED;
08603       return NULL;
08604    }
08605 
08606    if (pds.port)
08607       sin.sin_port = htons(atoi(pds.port));
08608 
08609    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08610    if (callno < 1) {
08611       ast_log(LOG_WARNING, "Unable to create call\n");
08612       *cause = AST_CAUSE_CONGESTION;
08613       return NULL;
08614    }
08615 
08616    ast_mutex_lock(&iaxsl[callno]);
08617 
08618    /* If this is a trunk, update it now */
08619    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08620    if (ast_test_flag(&cai, IAX_TRUNK)) {
08621       int new_callno;
08622       if ((new_callno = make_trunk(callno, 1)) != -1)
08623          callno = new_callno;
08624    }
08625    iaxs[callno]->maxtime = cai.maxtime;
08626    if (cai.found)
08627       ast_string_field_set(iaxs[callno], host, pds.peer);
08628 
08629    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08630 
08631    ast_mutex_unlock(&iaxsl[callno]);
08632 
08633    if (c) {
08634       /* Choose a format we can live with */
08635       if (c->nativeformats & format) 
08636          c->nativeformats &= format;
08637       else {
08638          native = c->nativeformats;
08639          fmt = format;
08640          res = ast_translator_best_choice(&fmt, &native);
08641          if (res < 0) {
08642             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08643                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08644             ast_hangup(c);
08645             return NULL;
08646          }
08647          c->nativeformats = native;
08648       }
08649       c->readformat = ast_best_codec(c->nativeformats);
08650       c->writeformat = c->readformat;
08651    }
08652 
08653    return c;
08654 }
08655 
08656 static void *sched_thread(void *ignore)
08657 {
08658    int count;
08659    int res;
08660    struct timeval tv;
08661    struct timespec ts;
08662 
08663    for (;;) {
08664       res = ast_sched_wait(sched);
08665       if ((res > 1000) || (res < 0))
08666          res = 1000;
08667       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08668       ts.tv_sec = tv.tv_sec;
08669       ts.tv_nsec = tv.tv_usec * 1000;
08670 
08671       pthread_testcancel();
08672       ast_mutex_lock(&sched_lock);
08673       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08674       ast_mutex_unlock(&sched_lock);
08675       pthread_testcancel();
08676 
08677       count = ast_sched_runq(sched);
08678       if (count >= 20)
08679          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08680    }
08681    return NULL;
08682 }
08683 
08684 static void *network_thread(void *ignore)
08685 {
08686    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08687       from the network, and queue them for delivery to the channels */
08688    int res, count, wakeup;
08689    struct iax_frame *f;
08690 
08691    if (timingfd > -1)
08692       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08693    
08694    for(;;) {
08695       pthread_testcancel();
08696 
08697       /* Go through the queue, sending messages which have not yet been
08698          sent, and scheduling retransmissions if appropriate */
08699       AST_LIST_LOCK(&iaxq.queue);
08700       count = 0;
08701       wakeup = -1;
08702       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08703          if (f->sentyet)
08704             continue;
08705          
08706          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
08707          if (ast_mutex_trylock(&iaxsl[f->callno])) {
08708             wakeup = 1;
08709             continue;
08710          }
08711 
08712          f->sentyet++;
08713 
08714          if (iaxs[f->callno]) {
08715             send_packet(f);
08716             count++;
08717          } 
08718 
08719          ast_mutex_unlock(&iaxsl[f->callno]);
08720 
08721          if (f->retries < 0) {
08722             /* This is not supposed to be retransmitted */
08723             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
08724             iaxq.count--;
08725             /* Free the iax frame */
08726             iax_frame_free(f);
08727          } else {
08728             /* We need reliable delivery.  Schedule a retransmission */
08729             f->retries++;
08730             f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08731             signal_condition(&sched_lock, &sched_cond);
08732          }
08733       }
08734       AST_LIST_TRAVERSE_SAFE_END
08735       AST_LIST_UNLOCK(&iaxq.queue);
08736 
08737       pthread_testcancel();
08738 
08739       if (count >= 20)
08740          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08741 
08742       /* Now do the IO, and run scheduled tasks */
08743       res = ast_io_wait(io, wakeup);
08744       if (res >= 0) {
08745          if (res >= 20)
08746             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08747       }
08748    }
08749    return NULL;
08750 }
08751 
08752 static int start_network_thread(void)
08753 {
08754    pthread_attr_t attr;
08755    int threadcount = 0;
08756    int x;
08757    for (x = 0; x < iaxthreadcount; x++) {
08758       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08759       if (thread) {
08760          thread->type = IAX_TYPE_POOL;
08761          thread->threadnum = ++threadcount;
08762          ast_mutex_init(&thread->lock);
08763          ast_cond_init(&thread->cond, NULL);
08764          pthread_attr_init(&attr);
08765          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08766          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08767             ast_log(LOG_WARNING, "Failed to create new thread!\n");
08768             free(thread);
08769             thread = NULL;
08770          }
08771          AST_LIST_LOCK(&idle_list);
08772          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08773          AST_LIST_UNLOCK(&idle_list);
08774       }
08775    }
08776    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08777    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08778    if (option_verbose > 1)
08779       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08780    return 0;
08781 }
08782 
08783 static struct iax2_context *build_context(char *context)
08784 {
08785    struct iax2_context *con;
08786 
08787    if ((con = ast_calloc(1, sizeof(*con))))
08788       ast_copy_string(con->context, context, sizeof(con->context));
08789    
08790    return con;
08791 }
08792 
08793 static int get_auth_methods(char *value)
08794 {
08795    int methods = 0;
08796    if (strstr(value, "rsa"))
08797       methods |= IAX_AUTH_RSA;
08798    if (strstr(value, "md5"))
08799       methods |= IAX_AUTH_MD5;
08800    if (strstr(value, "plaintext"))
08801       methods |= IAX_AUTH_PLAINTEXT;
08802    return methods;
08803 }
08804 
08805 
08806 /*! \brief Check if address can be used as packet source.
08807  \return 0  address available, 1  address unavailable, -1  error
08808 */
08809 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08810 {
08811    int sd;
08812    int res;
08813    
08814    sd = socket(AF_INET, SOCK_DGRAM, 0);
08815    if (sd < 0) {
08816       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08817       return -1;
08818    }
08819 
08820    res = bind(sd, sa, salen);
08821    if (res < 0) {
08822       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08823       close(sd);
08824       return 1;
08825    }
08826 
08827    close(sd);
08828    return 0;
08829 }
08830 
08831 /*! \brief Parse the "sourceaddress" value,
08832   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
08833   not found. */
08834 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08835 {
08836    struct sockaddr_in sin;
08837    int nonlocal = 1;
08838    int port = IAX_DEFAULT_PORTNO;
08839    int sockfd = defaultsockfd;
08840    char *tmp;
08841    char *addr;
08842    char *portstr;
08843 
08844    if (!(tmp = ast_strdupa(srcaddr)))
08845       return -1;
08846 
08847    addr = strsep(&tmp, ":");
08848    portstr = tmp;
08849 
08850    if (portstr) {
08851       port = atoi(portstr);
08852       if (port < 1)
08853          port = IAX_DEFAULT_PORTNO;
08854    }
08855    
08856    if (!ast_get_ip(&sin, addr)) {
08857       struct ast_netsock *sock;
08858       int res;
08859 
08860       sin.sin_port = 0;
08861       sin.sin_family = AF_INET;
08862       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08863       if (res == 0) {
08864          /* ip address valid. */
08865          sin.sin_port = htons(port);
08866          if (!(sock = ast_netsock_find(netsock, &sin)))
08867             sock = ast_netsock_find(outsock, &sin);
08868          if (sock) {
08869             sockfd = ast_netsock_sockfd(sock);
08870             nonlocal = 0;
08871          } else {
08872             unsigned int orig_saddr = sin.sin_addr.s_addr;
08873             /* INADDR_ANY matches anyway! */
08874             sin.sin_addr.s_addr = INADDR_ANY;
08875             if (ast_netsock_find(netsock, &sin)) {
08876                sin.sin_addr.s_addr = orig_saddr;
08877                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
08878                if (sock) {
08879                   sockfd = ast_netsock_sockfd(sock);
08880                   ast_netsock_unref(sock);
08881                   nonlocal = 0;
08882                } else {
08883                   nonlocal = 2;
08884                }
08885             }
08886          }
08887       }
08888    }
08889       
08890    peer->sockfd = sockfd;
08891 
08892    if (nonlocal == 1) {
08893       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08894          srcaddr, peer->name);
08895       return -1;
08896         } else if (nonlocal == 2) {
08897       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
08898          srcaddr, peer->name);
08899          return -1;
08900    } else {
08901       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08902       return 0;
08903    }
08904 }
08905 
08906 static void peer_destructor(void *obj)
08907 {
08908    struct iax2_peer *peer = obj;
08909 
08910    ast_free_ha(peer->ha);
08911 
08912    /* Delete it, it needs to disappear */
08913    if (peer->expire > -1)
08914       ast_sched_del(sched, peer->expire);
08915    if (peer->pokeexpire > -1)
08916       ast_sched_del(sched, peer->pokeexpire);
08917    if (peer->callno > 0) {
08918       ast_mutex_lock(&iaxsl[peer->callno]);
08919       iax2_destroy(peer->callno);
08920       ast_mutex_unlock(&iaxsl[peer->callno]);
08921    }
08922 
08923    register_peer_exten(peer, 0);
08924 
08925    if (peer->dnsmgr)
08926       ast_dnsmgr_release(peer->dnsmgr);
08927 
08928    ast_string_field_free_pools(peer);
08929 }
08930 
08931 /*! \brief Create peer structure based on configuration */
08932 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08933 {
08934    struct iax2_peer *peer = NULL;
08935    struct ast_ha *oldha = NULL;
08936    int maskfound=0;
08937    int found=0;
08938    int firstpass=1;
08939    struct iax2_peer tmp_peer = {
08940       .name = name,
08941    };
08942 
08943    if (!temponly) {
08944       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
08945       if (peer && !ast_test_flag(peer, IAX_DELME))
08946          firstpass = 0;
08947    }
08948 
08949    if (peer) {
08950       found++;
08951       if (firstpass) {
08952          oldha = peer->ha;
08953          peer->ha = NULL;
08954       }
08955       ao2_unlink(peers, peer);
08956    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
08957       peer->expire = -1;
08958       peer->pokeexpire = -1;
08959       peer->sockfd = defaultsockfd;
08960       if (ast_string_field_init(peer, 32))
08961          peer = peer_unref(peer);
08962    }
08963 
08964    if (peer) {
08965       if (firstpass) {
08966          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08967          peer->encmethods = iax2_encryption;
08968          peer->adsi = adsi;
08969          ast_string_field_set(peer,secret,"");
08970          if (!found) {
08971             ast_string_field_set(peer, name, name);
08972             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08973             peer->expiry = min_reg_expire;
08974          }
08975          peer->prefs = prefs;
08976          peer->capability = iax2_capability;
08977          peer->smoothing = 0;
08978          peer->pokefreqok = DEFAULT_FREQ_OK;
08979          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08980          ast_string_field_set(peer,context,"");
08981          ast_string_field_set(peer,peercontext,"");
08982          ast_clear_flag(peer, IAX_HASCALLERID);
08983          ast_string_field_set(peer, cid_name, "");
08984          ast_string_field_set(peer, cid_num, "");
08985       }
08986 
08987       if (!v) {
08988          v = alt;
08989          alt = NULL;
08990       }
08991       while(v) {
08992          if (!strcasecmp(v->name, "secret")) {
08993             ast_string_field_set(peer, secret, v->value);
08994          } else if (!strcasecmp(v->name, "mailbox")) {
08995             ast_string_field_set(peer, mailbox, v->value);
08996          } else if (!strcasecmp(v->name, "mohinterpret")) {
08997             ast_string_field_set(peer, mohinterpret, v->value);
08998          } else if (!strcasecmp(v->name, "mohsuggest")) {
08999             ast_string_field_set(peer, mohsuggest, v->value);
09000          } else if (!strcasecmp(v->name, "dbsecret")) {
09001             ast_string_field_set(peer, dbsecret, v->value);
09002          } else if (!strcasecmp(v->name, "trunk")) {
09003             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09004             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09005                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09006                ast_clear_flag(peer, IAX_TRUNK);
09007             }
09008          } else if (!strcasecmp(v->name, "auth")) {
09009             peer->authmethods = get_auth_methods(v->value);
09010          } else if (!strcasecmp(v->name, "encryption")) {
09011             peer->encmethods = get_encrypt_methods(v->value);
09012          } else if (!strcasecmp(v->name, "notransfer")) {
09013             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09014             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09015             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09016          } else if (!strcasecmp(v->name, "transfer")) {
09017             if (!strcasecmp(v->value, "mediaonly")) {
09018                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09019             } else if (ast_true(v->value)) {
09020                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09021             } else 
09022                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09023          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09024             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09025          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09026             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09027          } else if (!strcasecmp(v->name, "host")) {
09028             if (!strcasecmp(v->value, "dynamic")) {
09029                /* They'll register with us */
09030                ast_set_flag(peer, IAX_DYNAMIC); 
09031                if (!found) {
09032                   /* Initialize stuff iff we're not found, otherwise
09033                      we keep going with what we had */
09034                   memset(&peer->addr.sin_addr, 0, 4);
09035                   if (peer->addr.sin_port) {
09036                      /* If we've already got a port, make it the default rather than absolute */
09037                      peer->defaddr.sin_port = peer->addr.sin_port;
09038                      peer->addr.sin_port = 0;
09039                   }
09040                }
09041             } else {
09042                /* Non-dynamic.  Make sure we become that way if we're not */
09043                if (peer->expire > -1)
09044                   ast_sched_del(sched, peer->expire);
09045                peer->expire = -1;
09046                ast_clear_flag(peer, IAX_DYNAMIC);
09047                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
09048                   ast_string_field_free_pools(peer);
09049                   return peer_unref(peer);
09050                }
09051                if (!peer->addr.sin_port)
09052                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09053             }
09054             if (!maskfound)
09055                inet_aton("255.255.255.255", &peer->mask);
09056          } else if (!strcasecmp(v->name, "defaultip")) {
09057             if (ast_get_ip(&peer->defaddr, v->value)) {
09058                ast_string_field_free_pools(peer);
09059                return peer_unref(peer);
09060             }
09061          } else if (!strcasecmp(v->name, "sourceaddress")) {
09062             peer_set_srcaddr(peer, v->value);
09063          } else if (!strcasecmp(v->name, "permit") ||
09064                   !strcasecmp(v->name, "deny")) {
09065             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09066          } else if (!strcasecmp(v->name, "mask")) {
09067             maskfound++;
09068             inet_aton(v->value, &peer->mask);
09069          } else if (!strcasecmp(v->name, "context")) {
09070             ast_string_field_set(peer, context, v->value);
09071          } else if (!strcasecmp(v->name, "regexten")) {
09072             ast_string_field_set(peer, regexten, v->value);
09073          } else if (!strcasecmp(v->name, "peercontext")) {
09074             ast_string_field_set(peer, peercontext, v->value);
09075          } else if (!strcasecmp(v->name, "port")) {
09076             if (ast_test_flag(peer, IAX_DYNAMIC))
09077                peer->defaddr.sin_port = htons(atoi(v->value));
09078             else
09079                peer->addr.sin_port = htons(atoi(v->value));
09080          } else if (!strcasecmp(v->name, "username")) {
09081             ast_string_field_set(peer, username, v->value);
09082          } else if (!strcasecmp(v->name, "allow")) {
09083             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09084          } else if (!strcasecmp(v->name, "disallow")) {
09085             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09086          } else if (!strcasecmp(v->name, "callerid")) {
09087             if (!ast_strlen_zero(v->value)) {
09088                char name2[80];
09089                char num2[80];
09090                ast_callerid_split(v->value, name2, 80, num2, 80);
09091                ast_string_field_set(peer, cid_name, name2);
09092                ast_string_field_set(peer, cid_num, num2);
09093                ast_set_flag(peer, IAX_HASCALLERID);
09094             } else {
09095                ast_clear_flag(peer, IAX_HASCALLERID);
09096                ast_string_field_set(peer, cid_name, "");
09097                ast_string_field_set(peer, cid_num, "");
09098             }
09099          } else if (!strcasecmp(v->name, "fullname")) {
09100             if (!ast_strlen_zero(v->value)) {
09101                ast_string_field_set(peer, cid_name, v->value);
09102                ast_set_flag(peer, IAX_HASCALLERID);
09103             } else {
09104                ast_string_field_set(peer, cid_name, "");
09105                if (ast_strlen_zero(peer->cid_num))
09106                   ast_clear_flag(peer, IAX_HASCALLERID);
09107             }
09108          } else if (!strcasecmp(v->name, "cid_number")) {
09109             if (!ast_strlen_zero(v->value)) {
09110                ast_string_field_set(peer, cid_num, v->value);
09111                ast_set_flag(peer, IAX_HASCALLERID);
09112             } else {
09113                ast_string_field_set(peer, cid_num, "");
09114                if (ast_strlen_zero(peer->cid_name))
09115                   ast_clear_flag(peer, IAX_HASCALLERID);
09116             }
09117          } else if (!strcasecmp(v->name, "sendani")) {
09118             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09119          } else if (!strcasecmp(v->name, "inkeys")) {
09120             ast_string_field_set(peer, inkeys, v->value);
09121          } else if (!strcasecmp(v->name, "outkey")) {
09122             ast_string_field_set(peer, outkey, v->value);
09123          } else if (!strcasecmp(v->name, "qualify")) {
09124             if (!strcasecmp(v->value, "no")) {
09125                peer->maxms = 0;
09126             } else if (!strcasecmp(v->value, "yes")) {
09127                peer->maxms = DEFAULT_MAXMS;
09128             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09129                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);
09130                peer->maxms = 0;
09131             }
09132          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09133             peer->smoothing = ast_true(v->value);
09134          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09135             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09136                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);
09137             }
09138          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09139             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09140                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);
09141             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09142          } else if (!strcasecmp(v->name, "timezone")) {
09143             ast_string_field_set(peer, zonetag, v->value);
09144          } else if (!strcasecmp(v->name, "adsi")) {
09145             peer->adsi = ast_true(v->value);
09146          }/* else if (strcasecmp(v->name,"type")) */
09147          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09148          v = v->next;
09149          if (!v) {
09150             v = alt;
09151             alt = NULL;
09152          }
09153       }
09154       if (!peer->authmethods)
09155          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09156       ast_clear_flag(peer, IAX_DELME); 
09157       /* Make sure these are IPv4 addresses */
09158       peer->addr.sin_family = AF_INET;
09159    }
09160    if (oldha)
09161       ast_free_ha(oldha);
09162    return peer;
09163 }
09164 
09165 static void user_destructor(void *obj)
09166 {
09167    struct iax2_user *user = obj;
09168 
09169    ast_free_ha(user->ha);
09170    free_context(user->contexts);
09171    if(user->vars) {
09172       ast_variables_destroy(user->vars);
09173       user->vars = NULL;
09174    }
09175    ast_string_field_free_pools(user);
09176 }
09177 
09178 /*! \brief Create in-memory user structure from configuration */
09179 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09180 {
09181    struct iax2_user *user = NULL;
09182    struct iax2_context *con, *conl = NULL;
09183    struct ast_ha *oldha = NULL;
09184    struct iax2_context *oldcon = NULL;
09185    int format;
09186    int firstpass=1;
09187    int oldcurauthreq = 0;
09188    char *varname = NULL, *varval = NULL;
09189    struct ast_variable *tmpvar = NULL;
09190    struct iax2_user tmp_user = {
09191       .name = name,
09192    };
09193 
09194    if (!temponly) {
09195       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09196       if (user && !ast_test_flag(user, IAX_DELME))
09197          firstpass = 0;
09198    }
09199 
09200    if (user) {
09201       if (firstpass) {
09202          oldcurauthreq = user->curauthreq;
09203          oldha = user->ha;
09204          oldcon = user->contexts;
09205          user->ha = NULL;
09206          user->contexts = NULL;
09207       }
09208       /* Already in the list, remove it and it will be added back (or FREE'd) */
09209       ao2_unlink(users, user);
09210    } else {
09211       user = ao2_alloc(sizeof(*user), user_destructor);
09212    }
09213    
09214    if (user) {
09215       if (firstpass) {
09216          ast_string_field_free_pools(user);
09217          memset(user, 0, sizeof(struct iax2_user));
09218          if (ast_string_field_init(user, 32)) {
09219             user = user_unref(user);
09220             goto cleanup;
09221          }
09222          user->maxauthreq = maxauthreq;
09223          user->curauthreq = oldcurauthreq;
09224          user->prefs = prefs;
09225          user->capability = iax2_capability;
09226          user->encmethods = iax2_encryption;
09227          user->adsi = adsi;
09228          ast_string_field_set(user, name, name);
09229          ast_string_field_set(user, language, language);
09230          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09231          ast_clear_flag(user, IAX_HASCALLERID);
09232          ast_string_field_set(user, cid_name, "");
09233          ast_string_field_set(user, cid_num, "");
09234       }
09235       if (!v) {
09236          v = alt;
09237          alt = NULL;
09238       }
09239       while(v) {
09240          if (!strcasecmp(v->name, "context")) {
09241             con = build_context(v->value);
09242             if (con) {
09243                if (conl)
09244                   conl->next = con;
09245                else
09246                   user->contexts = con;
09247                conl = con;
09248             }
09249          } else if (!strcasecmp(v->name, "permit") ||
09250                   !strcasecmp(v->name, "deny")) {
09251             user->ha = ast_append_ha(v->name, v->value, user->ha);
09252          } else if (!strcasecmp(v->name, "setvar")) {
09253             varname = ast_strdupa(v->value);
09254             if (varname && (varval = strchr(varname,'='))) {
09255                *varval = '\0';
09256                varval++;
09257                if((tmpvar = ast_variable_new(varname, varval))) {
09258                   tmpvar->next = user->vars; 
09259                   user->vars = tmpvar;
09260                }
09261             }
09262          } else if (!strcasecmp(v->name, "allow")) {
09263             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09264          } else if (!strcasecmp(v->name, "disallow")) {
09265             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09266          } else if (!strcasecmp(v->name, "trunk")) {
09267             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09268             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09269                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09270                ast_clear_flag(user, IAX_TRUNK);
09271             }
09272          } else if (!strcasecmp(v->name, "auth")) {
09273             user->authmethods = get_auth_methods(v->value);
09274          } else if (!strcasecmp(v->name, "encryption")) {
09275             user->encmethods = get_encrypt_methods(v->value);
09276          } else if (!strcasecmp(v->name, "notransfer")) {
09277             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09278             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09279             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09280          } else if (!strcasecmp(v->name, "transfer")) {
09281             if (!strcasecmp(v->value, "mediaonly")) {
09282                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09283             } else if (ast_true(v->value)) {
09284                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09285             } else 
09286                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09287          } else if (!strcasecmp(v->name, "codecpriority")) {
09288             if(!strcasecmp(v->value, "caller"))
09289                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09290             else if(!strcasecmp(v->value, "disabled"))
09291                ast_set_flag(user, IAX_CODEC_NOPREFS);
09292             else if(!strcasecmp(v->value, "reqonly")) {
09293                ast_set_flag(user, IAX_CODEC_NOCAP);
09294                ast_set_flag(user, IAX_CODEC_NOPREFS);
09295             }
09296          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09297             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09298          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09299             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09300          } else if (!strcasecmp(v->name, "dbsecret")) {
09301             ast_string_field_set(user, dbsecret, v->value);
09302          } else if (!strcasecmp(v->name, "secret")) {
09303             if (!ast_strlen_zero(user->secret)) {
09304                char *old = ast_strdupa(user->secret);
09305 
09306                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09307             } else
09308                ast_string_field_set(user, secret, v->value);
09309          } else if (!strcasecmp(v->name, "callerid")) {
09310             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09311                char name2[80];
09312                char num2[80];
09313                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09314                ast_string_field_set(user, cid_name, name2);
09315                ast_string_field_set(user, cid_num, num2);
09316                ast_set_flag(user, IAX_HASCALLERID);
09317             } else {
09318                ast_clear_flag(user, IAX_HASCALLERID);
09319                ast_string_field_set(user, cid_name, "");
09320                ast_string_field_set(user, cid_num, "");
09321             }
09322          } else if (!strcasecmp(v->name, "fullname")) {
09323             if (!ast_strlen_zero(v->value)) {
09324                ast_string_field_set(user, cid_name, v->value);
09325                ast_set_flag(user, IAX_HASCALLERID);
09326             } else {
09327                ast_string_field_set(user, cid_name, "");
09328                if (ast_strlen_zero(user->cid_num))
09329                   ast_clear_flag(user, IAX_HASCALLERID);
09330             }
09331          } else if (!strcasecmp(v->name, "cid_number")) {
09332             if (!ast_strlen_zero(v->value)) {
09333                ast_string_field_set(user, cid_num, v->value);
09334                ast_set_flag(user, IAX_HASCALLERID);
09335             } else {
09336                ast_string_field_set(user, cid_num, "");
09337                if (ast_strlen_zero(user->cid_name))
09338                   ast_clear_flag(user, IAX_HASCALLERID);
09339             }
09340          } else if (!strcasecmp(v->name, "accountcode")) {
09341             ast_string_field_set(user, accountcode, v->value);
09342          } else if (!strcasecmp(v->name, "mohinterpret")) {
09343             ast_string_field_set(user, mohinterpret, v->value);
09344          } else if (!strcasecmp(v->name, "mohsuggest")) {
09345             ast_string_field_set(user, mohsuggest, v->value);
09346          } else if (!strcasecmp(v->name, "language")) {
09347             ast_string_field_set(user, language, v->value);
09348          } else if (!strcasecmp(v->name, "amaflags")) {
09349             format = ast_cdr_amaflags2int(v->value);
09350             if (format < 0) {
09351                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09352             } else {
09353                user->amaflags = format;
09354             }
09355          } else if (!strcasecmp(v->name, "inkeys")) {
09356             ast_string_field_set(user, inkeys, v->value);
09357          } else if (!strcasecmp(v->name, "maxauthreq")) {
09358             user->maxauthreq = atoi(v->value);
09359             if (user->maxauthreq < 0)
09360                user->maxauthreq = 0;
09361          } else if (!strcasecmp(v->name, "adsi")) {
09362             user->adsi = ast_true(v->value);
09363          }/* else if (strcasecmp(v->name,"type")) */
09364          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09365          v = v->next;
09366          if (!v) {
09367             v = alt;
09368             alt = NULL;
09369          }
09370       }
09371       if (!user->authmethods) {
09372          if (!ast_strlen_zero(user->secret)) {
09373             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09374             if (!ast_strlen_zero(user->inkeys))
09375                user->authmethods |= IAX_AUTH_RSA;
09376          } else if (!ast_strlen_zero(user->inkeys)) {
09377             user->authmethods = IAX_AUTH_RSA;
09378          } else {
09379             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09380          }
09381       }
09382       ast_clear_flag(user, IAX_DELME);
09383    }
09384 cleanup:
09385    if (oldha)
09386       ast_free_ha(oldha);
09387    if (oldcon)
09388       free_context(oldcon);
09389    return user;
09390 }
09391 
09392 static int peer_delme_cb(void *obj, void *arg, int flags)
09393 {
09394    struct iax2_peer *peer = obj;
09395 
09396    ast_set_flag(peer, IAX_DELME);
09397 
09398    return 0;
09399 }
09400 
09401 static int user_delme_cb(void *obj, void *arg, int flags)
09402 {
09403    struct iax2_user *user = obj;
09404 
09405    ast_set_flag(user, IAX_DELME);
09406 
09407    return 0;
09408 }
09409 
09410 static void delete_users(void)
09411 {
09412    struct iax2_registry *reg;
09413 
09414    ao2_callback(users, 0, user_delme_cb, NULL);
09415 
09416    AST_LIST_LOCK(&registrations);
09417    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09418       if (reg->expire > -1)
09419          ast_sched_del(sched, reg->expire);
09420       if (reg->callno) {
09421          ast_mutex_lock(&iaxsl[reg->callno]);
09422          if (iaxs[reg->callno]) {
09423             iaxs[reg->callno]->reg = NULL;
09424             iax2_destroy(reg->callno);
09425          }
09426          ast_mutex_unlock(&iaxsl[reg->callno]);
09427       }
09428       if (reg->dnsmgr)
09429          ast_dnsmgr_release(reg->dnsmgr);
09430       free(reg);
09431    }
09432    AST_LIST_UNLOCK(&registrations);
09433 
09434    ao2_callback(peers, 0, peer_delme_cb, NULL);
09435 }
09436 
09437 static void prune_users(void)
09438 {
09439    struct iax2_user *user;
09440    ao2_iterator i;
09441 
09442    i = ao2_iterator_init(users, 0);
09443    while ((user = ao2_iterator_next(&i))) {
09444       if (ast_test_flag(user, IAX_DELME))
09445          ao2_unlink(users, user);
09446       user_unref(user);
09447    }
09448 }
09449 
09450 /* Prune peers who still are supposed to be deleted */
09451 static void prune_peers(void)
09452 {
09453    struct iax2_peer *peer;
09454    ao2_iterator i;
09455 
09456    i = ao2_iterator_init(peers, 0);
09457    while ((peer = ao2_iterator_next(&i))) {
09458       if (ast_test_flag(peer, IAX_DELME))
09459          ao2_unlink(peers, peer);
09460       peer_unref(peer);
09461    }
09462 }
09463 
09464 static void set_timing(void)
09465 {
09466 #ifdef HAVE_ZAPTEL
09467    int bs = trunkfreq * 8;
09468    if (timingfd > -1) {
09469       if (
09470 #ifdef ZT_TIMERACK
09471          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09472 #endif         
09473          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09474          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09475    }
09476 #endif
09477 }
09478 
09479 
09480 /*! \brief Load configuration */
09481 static int set_config(char *config_file, int reload)
09482 {
09483    struct ast_config *cfg, *ucfg;
09484    int capability=iax2_capability;
09485    struct ast_variable *v;
09486    char *cat;
09487    const char *utype;
09488    const char *tosval;
09489    int format;
09490    int portno = IAX_DEFAULT_PORTNO;
09491    int  x;
09492    struct iax2_user *user;
09493    struct iax2_peer *peer;
09494    struct ast_netsock *ns;
09495 #if 0
09496    static unsigned short int last_port=0;
09497 #endif
09498 
09499    cfg = ast_config_load(config_file);
09500    
09501    if (!cfg) {
09502       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09503       return -1;
09504    }
09505 
09506    /* Reset global codec prefs */   
09507    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09508    
09509    /* Reset Global Flags */
09510    memset(&globalflags, 0, sizeof(globalflags));
09511    ast_set_flag(&globalflags, IAX_RTUPDATE);
09512 
09513 #ifdef SO_NO_CHECK
09514    nochecksums = 0;
09515 #endif
09516 
09517    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09518    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09519 
09520    maxauthreq = 3;
09521 
09522    v = ast_variable_browse(cfg, "general");
09523 
09524    /* Seed initial tos value */
09525    tosval = ast_variable_retrieve(cfg, "general", "tos");
09526    if (tosval) {
09527       if (ast_str2tos(tosval, &tos))
09528          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09529    }
09530    while(v) {
09531       if (!strcasecmp(v->name, "bindport")){ 
09532          if (reload)
09533             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09534          else
09535             portno = atoi(v->value);
09536       } else if (!strcasecmp(v->name, "pingtime")) 
09537          ping_time = atoi(v->value);
09538       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09539          if (reload) {
09540             if (atoi(v->value) != iaxthreadcount)
09541                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09542          } else {
09543             iaxthreadcount = atoi(v->value);
09544             if (iaxthreadcount < 1) {
09545                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09546                iaxthreadcount = 1;
09547             } else if (iaxthreadcount > 256) {
09548                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09549                iaxthreadcount = 256;
09550             }
09551          }
09552       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09553          if (reload) {
09554             AST_LIST_LOCK(&dynamic_list);
09555             iaxmaxthreadcount = atoi(v->value);
09556             AST_LIST_UNLOCK(&dynamic_list);
09557          } else {
09558             iaxmaxthreadcount = atoi(v->value);
09559             if (iaxmaxthreadcount < 0) {
09560                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09561                iaxmaxthreadcount = 0;
09562             } else if (iaxmaxthreadcount > 256) {
09563                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09564                iaxmaxthreadcount = 256;
09565             }
09566          }
09567       } else if (!strcasecmp(v->name, "nochecksums")) {
09568 #ifdef SO_NO_CHECK
09569          if (ast_true(v->value))
09570             nochecksums = 1;
09571          else
09572             nochecksums = 0;
09573 #else
09574          if (ast_true(v->value))
09575             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09576 #endif
09577       }
09578       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09579          maxjitterbuffer = atoi(v->value);
09580       else if (!strcasecmp(v->name, "resyncthreshold")) 
09581          resyncthreshold = atoi(v->value);
09582       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09583          maxjitterinterps = atoi(v->value);
09584       else if (!strcasecmp(v->name, "lagrqtime")) 
09585          lagrq_time = atoi(v->value);
09586       else if (!strcasecmp(v->name, "maxregexpire")) 
09587          max_reg_expire = atoi(v->value);
09588       else if (!strcasecmp(v->name, "minregexpire")) 
09589          min_reg_expire = atoi(v->value);
09590       else if (!strcasecmp(v->name, "bindaddr")) {
09591          if (reload) {
09592             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09593          } else {
09594             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09595                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09596             } else {
09597                if (option_verbose > 1) {
09598                   if (strchr(v->value, ':'))
09599                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09600                   else
09601                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09602                }
09603                if (defaultsockfd < 0) 
09604                   defaultsockfd = ast_netsock_sockfd(ns);
09605                ast_netsock_unref(ns);
09606             }
09607          }
09608       } else if (!strcasecmp(v->name, "authdebug"))
09609          authdebug = ast_true(v->value);
09610       else if (!strcasecmp(v->name, "encryption"))
09611          iax2_encryption = get_encrypt_methods(v->value);
09612       else if (!strcasecmp(v->name, "notransfer")) {
09613          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09614          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09615          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09616       } else if (!strcasecmp(v->name, "transfer")) {
09617          if (!strcasecmp(v->value, "mediaonly")) {
09618             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09619          } else if (ast_true(v->value)) {
09620             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09621          } else 
09622             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09623       } else if (!strcasecmp(v->name, "codecpriority")) {
09624          if(!strcasecmp(v->value, "caller"))
09625             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09626          else if(!strcasecmp(v->value, "disabled"))
09627             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09628          else if(!strcasecmp(v->value, "reqonly")) {
09629             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09630             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09631          }
09632       } else if (!strcasecmp(v->name, "jitterbuffer"))
09633          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
09634       else if (!strcasecmp(v->name, "forcejitterbuffer"))
09635          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
09636       else if (!strcasecmp(v->name, "delayreject"))
09637          delayreject = ast_true(v->value);
09638       else if (!strcasecmp(v->name, "rtcachefriends"))
09639          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
09640       else if (!strcasecmp(v->name, "rtignoreregexpire"))
09641          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
09642       else if (!strcasecmp(v->name, "rtupdate"))
09643          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09644       else if (!strcasecmp(v->name, "trunktimestamps"))
09645          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09646       else if (!strcasecmp(v->name, "rtautoclear")) {
09647          int i = atoi(v->value);
09648          if(i > 0)
09649             global_rtautoclear = i;
09650          else
09651             i = 0;
09652          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
09653       } else if (!strcasecmp(v->name, "trunkfreq")) {
09654          trunkfreq = atoi(v->value);
09655          if (trunkfreq < 10)
09656             trunkfreq = 10;
09657       } else if (!strcasecmp(v->name, "autokill")) {
09658          if (sscanf(v->value, "%d", &x) == 1) {
09659             if (x >= 0)
09660                autokill = x;
09661             else
09662                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09663          } else if (ast_true(v->value)) {
09664             autokill = DEFAULT_MAXMS;
09665          } else {
09666             autokill = 0;
09667          }
09668       } else if (!strcasecmp(v->name, "bandwidth")) {
09669          if (!strcasecmp(v->value, "low")) {
09670             capability = IAX_CAPABILITY_LOWBANDWIDTH;
09671          } else if (!strcasecmp(v->value, "medium")) {
09672             capability = IAX_CAPABILITY_MEDBANDWIDTH;
09673          } else if (!strcasecmp(v->value, "high")) {
09674             capability = IAX_CAPABILITY_FULLBANDWIDTH;
09675          } else
09676             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09677       } else if (!strcasecmp(v->name, "allow")) {
09678          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09679       } else if (!strcasecmp(v->name, "disallow")) {
09680          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09681       } else if (!strcasecmp(v->name, "register")) {
09682          iax2_register(v->value, v->lineno);
09683       } else if (!strcasecmp(v->name, "iaxcompat")) {
09684          iaxcompat = ast_true(v->value);
09685       } else if (!strcasecmp(v->name, "regcontext")) {
09686          ast_copy_string(regcontext, v->value, sizeof(regcontext));
09687          /* Create context if it doesn't exist already */
09688          if (!ast_context_find(regcontext))
09689             ast_context_create(NULL, regcontext, "IAX2");
09690       } else if (!strcasecmp(v->name, "tos")) {
09691          if (ast_str2tos(v->value, &tos))
09692             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09693       } else if (!strcasecmp(v->name, "accountcode")) {
09694          ast_copy_string(accountcode, v->value, sizeof(accountcode));
09695       } else if (!strcasecmp(v->name, "mohinterpret")) {
09696          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09697       } else if (!strcasecmp(v->name, "mohsuggest")) {
09698          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09699       } else if (!strcasecmp(v->name, "amaflags")) {
09700          format = ast_cdr_amaflags2int(v->value);
09701          if (format < 0) {
09702             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09703          } else {
09704             amaflags = format;
09705          }
09706       } else if (!strcasecmp(v->name, "language")) {
09707          ast_copy_string(language, v->value, sizeof(language));
09708       } else if (!strcasecmp(v->name, "maxauthreq")) {
09709          maxauthreq = atoi(v->value);
09710          if (maxauthreq < 0)
09711             maxauthreq = 0;
09712       } else if (!strcasecmp(v->name, "adsi")) {
09713          adsi = ast_true(v->value);
09714       } /*else if (strcasecmp(v->name,"type")) */
09715       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09716       v = v->next;
09717    }
09718    
09719    if (defaultsockfd < 0) {
09720       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09721          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09722       } else {
09723          if (option_verbose > 1)
09724             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09725          defaultsockfd = ast_netsock_sockfd(ns);
09726          ast_netsock_unref(ns);
09727       }
09728    }
09729    if (reload) {
09730       ast_netsock_release(outsock);
09731       outsock = ast_netsock_list_alloc();
09732       if (!outsock) {
09733          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09734          return -1;
09735       }
09736       ast_netsock_init(outsock);
09737    }
09738 
09739    if (min_reg_expire > max_reg_expire) {
09740       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09741          min_reg_expire, max_reg_expire, max_reg_expire);
09742       min_reg_expire = max_reg_expire;
09743    }
09744    iax2_capability = capability;
09745    
09746    ucfg = ast_config_load("users.conf");
09747    if (ucfg) {
09748       struct ast_variable *gen;
09749       int genhasiax;
09750       int genregisteriax;
09751       const char *hasiax, *registeriax;
09752       
09753       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09754       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09755       gen = ast_variable_browse(ucfg, "general");
09756       cat = ast_category_browse(ucfg, NULL);
09757       while (cat) {
09758          if (strcasecmp(cat, "general")) {
09759             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09760             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09761             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09762                /* Start with general parameters, then specific parameters, user and peer */
09763                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09764                if (user) {
09765                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09766                   user = NULL;
09767                }
09768                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09769                if (peer) {
09770                   if (ast_test_flag(peer, IAX_DYNAMIC))
09771                      reg_source_db(peer);
09772                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09773                   peer = NULL;
09774                }
09775             }
09776             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09777                char tmp[256];
09778                const char *host = ast_variable_retrieve(ucfg, cat, "host");
09779                const char *username = ast_variable_retrieve(ucfg, cat, "username");
09780                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09781                if (!host)
09782                   host = ast_variable_retrieve(ucfg, "general", "host");
09783                if (!username)
09784                   username = ast_variable_retrieve(ucfg, "general", "username");
09785                if (!secret)
09786                   secret = ast_variable_retrieve(ucfg, "general", "secret");
09787                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09788                   if (!ast_strlen_zero(secret))
09789                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09790                   else
09791                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09792                   iax2_register(tmp, 0);
09793                }
09794             }
09795          }
09796          cat = ast_category_browse(ucfg, cat);
09797       }
09798       ast_config_destroy(ucfg);
09799    }
09800    
09801    cat = ast_category_browse(cfg, NULL);
09802    while(cat) {
09803       if (strcasecmp(cat, "general")) {
09804          utype = ast_variable_retrieve(cfg, cat, "type");
09805          if (utype) {
09806             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09807                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09808                if (user) {
09809                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09810                   user = NULL;
09811                }
09812             }
09813             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09814                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09815                if (peer) {
09816                   if (ast_test_flag(peer, IAX_DYNAMIC))
09817                      reg_source_db(peer);
09818                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09819                   peer = NULL;
09820                }
09821             } else if (strcasecmp(utype, "user")) {
09822                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
09823             }
09824          } else
09825             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
09826       }
09827       cat = ast_category_browse(cfg, cat);
09828    }
09829    ast_config_destroy(cfg);
09830    set_timing();
09831    return capability;
09832 }
09833 
09834 static int reload_config(void)
09835 {
09836    char *config = "iax.conf";
09837    struct iax2_registry *reg;
09838 
09839    strcpy(accountcode, "");
09840    strcpy(language, "");
09841    strcpy(mohinterpret, "default");
09842    strcpy(mohsuggest, "");
09843    amaflags = 0;
09844    delayreject = 0;
09845    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09846    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09847    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09848    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09849    delete_users();
09850    set_config(config, 1);
09851    prune_peers();
09852    prune_users();
09853    AST_LIST_LOCK(&registrations);
09854    AST_LIST_TRAVERSE(&registrations, reg, entry)
09855       iax2_do_register(reg);
09856    AST_LIST_UNLOCK(&registrations);
09857    /* Qualify hosts, too */
09858    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
09859    reload_firmware();
09860    iax_provision_reload();
09861 
09862    return 0;
09863 }
09864 
09865 static int iax2_reload(int fd, int argc, char *argv[])
09866 {
09867    return reload_config();
09868 }
09869 
09870 static int reload(void)
09871 {
09872    return reload_config();
09873 }
09874 
09875 static int cache_get_callno_locked(const char *data)
09876 {
09877    struct sockaddr_in sin;
09878    int x;
09879    int callno;
09880    struct iax_ie_data ied;
09881    struct create_addr_info cai;
09882    struct parsed_dial_string pds;
09883    char *tmpstr;
09884 
09885    for (x=0; x<IAX_MAX_CALLS; x++) {
09886       /* Look for an *exact match* call.  Once a call is negotiated, it can only
09887          look up entries for a single context */
09888       if (!ast_mutex_trylock(&iaxsl[x])) {
09889          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09890             return x;
09891          ast_mutex_unlock(&iaxsl[x]);
09892       }
09893    }
09894 
09895    /* No match found, we need to create a new one */
09896 
09897    memset(&cai, 0, sizeof(cai));
09898    memset(&ied, 0, sizeof(ied));
09899    memset(&pds, 0, sizeof(pds));
09900 
09901    tmpstr = ast_strdupa(data);
09902    parse_dial_string(tmpstr, &pds);
09903 
09904    /* Populate our address from the given */
09905    if (create_addr(pds.peer, &sin, &cai))
09906       return -1;
09907 
09908    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09909       pds.peer, pds.username, pds.password, pds.context);
09910 
09911    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
09912    if (callno < 1) {
09913       ast_log(LOG_WARNING, "Unable to create call\n");
09914       return -1;
09915    }
09916 
09917    ast_mutex_lock(&iaxsl[callno]);
09918    ast_string_field_set(iaxs[callno], dproot, data);
09919    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09920 
09921    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09922    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09923    /* the string format is slightly different from a standard dial string,
09924       because the context appears in the 'exten' position
09925    */
09926    if (pds.exten)
09927       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09928    if (pds.username)
09929       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09930    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09931    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09932    /* Keep password handy */
09933    if (pds.password)
09934       ast_string_field_set(iaxs[callno], secret, pds.password);
09935    if (pds.key)
09936       ast_string_field_set(iaxs[callno], outkey, pds.key);
09937    /* Start the call going */
09938    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09939 
09940    return callno;
09941 }
09942 
09943 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
09944 {
09945    struct iax2_dpcache *dp, *prev = NULL, *next;
09946    struct timeval tv;
09947    int x;
09948    int com[2];
09949    int timeout;
09950    int old=0;
09951    int outfd;
09952    int abort;
09953    int callno;
09954    struct ast_channel *c;
09955    struct ast_frame *f;
09956    gettimeofday(&tv, NULL);
09957    dp = dpcache;
09958    while(dp) {
09959       next = dp->next;
09960       /* Expire old caches */
09961       if (ast_tvcmp(tv, dp->expiry) > 0) {
09962             /* It's expired, let it disappear */
09963             if (prev)
09964                prev->next = dp->next;
09965             else
09966                dpcache = dp->next;
09967             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09968                /* Free memory and go again */
09969                free(dp);
09970             } else {
09971                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);
09972             }
09973             dp = next;
09974             continue;
09975       }
09976       /* We found an entry that matches us! */
09977       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
09978          break;
09979       prev = dp;
09980       dp = next;
09981    }
09982    if (!dp) {
09983       /* No matching entry.  Create a new one. */
09984       /* First, can we make a callno? */
09985       callno = cache_get_callno_locked(data);
09986       if (callno < 0) {
09987          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09988          return NULL;
09989       }
09990       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
09991          ast_mutex_unlock(&iaxsl[callno]);
09992          return NULL;
09993       }
09994       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09995       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09996       gettimeofday(&dp->expiry, NULL);
09997       dp->orig = dp->expiry;
09998       /* Expires in 30 mins by default */
09999       dp->expiry.tv_sec += iaxdefaultdpcache;
10000       dp->next = dpcache;
10001       dp->flags = CACHE_FLAG_PENDING;
10002       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10003          dp->waiters[x] = -1;
10004       dpcache = dp;
10005       dp->peer = iaxs[callno]->dpentries;
10006       iaxs[callno]->dpentries = dp;
10007       /* Send the request if we're already up */
10008       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10009          iax2_dprequest(dp, callno);
10010       ast_mutex_unlock(&iaxsl[callno]);
10011    }
10012    /* By here we must have a dp */
10013    if (dp->flags & CACHE_FLAG_PENDING) {
10014       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10015          for a reply to come back so long as it's pending */
10016       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10017          /* Find an empty slot */
10018          if (dp->waiters[x] < 0)
10019             break;
10020       }
10021       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10022          ast_log(LOG_WARNING, "No more waiter positions available\n");
10023          return NULL;
10024       }
10025       if (pipe(com)) {
10026          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10027          return NULL;
10028       }
10029       dp->waiters[x] = com[1];
10030       /* Okay, now we wait */
10031       timeout = iaxdefaulttimeout * 1000;
10032       /* Temporarily unlock */
10033       ast_mutex_unlock(&dpcache_lock);
10034       /* Defer any dtmf */
10035       if (chan)
10036          old = ast_channel_defer_dtmf(chan);
10037       abort = 0;
10038       while(timeout) {
10039          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10040          if (outfd > -1) {
10041             break;
10042          }
10043          if (c) {
10044             f = ast_read(c);
10045             if (f)
10046                ast_frfree(f);
10047             else {
10048                /* Got hung up on, abort! */
10049                break;
10050                abort = 1;
10051             }
10052          }
10053       }
10054       if (!timeout) {
10055          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10056       }
10057       ast_mutex_lock(&dpcache_lock);
10058       dp->waiters[x] = -1;
10059       close(com[1]);
10060       close(com[0]);
10061       if (abort) {
10062          /* Don't interpret anything, just abort.  Not sure what th epoint
10063            of undeferring dtmf on a hung up channel is but hey whatever */
10064          if (!old && chan)
10065             ast_channel_undefer_dtmf(chan);
10066          return NULL;
10067       }
10068       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10069          /* Now to do non-independent analysis the results of our wait */
10070          if (dp->flags & CACHE_FLAG_PENDING) {
10071             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10072                pending.  Don't let it take as long to timeout. */
10073             dp->flags &= ~CACHE_FLAG_PENDING;
10074             dp->flags |= CACHE_FLAG_TIMEOUT;
10075             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10076                systems without leaving it unavailable once the server comes back online */
10077             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10078             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10079                if (dp->waiters[x] > -1)
10080                   write(dp->waiters[x], "asdf", 4);
10081          }
10082       }
10083       /* Our caller will obtain the rest */
10084       if (!old && chan)
10085          ast_channel_undefer_dtmf(chan);
10086    }
10087    return dp;  
10088 }
10089 
10090 /*! \brief Part of the IAX2 switch interface */
10091 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10092 {
10093    struct iax2_dpcache *dp;
10094    int res = 0;
10095 #if 0
10096    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10097 #endif
10098    if ((priority != 1) && (priority != 2))
10099       return 0;
10100    ast_mutex_lock(&dpcache_lock);
10101    dp = find_cache(chan, data, context, exten, priority);
10102    if (dp) {
10103       if (dp->flags & CACHE_FLAG_EXISTS)
10104          res= 1;
10105    }
10106    ast_mutex_unlock(&dpcache_lock);
10107    if (!dp) {
10108       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10109    }
10110    return res;
10111 }
10112 
10113 /*! \brief part of the IAX2 dial plan switch interface */
10114 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10115 {
10116    int res = 0;
10117    struct iax2_dpcache *dp;
10118 #if 0
10119    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10120 #endif
10121    if ((priority != 1) && (priority != 2))
10122       return 0;
10123    ast_mutex_lock(&dpcache_lock);
10124    dp = find_cache(chan, data, context, exten, priority);
10125    if (dp) {
10126       if (dp->flags & CACHE_FLAG_CANEXIST)
10127          res= 1;
10128    }
10129    ast_mutex_unlock(&dpcache_lock);
10130    if (!dp) {
10131       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10132    }
10133    return res;
10134 }
10135 
10136 /*! \brief Part of the IAX2 Switch interface */
10137 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10138 {
10139    int res = 0;
10140    struct iax2_dpcache *dp;
10141 #if 0
10142    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10143 #endif
10144    if ((priority != 1) && (priority != 2))
10145       return 0;
10146    ast_mutex_lock(&dpcache_lock);
10147    dp = find_cache(chan, data, context, exten, priority);
10148    if (dp) {
10149       if (dp->flags & CACHE_FLAG_MATCHMORE)
10150          res= 1;
10151    }
10152    ast_mutex_unlock(&dpcache_lock);
10153    if (!dp) {
10154       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10155    }
10156    return res;
10157 }
10158 
10159 /*! \brief Execute IAX2 dialplan switch */
10160 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10161 {
10162    char odata[256];
10163    char req[256];
10164    char *ncontext;
10165    struct iax2_dpcache *dp;
10166    struct ast_app *dial;
10167 #if 0
10168    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);
10169 #endif
10170    if (priority == 2) {
10171       /* Indicate status, can be overridden in dialplan */
10172       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10173       if (dialstatus) {
10174          dial = pbx_findapp(dialstatus);
10175          if (dial) 
10176             pbx_exec(chan, dial, "");
10177       }
10178       return -1;
10179    } else if (priority != 1)
10180       return -1;
10181    ast_mutex_lock(&dpcache_lock);
10182    dp = find_cache(chan, data, context, exten, priority);
10183    if (dp) {
10184       if (dp->flags & CACHE_FLAG_EXISTS) {
10185          ast_copy_string(odata, data, sizeof(odata));
10186          ncontext = strchr(odata, '/');
10187          if (ncontext) {
10188             *ncontext = '\0';
10189             ncontext++;
10190             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10191          } else {
10192             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10193          }
10194          if (option_verbose > 2)
10195             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10196       } else {
10197          ast_mutex_unlock(&dpcache_lock);
10198          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10199          return -1;
10200       }
10201    }
10202    ast_mutex_unlock(&dpcache_lock);
10203    dial = pbx_findapp("Dial");
10204    if (dial) {
10205       return pbx_exec(chan, dial, req);
10206    } else {
10207       ast_log(LOG_WARNING, "No dial application registered\n");
10208    }
10209    return -1;
10210 }
10211 
10212 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10213 {
10214    struct iax2_peer *peer;
10215    char *peername, *colname;
10216 
10217    peername = ast_strdupa(data);
10218 
10219    /* if our channel, return the IP address of the endpoint of current channel */
10220    if (!strcmp(peername,"CURRENTCHANNEL")) {
10221            unsigned short callno;
10222       if (chan->tech != &iax2_tech)
10223          return -1;
10224       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10225       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10226       return 0;
10227    }
10228 
10229    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10230       *colname++ = '\0';
10231    else if ((colname = strchr(peername, '|')))
10232       *colname++ = '\0';
10233    else
10234       colname = "ip";
10235 
10236    if (!(peer = find_peer(peername, 1)))
10237       return -1;
10238 
10239    if (!strcasecmp(colname, "ip")) {
10240       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10241    } else  if (!strcasecmp(colname, "status")) {
10242       peer_status(peer, buf, len); 
10243    } else  if (!strcasecmp(colname, "mailbox")) {
10244       ast_copy_string(buf, peer->mailbox, len);
10245    } else  if (!strcasecmp(colname, "context")) {
10246       ast_copy_string(buf, peer->context, len);
10247    } else  if (!strcasecmp(colname, "expire")) {
10248       snprintf(buf, len, "%d", peer->expire);
10249    } else  if (!strcasecmp(colname, "dynamic")) {
10250       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10251    } else  if (!strcasecmp(colname, "callerid_name")) {
10252       ast_copy_string(buf, peer->cid_name, len);
10253    } else  if (!strcasecmp(colname, "callerid_num")) {
10254       ast_copy_string(buf, peer->cid_num, len);
10255    } else  if (!strcasecmp(colname, "codecs")) {
10256       ast_getformatname_multiple(buf, len -1, peer->capability);
10257    } else  if (!strncasecmp(colname, "codec[", 6)) {
10258       char *codecnum, *ptr;
10259       int index = 0, codec = 0;
10260       
10261       codecnum = strchr(colname, '[');
10262       *codecnum = '\0';
10263       codecnum++;
10264       if ((ptr = strchr(codecnum, ']'))) {
10265          *ptr = '\0';
10266       }
10267       index = atoi(codecnum);
10268       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10269          ast_copy_string(buf, ast_getformatname(codec), len);
10270       }
10271    }
10272 
10273    peer_unref(peer);
10274 
10275    return 0;
10276 }
10277 
10278 struct ast_custom_function iaxpeer_function = {
10279    .name = "IAXPEER",
10280    .synopsis = "Gets IAX peer information",
10281    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10282    .read = function_iaxpeer,
10283    .desc = "If peername specified, valid items are:\n"
10284    "- ip (default)          The IP address.\n"
10285    "- status                The peer's status (if qualify=yes)\n"
10286    "- mailbox               The configured mailbox.\n"
10287    "- context               The configured context.\n"
10288    "- expire                The epoch time of the next expire.\n"
10289    "- dynamic               Is it dynamic? (yes/no).\n"
10290    "- callerid_name         The configured Caller ID name.\n"
10291    "- callerid_num          The configured Caller ID number.\n"
10292    "- codecs                The configured codecs.\n"
10293    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10294    "\n"
10295    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10296    "\n"
10297 };
10298 
10299 
10300 /*! \brief Part of the device state notification system ---*/
10301 static int iax2_devicestate(void *data) 
10302 {
10303    struct parsed_dial_string pds;
10304    char *tmp = ast_strdupa(data);
10305    struct iax2_peer *p;
10306    int res = AST_DEVICE_INVALID;
10307 
10308    memset(&pds, 0, sizeof(pds));
10309    parse_dial_string(tmp, &pds);
10310    if (ast_strlen_zero(pds.peer))
10311       return res;
10312    
10313    if (option_debug > 2)
10314       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10315 
10316    /* SLD: FIXME: second call to find_peer during registration */
10317    if (!(p = find_peer(pds.peer, 1)))
10318       return res;
10319 
10320    res = AST_DEVICE_UNAVAILABLE;
10321    if (option_debug > 2) 
10322       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10323          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10324    
10325    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10326        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10327       /* Peer is registered, or have default IP address
10328          and a valid registration */
10329       if (p->historicms == 0 || p->historicms <= p->maxms)
10330          /* let the core figure out whether it is in use or not */
10331          res = AST_DEVICE_UNKNOWN;  
10332    }
10333 
10334    peer_unref(p);
10335 
10336    return res;
10337 }
10338 
10339 static struct ast_switch iax2_switch = 
10340 {
10341    name:          "IAX2",
10342    description:      "IAX Remote Dialplan Switch",
10343    exists:        iax2_exists,
10344    canmatch:      iax2_canmatch,
10345    exec:       iax2_exec,
10346    matchmore:     iax2_matchmore,
10347 };
10348 
10349 static char show_stats_usage[] =
10350 "Usage: iax2 show stats\n"
10351 "       Display statistics on IAX channel driver.\n";
10352 
10353 static char show_cache_usage[] =
10354 "Usage: iax2 show cache\n"
10355 "       Display currently cached IAX Dialplan results.\n";
10356 
10357 static char show_peer_usage[] =
10358 "Usage: iax2 show peer <name>\n"
10359 "       Display details on specific IAX peer\n";
10360 
10361 static char prune_realtime_usage[] =
10362 "Usage: iax2 prune realtime [<peername>|all]\n"
10363 "       Prunes object(s) from the cache\n";
10364 
10365 static char iax2_reload_usage[] =
10366 "Usage: iax2 reload\n"
10367 "       Reloads IAX configuration from iax.conf\n";
10368 
10369 static char show_prov_usage[] =
10370 "Usage: iax2 provision <host> <template> [forced]\n"
10371 "       Provisions the given peer or IP address using a template\n"
10372 "       matching either 'template' or '*' if the template is not\n"
10373 "       found.  If 'forced' is specified, even empty provisioning\n"
10374 "       fields will be provisioned as empty fields.\n";
10375 
10376 static char show_users_usage[] = 
10377 "Usage: iax2 show users [like <pattern>]\n"
10378 "       Lists all known IAX2 users.\n"
10379 "       Optional regular expression pattern is used to filter the user list.\n";
10380 
10381 static char show_channels_usage[] = 
10382 "Usage: iax2 show channels\n"
10383 "       Lists all currently active IAX channels.\n";
10384 
10385 static char show_netstats_usage[] = 
10386 "Usage: iax2 show netstats\n"
10387 "       Lists network status for all currently active IAX channels.\n";
10388 
10389 static char show_threads_usage[] = 
10390 "Usage: iax2 show threads\n"
10391 "       Lists status of IAX helper threads\n";
10392 
10393 static char show_peers_usage[] = 
10394 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10395 "       Lists all known IAX2 peers.\n"
10396 "       Optional 'registered' argument lists only peers with known addresses.\n"
10397 "       Optional regular expression pattern is used to filter the peer list.\n";
10398 
10399 static char show_firmware_usage[] = 
10400 "Usage: iax2 show firmware\n"
10401 "       Lists all known IAX firmware images.\n";
10402 
10403 static char show_reg_usage[] =
10404 "Usage: iax2 show registry\n"
10405 "       Lists all registration requests and status.\n";
10406 
10407 static char debug_usage[] = 
10408 "Usage: iax2 set debug\n"
10409 "       Enables dumping of IAX packets for debugging purposes\n";
10410 
10411 static char no_debug_usage[] = 
10412 "Usage: iax2 set debug off\n"
10413 "       Disables dumping of IAX packets for debugging purposes\n";
10414 
10415 static char debug_trunk_usage[] =
10416 "Usage: iax2 set debug trunk\n"
10417 "       Requests current status of IAX trunking\n";
10418 
10419 static char no_debug_trunk_usage[] =
10420 "Usage: iax2 set debug trunk off\n"
10421 "       Requests current status of IAX trunking\n";
10422 
10423 static char debug_jb_usage[] =
10424 "Usage: iax2 set debug jb\n"
10425 "       Enables jitterbuffer debugging information\n";
10426 
10427 static char no_debug_jb_usage[] =
10428 "Usage: iax2 set debug jb off\n"
10429 "       Disables jitterbuffer debugging information\n";
10430 
10431 static char iax2_test_losspct_usage[] =
10432 "Usage: iax2 test losspct <percentage>\n"
10433 "       For testing, throws away <percentage> percent of incoming packets\n";
10434 
10435 #ifdef IAXTESTS
10436 static char iax2_test_late_usage[] =
10437 "Usage: iax2 test late <ms>\n"
10438 "       For testing, count the next frame as <ms> ms late\n";
10439 
10440 static char iax2_test_resync_usage[] =
10441 "Usage: iax2 test resync <ms>\n"
10442 "       For testing, adjust all future frames by <ms> ms\n";
10443 
10444 static char iax2_test_jitter_usage[] =
10445 "Usage: iax2 test jitter <ms> <pct>\n"
10446 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10447 #endif /* IAXTESTS */
10448 
10449 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10450    { "iax2", "trunk", "debug", NULL },
10451    iax2_do_trunk_debug, NULL,
10452    NULL };
10453 
10454 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10455    { "iax2", "jb", "debug", NULL },
10456    iax2_do_jb_debug, NULL,
10457    NULL };
10458 
10459 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10460    { "iax2", "no", "debug", NULL },
10461    iax2_no_debug, NULL,
10462    NULL };
10463 
10464 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10465    { "iax2", "no", "trunk", "debug", NULL },
10466    iax2_no_trunk_debug, NULL,
10467    NULL };
10468 
10469 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10470    { "iax2", "no", "jb", "debug", NULL },
10471    iax2_no_jb_debug, NULL,
10472    NULL };
10473 
10474 static struct ast_cli_entry cli_iax2[] = {
10475    { { "iax2", "show", "cache", NULL },
10476    iax2_show_cache, "Display IAX cached dialplan",
10477    show_cache_usage, NULL, },
10478 
10479    { { "iax2", "show", "channels", NULL },
10480    iax2_show_channels, "List active IAX channels",
10481    show_channels_usage, NULL, },
10482 
10483    { { "iax2", "show", "firmware", NULL },
10484    iax2_show_firmware, "List available IAX firmwares",
10485    show_firmware_usage, NULL, },
10486 
10487    { { "iax2", "show", "netstats", NULL },
10488    iax2_show_netstats, "List active IAX channel netstats",
10489    show_netstats_usage, NULL, },
10490 
10491    { { "iax2", "show", "peers", NULL },
10492    iax2_show_peers, "List defined IAX peers",
10493    show_peers_usage, NULL, },
10494 
10495    { { "iax2", "show", "registry", NULL },
10496    iax2_show_registry, "Display IAX registration status",
10497    show_reg_usage, NULL, },
10498 
10499    { { "iax2", "show", "stats", NULL },
10500    iax2_show_stats, "Display IAX statistics",
10501    show_stats_usage, NULL, },
10502 
10503    { { "iax2", "show", "threads", NULL },
10504    iax2_show_threads, "Display IAX helper thread info",
10505    show_threads_usage, NULL, },
10506 
10507    { { "iax2", "show", "users", NULL },
10508    iax2_show_users, "List defined IAX users",
10509    show_users_usage, NULL, },
10510 
10511    { { "iax2", "prune", "realtime", NULL },
10512    iax2_prune_realtime, "Prune a cached realtime lookup",
10513    prune_realtime_usage, complete_iax2_show_peer },
10514 
10515    { { "iax2", "reload", NULL },
10516    iax2_reload, "Reload IAX configuration",
10517    iax2_reload_usage },
10518 
10519    { { "iax2", "show", "peer", NULL },
10520    iax2_show_peer, "Show details on specific IAX peer",
10521    show_peer_usage, complete_iax2_show_peer },
10522 
10523    { { "iax2", "set", "debug", NULL },
10524    iax2_do_debug, "Enable IAX debugging",
10525    debug_usage },
10526 
10527    { { "iax2", "set", "debug", "trunk", NULL },
10528    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10529    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10530 
10531    { { "iax2", "set", "debug", "jb", NULL },
10532    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10533    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10534 
10535    { { "iax2", "set", "debug", "off", NULL },
10536    iax2_no_debug, "Disable IAX debugging",
10537    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10538 
10539    { { "iax2", "set", "debug", "trunk", "off", NULL },
10540    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10541    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10542 
10543    { { "iax2", "set", "debug", "jb", "off", NULL },
10544    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10545    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10546 
10547    { { "iax2", "test", "losspct", NULL },
10548    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10549    iax2_test_losspct_usage },
10550 
10551    { { "iax2", "provision", NULL },
10552    iax2_prov_cmd, "Provision an IAX device",
10553    show_prov_usage, iax2_prov_complete_template_3rd },
10554 
10555 #ifdef IAXTESTS
10556    { { "iax2", "test", "late", NULL },
10557    iax2_test_late, "Test the receipt of a late frame",
10558    iax2_test_late_usage },
10559 
10560    { { "iax2", "test", "resync", NULL },
10561    iax2_test_resync, "Test a resync in received timestamps",
10562    iax2_test_resync_usage },
10563 
10564    { { "iax2", "test", "jitter", NULL },
10565    iax2_test_jitter, "Simulates jitter for testing",
10566    iax2_test_jitter_usage },
10567 #endif /* IAXTESTS */
10568 };
10569 
10570 static int __unload_module(void)
10571 {
10572    struct iax2_thread *thread = NULL;
10573    int x;
10574 
10575    /* Make sure threads do not hold shared resources when they are canceled */
10576    
10577    /* Grab the sched lock resource to keep it away from threads about to die */
10578    /* Cancel the network thread, close the net socket */
10579    if (netthreadid != AST_PTHREADT_NULL) {
10580       AST_LIST_LOCK(&iaxq.queue);
10581       ast_mutex_lock(&sched_lock);
10582       pthread_cancel(netthreadid);
10583       ast_cond_signal(&sched_cond);
10584       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10585       AST_LIST_UNLOCK(&iaxq.queue);
10586       pthread_join(netthreadid, NULL);
10587    }
10588    if (schedthreadid != AST_PTHREADT_NULL) {
10589       ast_mutex_lock(&sched_lock);  
10590       pthread_cancel(schedthreadid);
10591       ast_cond_signal(&sched_cond);
10592       ast_mutex_unlock(&sched_lock);   
10593       pthread_join(schedthreadid, NULL);
10594    }
10595    
10596    /* Call for all threads to halt */
10597    AST_LIST_LOCK(&idle_list);
10598    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10599       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10600       pthread_cancel(thread->threadid);
10601    }
10602    AST_LIST_TRAVERSE_SAFE_END
10603    AST_LIST_UNLOCK(&idle_list);
10604 
10605    AST_LIST_LOCK(&active_list);
10606    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10607       AST_LIST_REMOVE_CURRENT(&active_list, list);
10608       pthread_cancel(thread->threadid);
10609    }
10610    AST_LIST_TRAVERSE_SAFE_END
10611    AST_LIST_UNLOCK(&active_list);
10612 
10613    AST_LIST_LOCK(&dynamic_list);
10614         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10615       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10616       pthread_cancel(thread->threadid);
10617         }
10618    AST_LIST_TRAVERSE_SAFE_END
10619         AST_LIST_UNLOCK(&dynamic_list);
10620 
10621    AST_LIST_HEAD_DESTROY(&iaxq.queue);
10622 
10623    /* Wait for threads to exit */
10624    while(0 < iaxactivethreadcount)
10625       usleep(10000);
10626    
10627    ast_netsock_release(netsock);
10628    ast_netsock_release(outsock);
10629    for (x=0;x<IAX_MAX_CALLS;x++)
10630       if (iaxs[x])
10631          iax2_destroy(x);
10632    ast_manager_unregister( "IAXpeers" );
10633    ast_manager_unregister( "IAXnetstats" );
10634    ast_unregister_application(papp);
10635    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10636    ast_unregister_switch(&iax2_switch);
10637    ast_channel_unregister(&iax2_tech);
10638    delete_users();
10639    iax_provision_unload();
10640    sched_context_destroy(sched);
10641 
10642    ast_mutex_destroy(&waresl.lock);
10643 
10644    for (x = 0; x < IAX_MAX_CALLS; x++)
10645       ast_mutex_destroy(&iaxsl[x]);
10646 
10647    ao2_ref(peers, -1);
10648    ao2_ref(users, -1);
10649 
10650    return 0;
10651 }
10652 
10653 static int unload_module(void)
10654 {
10655    ast_custom_function_unregister(&iaxpeer_function);
10656    return __unload_module();
10657 }
10658 
10659 static int peer_set_sock_cb(void *obj, void *arg, int flags)
10660 {
10661    struct iax2_peer *peer = obj;
10662 
10663    if (peer->sockfd < 0)
10664       peer->sockfd = defaultsockfd;
10665 
10666    return 0;
10667 }
10668 
10669 /*! \brief Load IAX2 module, load configuraiton ---*/
10670 static int load_module(void)
10671 {
10672    char *config = "iax.conf";
10673    int res = 0;
10674    int x;
10675    struct iax2_registry *reg = NULL;
10676 
10677    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
10678    if (!peers)
10679       return AST_MODULE_LOAD_FAILURE;
10680    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
10681    if (!users) {
10682       ao2_ref(peers, -1);
10683       return AST_MODULE_LOAD_FAILURE;
10684    }
10685 
10686    ast_custom_function_register(&iaxpeer_function);
10687 
10688    iax_set_output(iax_debug_output);
10689    iax_set_error(iax_error_output);
10690    jb_setoutput(jb_error_output, jb_warning_output, NULL);
10691    
10692 #ifdef HAVE_ZAPTEL
10693 #ifdef ZT_TIMERACK
10694    timingfd = open("/dev/zap/timer", O_RDWR);
10695    if (timingfd < 0)
10696 #endif
10697       timingfd = open("/dev/zap/pseudo", O_RDWR);
10698    if (timingfd < 0) 
10699       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10700 #endif      
10701 
10702    memset(iaxs, 0, sizeof(iaxs));
10703 
10704    for (x=0;x<IAX_MAX_CALLS;x++)
10705       ast_mutex_init(&iaxsl[x]);
10706    
10707    ast_cond_init(&sched_cond, NULL);
10708 
10709    io = io_context_create();
10710    sched = sched_context_create();
10711    
10712    if (!io || !sched) {
10713       ast_log(LOG_ERROR, "Out of memory\n");
10714       return -1;
10715    }
10716 
10717    netsock = ast_netsock_list_alloc();
10718    if (!netsock) {
10719       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10720       return -1;
10721    }
10722    ast_netsock_init(netsock);
10723 
10724    outsock = ast_netsock_list_alloc();
10725    if (!outsock) {
10726       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10727       return -1;
10728    }
10729    ast_netsock_init(outsock);
10730 
10731    ast_mutex_init(&waresl.lock);
10732 
10733    AST_LIST_HEAD_INIT(&iaxq.queue);
10734    
10735    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10736 
10737    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10738    
10739    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10740    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10741 
10742    if(set_config(config, 0) == -1)
10743       return AST_MODULE_LOAD_DECLINE;
10744 
10745    if (ast_channel_register(&iax2_tech)) {
10746       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10747       __unload_module();
10748       return -1;
10749    }
10750 
10751    if (ast_register_switch(&iax2_switch)) 
10752       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10753 
10754    res = start_network_thread();
10755    if (!res) {
10756       if (option_verbose > 1) 
10757          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10758    } else {
10759       ast_log(LOG_ERROR, "Unable to start network thread\n");
10760       ast_netsock_release(netsock);
10761       ast_netsock_release(outsock);
10762    }
10763 
10764    AST_LIST_LOCK(&registrations);
10765    AST_LIST_TRAVERSE(&registrations, reg, entry)
10766       iax2_do_register(reg);
10767    AST_LIST_UNLOCK(&registrations); 
10768 
10769    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
10770    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
10771 
10772    reload_firmware();
10773    iax_provision_reload();
10774    return res;
10775 }
10776 
10777 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10778       .load = load_module,
10779       .unload = unload_module,
10780       .reload = reload,
10781           );

Generated on Fri Aug 24 02:22:13 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1