reSIProcate/stack  9694
DnsResult.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_DNSRESULT_HXX)
00002 #define RESIP_DNSRESULT_HXX
00003 
00004 #ifdef HAVE_CONFIG_H
00005 #include "config.h"
00006 #endif
00007 
00008 
00009 #include <iosfwd>
00010 #include <set>
00011 #include <vector>
00012 #include <deque>
00013 #include <map>
00014 #include <stack>
00015 
00016 #include "resip/stack/Tuple.hxx"
00017 #include "resip/stack/Transport.hxx"
00018 #include "resip/stack/Uri.hxx"
00019 #include "rutil/HeapInstanceCounter.hxx"
00020 #include "rutil/dns/RRVip.hxx"
00021 #include "rutil/dns/DnsStub.hxx"
00022 
00023 #ifdef WIN32
00024 #include <Ws2tcpip.h>
00025 #endif
00026 
00027 struct hostent;
00028 
00029 namespace resip
00030 {
00031 class DnsInterface;
00032 class DnsAAAARecord;
00033 class DnsHandler;
00034 
00035 class DnsResult : public DnsResultSink
00036 {
00037    public:
00038       RESIP_HeapCount(DnsResult);
00039       DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHandler* handler);
00040       virtual ~DnsResult();
00041 
00042       typedef enum
00043       {
00044          Available, // A result is available now
00045          Pending,   // More results may be pending 
00046          Finished,  // No more results available and none pending
00047          Destroyed  // the associated transaction has been deleted
00048                      // (ie, this DnsResult will delete itself as soon as it
00049                      // gets a new result)
00050       } Type;
00051 
00052       typedef std::vector<Data> DataVector;
00053 
00054       
00064       void lookup(const Uri& uri, const std::vector<Data> &enumSuffixes);
00065 
00073       bool blacklistLast(UInt64 expiry);
00074       
00084       bool greylistLast(UInt64 expiry);
00085       
00095       Type available();
00096       
00106       Tuple next();
00107 
00121       void whitelistLast();
00122 
00123       // return the target of associated query
00124       Data target() const { return mTarget; }
00125       unsigned int getSRVResultsSize() const {return (unsigned int)mSRVResults.size();}
00126 
00127       // Will delete this DnsResult if no pending queries are out there or wait
00128       // until the pending queries get responses and then delete
00129       void destroy();
00130 
00131       // Used to store a NAPTR result
00132       class NAPTR
00133       {
00134          public:
00135             NAPTR();
00136             // As defined by RFC3263
00137             bool operator<(const NAPTR& rhs) const;
00138 
00139             Data key; // NAPTR record key
00140             
00141             int order;
00142             int pref;
00143             Data flags;
00144             Data service;
00145             DnsNaptrRecord::RegExp regex;
00146             Data replacement;
00147       };
00148       
00149       class SRV
00150       {
00151          public:
00152             SRV();
00153             // As defined by RFC3263, RFC2782
00154             bool operator<(const SRV& rhs) const;
00155             
00156             Data key; // SRV record key
00157             
00158             int naptrpref;
00159             TransportType transport;
00160             int priority;
00161             int weight;
00162             int port;
00163             Data target;
00164       };
00165 
00166    private:
00167       void lookupInternal(const Uri& uri);
00168 
00169       // Given a transport and port from uri, return the default port to use
00170       int getDefaultPort(TransportType transport, int port);
00171       
00172       void lookupHost(const Data& target);
00173       
00174       // compute the cumulative weights for the SRV entries with the lowest
00175       // priority, then randomly pick according to RFC2782 from the entries with
00176       // the lowest priority based on weights. When all entries at the lowest
00177       // priority are chosen, pick the next lowest priority and repeat. After an
00178       // SRV entry is selected, remove it from mSRVResults
00179       SRV retrieveSRV();
00180       
00181       // Will retrieve the next SRV record and compute the prime the mResults
00182       // with the appropriate Tuples. 
00183       void primeResults();
00184       
00185    private:
00186       DnsInterface& mInterface;
00187       DnsStub& mDns;
00188       RRVip& mVip;
00189       DnsHandler* mHandler;
00190       int mSRVCount;
00191       Uri mInputUri;
00192       bool mDoingEnum;
00193       
00194       bool mSips;
00195       Data mTarget;
00196       Data mSrvKey;
00197       TransportType mTransport; // current
00198       int mPort; // current
00199       
00211       bool mHaveChosenTransport;
00212       
00220       Type mType;
00221 
00222       //Ugly hack
00223       Data mPassHostFromAAAAtoA;
00224 
00225       void transition(Type t);      
00226       
00227       // This is where the current pending (ordered) results are stored. As they
00228       // are retrieved by calling next(), they are popped from the front of the list
00229       std::deque<Tuple> mResults;
00230       std::vector<Tuple> mGreylistedTuples;
00231       
00232       // Map of NAPTR records by replacement (ie. SRV lookup key)
00233       std::map<Data, NAPTR> mTopOrderedNAPTRs;
00234 
00235       // used in determining the next SRV record to use as per rfc2782
00236       int mCumulativeWeight; // for current priority
00237 
00238       // All SRV records sorted in order of preference
00239       std::vector<SRV> mSRVResults;
00240       
00241       friend class DnsInterface;
00242       friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult&);
00243       friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult::SRV&);
00244       friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult::NAPTR&);
00245 
00246       // DnsResultSink
00247       void onDnsResult(const DNSResult<DnsHostRecord>&);
00248 
00249 //#ifdef USE_IPV6
00250       void onDnsResult(const DNSResult<DnsAAAARecord>&);
00251 //#endif
00252 
00253       void onDnsResult(const DNSResult<DnsSrvRecord>&);
00254       void onDnsResult(const DNSResult<DnsNaptrRecord>&);
00255       void onDnsResult(const DNSResult<DnsCnameRecord>&);
00256 
00257       void onEnumResult(const DNSResult<DnsNaptrRecord>& result);
00258       void onNaptrResult(const DNSResult<DnsNaptrRecord>& result);
00259       
00260 
00261       typedef struct
00262       {
00263          Data domain;
00264          int rrType;
00265          Data value; // stores ip for A/AAAA, target host:port for SRV, and replacement for NAPTR.
00266       } Item;
00267 
00274       std::vector<Item> mLastReturnedPath;
00275       
00283       std::vector<Item> mCurrentPath;
00284       
00285       bool mHaveReturnedResults;
00286 
00287       void clearCurrPath();
00288       
00289       Tuple mLastResult;
00290 };
00291 
00292 EncodeStream& operator<<(EncodeStream& strm, const DnsResult&);
00293 EncodeStream& operator<<(EncodeStream& strm, const DnsResult::SRV&);
00294 EncodeStream& operator<<(EncodeStream& strm, const DnsResult::NAPTR&);
00295 
00296 }
00297 
00298 #endif
00299 //  Copyright (c) 2003, Jason Fischl 
00300 /* ====================================================================
00301  * The Vovida Software License, Version 1.0 
00302  * 
00303  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00304  * 
00305  * Redistribution and use in source and binary forms, with or without
00306  * modification, are permitted provided that the following conditions
00307  * are met:
00308  * 
00309  * 1. Redistributions of source code must retain the above copyright
00310  *    notice, this list of conditions and the following disclaimer.
00311  * 
00312  * 2. Redistributions in binary form must reproduce the above copyright
00313  *    notice, this list of conditions and the following disclaimer in
00314  *    the documentation and/or other materials provided with the
00315  *    distribution.
00316  * 
00317  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00318  *    and "Vovida Open Communication Application Library (VOCAL)" must
00319  *    not be used to endorse or promote products derived from this
00320  *    software without prior written permission. For written
00321  *    permission, please contact vocal@vovida.org.
00322  *
00323  * 4. Products derived from this software may not be called "VOCAL", nor
00324  *    may "VOCAL" appear in their name, without prior written
00325  *    permission of Vovida Networks, Inc.
00326  * 
00327  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00328  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00329  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00330  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00331  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00332  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00333  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00334  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00335  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00336  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00337  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00338  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00339  * DAMAGE.
00340  * 
00341  * ====================================================================
00342  * 
00343  * This software consists of voluntary contributions made by Vovida
00344  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00345  * Inc.  For more information on Vovida Networks, Inc., please see
00346  * <http://www.vovida.org/>.
00347  *
00348  */