]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
removed some dead code
authorBert Hubert <bert.hubert@netherlabs.nl>
Mon, 30 Dec 2002 21:00:56 +0000 (21:00 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Mon, 30 Dec 2002 21:00:56 +0000 (21:00 +0000)
updated doxygen documentation
updated README and TODO

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@104 d19b8d6e-7fed-0310-83ef-9ca221ded41b

17 files changed:
ChangeLog
README
TODO
configure.in
pdns/backends/bind/bindbackend.cc
pdns/backends/gsql/gsqlbackend.cc
pdns/distributor.hh
pdns/dnsbackend.cc
pdns/dnsbackend.hh
pdns/dnspacket.hh
pdns/mtasker.cc
pdns/nameserver.cc
pdns/packethandler.cc
pdns/packethandler.hh
pdns/tcpreceiver.cc
pdns/ueberbackend.hh
pdns/utility.hh

index f5c444fa0a033092eeb3da047d36f33451e230fb..e0d86d8bd997c88f657051feb670276f1ecbb548 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@ Changes since 2.9.3a:
        - zone parser now allows both $include and $INCLUDE
        - wildcard ANY queries work again (colemarcus)
        - resolved crashes after failed gmysql/gpgsql connections
+       - major brokenness in slave support in gmysql/gpgsql (mark)
+       - solaris compilation fixes
+       - make IPv6 work again on FreeBSD (Peter van Dijk)
+
 
 Changes since 2.9.2:
        - windows compilation patches
diff --git a/README b/README
index 91ef818512cc63dabf6d16265ac50aa66bb965a6..508db54e4f7ead093d43786de19121a619dca85f 100644 (file)
--- a/README
+++ b/README
@@ -30,6 +30,11 @@ See http://rtfm.powerdns.com/compiling-powerdns.html for more details.
 Please don't use the 'mysql' backend, it is deprecated. Use the 'gmysql'
 one! 
 
+CVS
+---
+
+If you need code from CVS, read HACKING.
+
 SOLARIS NOTES
 -------------
 You need gcc 3.x, preferably 3.2! The 'Sunpro' compiler is currently not
diff --git a/TODO b/TODO
index 06b5b4c299ec50a7feb7027fc56ff8d320b3af86..6750a05c32f32f675350e732d4fb7b623af88b83 100644 (file)
--- a/TODO
+++ b/TODO
@@ -32,12 +32,14 @@ Medium size things:
 
 
 Small things, great for coders new to PowerDNS:
-       - add LOC record
+done   - add LOC record
        - add KEY record
        - add SIG record
-       - get the xdb backend building again
+done   - get the xdb backend building again
        - 'make distclean' tries to calculate dependencies in
                modules/pgmysqlbackend, which is not needed
+       - remove 'handle' from UeberBackend and BindBackend
+
 
        - investigate if the following is better for the spgsql driver:
 int SPgSQL::doQuery(const string &query)
index 53d23bc0520ae3e6bc3a0410379974e8b8c060a0..9eabed8b80c1a0c328cf6e43935c046a28f1dd5a 100644 (file)
@@ -1,6 +1,6 @@
 dnl intro
 AC_INIT(pdns/receiver.cc)
-AM_INIT_AUTOMAKE(pdns, 2.9.3a)
+AM_INIT_AUTOMAKE(pdns, 2.9.4)
 AC_CANONICAL_HOST
 AM_CONFIG_HEADER(config.h)
 AC_C_BIGENDIAN 
index a8b980a95d1cfbf3322a24b704994920366da8d6..96d41b6124a5b974d0c4d5d8f3bea07df0b5e754 100644 (file)
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: bindbackend.cc,v 1.9 2002/12/20 16:12:06 ahu Exp $ 
+// $Id: bindbackend.cc,v 1.10 2002/12/30 21:00:56 ahu Exp $ 
 #include <errno.h>
 #include <string>
 #include <map>
@@ -332,7 +332,7 @@ BBResourceRecord BindBackend::resourceMaker(int id, const string &qtype, const s
 
   make.qtype=QType::chartocode(qtype.c_str());
   if(!make.qtype)
-    throw AhuException("Unknown qtype '"+qtype+"'");
+    throw AhuException("Unknown qtype '"+qtype+"'"); // never leaves the BindBackend
 
   set<string>::const_iterator i=s_contents.find(content);
   if(i==s_contents.end()) {
index 7b88cd01b29db7b630bde09bca103adb0f707c71..66f389699f483049062554c05166427b8a07f2f6 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: gsqlbackend.cc,v 1.2 2002/12/29 19:47:25 ahu Exp $ 
+// $Id: gsqlbackend.cc,v 1.3 2002/12/30 21:00:56 ahu Exp $ 
 #include <string>
 #include <map>
 
@@ -74,9 +74,21 @@ bool GSQLBackend::getDomainInfo(const string &domain, DomainInfo &di)
   di.last_check=atol(d_result[0][3].c_str());
   di.backend=this;
   
-  string type=d_result[0][4];
-  if(type=="SLAVE")
+  string type=d_result[0][5];
+  if(type=="SLAVE") {
+    di.serial=0;
+    try {
+      SOAData sd;
+      if(!getSOA(domain,sd))
+       L<<Logger::Error<<"No serial for '"<<domain<<"' found - zone is missing?"<<endl;
+      di.serial=sd.serial;
+    }
+    catch(AhuException &ae){
+      L<<Logger::Error<<"Error retrieving serial for '"<<domain<<"': "<<ae.reason<<endl;
+    }
+    
     di.kind=DomainInfo::Slave;
+  }
   else if(type=="MASTER")
     di.kind=DomainInfo::Slave;
   else 
index 03cad418a4b0231c3636a526d2bfb56e28b5265d..17a5757f5640fa3ba41ca84d38b789594e335fec 100644 (file)
 /** the Distributor template class enables you to multithread slow question/answer 
     processes. 
     
-    Generally, you will run 2 threads. One that inserts questions and one that handles
-    the answers.
-*/
+    Questions are posed to the Distributor, which can either hand back the answer,
+    or give it directly to a callback. Only the latter mode of operation is used in 
+    PowerDNS. 
+
+    The Distributor takes care that there are enough Backends alive at any one
+    time and will try to spawn additional ones should they die.
 
+    The Backend needs to count the number of living instances and supply this number to
+    the Distributor using its numBackends() method. This is silly.
 
+    If an exception escapes a Backend, the distributor retires it.
+*/
 template<class Answer, class Question, class Backend> class Distributor
 {
 public:
@@ -72,8 +79,8 @@ public:
        sleep(1);
        int qcount, acount;
 
-  us->numquestions.getvalue( &qcount );
-  us->numanswers.getvalue( &acount );
+       us->numquestions.getvalue( &qcount );
+       us->numanswers.getvalue( &acount );
 
        L <<"queued questions: "<<qcount<<", pending answers: "<<acount<<endl;
       }
index 12c8c0102005a735d87cf009490d8ee6cab62e91..10fba13a31d3c3ec2f24ce8f0422eaadf37b510e 100644 (file)
@@ -250,7 +250,7 @@ vector<DNSBackend *>BackendMakerClass::all()
   }
   catch(...) {
     // and cleanup
-    L<<Logger::Error<<"Caught an exception instantiating a backend, details should follow"<<endl;
+    L<<Logger::Error<<"Caught an exception instantiating a backend, cleaning up"<<endl;
     for(vector<DNSBackend *>::const_iterator i=ret.begin();i!=ret.end();++i)
       delete *i;
     throw;
@@ -259,6 +259,16 @@ vector<DNSBackend *>BackendMakerClass::all()
   return ret;
 }
 
+/** getSOA() is a function that is called to get the SOA of a domain. Callers should ONLY
+    use getSOA() and no perform a lookup() themselves as backends may decide to special case
+    the SOA record.
+    
+    Returns false if there is definitely no SOA for the domain. May throw a DBException
+    to indicate that the backend is currently unable to supply an answer.
+
+    \param domain Domain we want to get the SOA details of
+    \param sd SOAData which is filled with the SOA details
+*/
 bool DNSBackend::getSOA(const string &domain, SOAData &sd)
 {
   this->lookup(QType(QType::SOA),domain,0);
index 8483a222cda306bf29f7a8ba1208a746dc75316f..af31536098143b5bd7ba6f8b7103ce67c41e7503 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: dnsbackend.hh,v 1.4 2002/12/20 14:25:29 ahu Exp $
+// $Id: dnsbackend.hh,v 1.5 2002/12/30 21:00:56 ahu Exp $
 /* (C) 2002 POWERDNS.COM BV  */
    
 #ifndef DNSBACKEND_HH
@@ -41,9 +41,6 @@ class DNSPacket;
 #include "dns.hh"
 using namespace std;
 
-/** This virtual base class defines the interface for backends for the ahudns. To create a backend,
-    inherit from this class and implement functions for all virtual methods.
-*/
   
 class DNSBackend;  
 struct DomainInfo
@@ -59,34 +56,56 @@ struct DomainInfo
 };
 
 class DNSPacket;
+
+
+//! This virtual base class defines the interface for backends for the ahudns. 
+/** To create a backend, inherit from this class and implement functions for all virtual methods.
+    Methods should not throw an exception if they are sure they did not find the requested data. However,
+    if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException,
+    which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking
+    issues should lead to DBExceptions.
+
+    More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should
+    lead to the throwing of an AhuException. This exception will fall straight through the UeberBackend and the PacketHandler
+    and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one.
+*/
 class DNSBackend
 {
 public:
+  //! lookup() initiates a lookup. A lookup without results should not throw!
   virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0; 
-  virtual bool get(DNSResourceRecord &)=0;
-  virtual bool list(int domain_id)=0; 
+  virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
+  //! Initiates a list of the specified domain
+  /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false
+      if the backend does not consider itself responsible for the id passed.
+      \param domain_id ID of which a list is requested
+  */
+  virtual bool list(int domain_id)=0;  
 
   virtual ~DNSBackend(){};
 
-  static void reconfigure(const string &);
-
+  //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
   virtual bool getSOA(const string &name, SOAData &soadata);
 
+  //! returns true if master ip is master for domain name.
   virtual bool isMaster(const string &name, const string &ip)
   {
     return false;
   }
   
+  //! starts the transaction for updating domain qname (FIXME: what is id?)
   virtual bool startTransaction(const string &qname, int id=-1)
   {
     return false;
   }
 
+  //! commits the transaction started by startTransaction
   virtual bool commitTransaction()
   {
     return false;
   }
 
+  //! aborts the transaction started by strartTransaction, should leave state unaltered
   virtual bool abortTransaction()
   {
     return false;
@@ -100,41 +119,51 @@ public:
   {
   }
 
+  //! feeds a record to a zone, needs a call to startTransaction first
   virtual bool feedRecord(const DNSResourceRecord &rr)
   {
     return false; // no problem!
   }
+  //! if this returns true, DomainInfo di contains information about the domain
   virtual bool getDomainInfo(const string &domain, DomainInfo &di)
   {
     return false;
   }
+  //! slave capable backends should return a list of slaves that should be rechecked for staleness
   virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
   {
   }
 
+  //! get a list of IP addresses that should also be notified for a domain
   virtual void alsoNotifies(const string &domain, set<string> *ips)
   {
   }
+
+  //! get list of domains that have been changed since their last notification to slaves
   virtual void getUpdatedMasters(vector<DomainInfo>* domains)
   {
   }
-  virtual DNSBackend *getBackendAndID(const string &qdomain, u_int32_t *id)
-  {
-    return 0;
-  }
+  
+  //! Called by PowerDNS to inform a backend that a domain has been checked for freshness
   virtual void setFresh(u_int32_t domain_id)
   {
 
   }
+  //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves
   virtual void setNotified(u_int32_t id, u_int32_t serial)
   {
   }
 
+  //! Can be called to seed the getArg() function with a prefix
   void setArgPrefix(const string &prefix);
+
+  //! determine if ip is a supermaster or a domain
   virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
   {
     return false;
   }
+
+  //! called by PowerDNS to create a slave record for a superMaster
   virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
   {
     return false;
@@ -186,6 +215,7 @@ private:
 
 extern BackendMakerClass &BackendMakers();
 
+//! Exception that can be thrown by a DNSBackend to indicate a failure
 class DBException : public AhuException
 {
 public:
index e30686cf222672c215feedb0b4c2382758963a8c..ad0b7560b9fd704bacdfaaf2f35e5505b913e74f 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: dnspacket.hh,v 1.7 2002/12/18 09:30:13 ahu Exp $
+// $Id: dnspacket.hh,v 1.8 2002/12/30 21:00:56 ahu Exp $
 #ifndef DNSPACKET_HH
 #define DNSPACKET_HH
 
@@ -180,12 +180,9 @@ private:
       number of seconds since 1 jan 1970 (unix timestamp). The other values are substituted as indicated
 
   */
-
-
   void addSOARecord(const string &domain, const string &content, u_int32_t ttl, DNSResourceRecord::Place place); 
   void addSOARecord(const DNSResourceRecord &); //!< add a SOA record to the packet
 
-
   void addTXTRecord(string domain, string, u_int32_t ttl); //!< add a TXT record to the packet
   void addTXTRecord(const DNSResourceRecord &); //!< add a TXT record to the packet
 
index 6bf96175e01ead2156b9ade83b4f7998c7e15e45..6921e1f69f9016984edd16225a10acd035497ddf 100644 (file)
@@ -20,7 +20,7 @@
 #include <stdio.h>
 #include <iostream>
 
-/** \mainpage
+/** \page MTasker
     Simple system for implementing cooperative multitasking of functions, with 
     support for waiting on events which can return values.
 
index 1ef97afe52baa769208f22b0959710c6f3794571..2f4efb9ebc1cc4d4ed58b525e989be97eebb4cf7 100644 (file)
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: nameserver.cc,v 1.3 2002/12/10 13:36:26 ahu Exp $ 
+// $Id: nameserver.cc,v 1.4 2002/12/30 21:00:56 ahu Exp $ 
 #include "utility.hh"
 #include <cstdio>
 #include <cstring>
@@ -41,27 +41,19 @@ extern StatBag S;
     own backend, see the documentation for the DNSBackend class.
 
     \section copyright Copyright and License
-    AhuDNS is (C) 2002 PowerDNS BV.
-
-    AhuDNS is NOT open source (yet), so treat this code as a trade secret. If it has been supplied to you for evaluation,
-    this does not mean that you can deploy the code!
+    AhuDNS is (C) 2002 PowerDNS BV. It is distributed according to the terms of the General Public License version 2.
 
     \section overview High level overview
 
-    AhuDNS is highly threaded, which means that several tasks each have their own process thread. Two of the pivotal
-    threads are the qthread() and the athread().
-
-    - The qthread() receives questions over the network (via the Nameserver class, which returns DNSPacket objects), and gives them to the Distributor.
-    - The athread() waits on the Distributor to return answers, ready to send back over the network, again via UDPNameserver.
-
-    The Distributor contains a configurable number of PacketHandler instances, each in its own thread, for connection pooling
+    The Distributor contains a configurable number of PacketHandler instances, each in its own thread, for connection pooling. 
+    PacketHandler instances are recycled of they let escape an AhuException.
 
     The PacketHandler implements the RFC1034 algorithm and converts question packets into DNSBackend queries.
 
     A DNSBackend is an entity that returns DNSResourceRecord objects in return to explicit questions for domains with a specified QType
 
-    AhuDNS uses the UeberBackend as its DNSBackend. The UeberBackend by default has no DNSBackends within itself, those are loaded
-    using the dynloader tool. This way DNSBackend implementations can be kept completely separate.
+    PowerDNS uses the UeberBackend as its DNSBackend. The UeberBackend by default has no DNSBackends within itself, those are loaded
+    using the pdns_control tool. This way DNSBackend implementations can be kept completely separate (but they often aren't).s
 
     If one or more DNSBackends are loaded, the UeberBackend fields the queries to all of them until one answers.
 
@@ -82,7 +74,7 @@ extern StatBag S;
     These statistics are made available via the UeberBackend on the same socket that is used for dynamic module commands.
 
     \section Main Main 
-    The main() of AhuDNS can be found in receiver.cc - start reading there for further insights into the operation of the nameserver
+    The main() of PowerDNS can be found in receiver.cc - start reading there for further insights into the operation of the nameserver
 
 
 */
@@ -159,6 +151,9 @@ void UDPNameserver::bindIPv6()
 
     sockaddr_in6 locala;
     locala.sin6_port=ntohs(arg().asNum("local-port"));
+    locala.sin6_family=AF_INET6;
+    locala.sin6_flowinfo=0;
+
     if(!inet_pton(AF_INET6, localname.c_str(), (void *)&locala.sin6_addr)) {
       addrinfo *addrinfos;
       addrinfo hints;
@@ -171,6 +166,7 @@ void UDPNameserver::bindIPv6()
       memcpy(&locala,addrinfos->ai_addr,addrinfos->ai_addrlen);
     }
 
+
     if(bind(s, (sockaddr*)&locala, sizeof(locala))<0) {
       L<<Logger::Error<<"binding to UDP ipv6 socket: "<<strerror(errno)<<endl;
       throw AhuException("Unable to bind to UDP ipv6 socket");
index 1d70c03a050f28857758a2347f8ed4aff8d065d0..42a5381299840305417eaf2218ad6034b8be0844 100644 (file)
@@ -63,7 +63,6 @@ PacketHandler::~PacketHandler()
 {
   --s_count;
   DLOG(L<<Logger::Error<<"PacketHandler destructor called - "<<s_count<<" left"<<endl);
-
 }
 
 
@@ -151,7 +150,7 @@ int PacketHandler::doDNSCheckRequest(DNSPacket *p, DNSPacket *r, string &target)
   DNSResourceRecord rr;
 
   if (p->qclass == 3 && p->qtype.getName() == "HINFO") {
-    rr.content = "PowerDNS $Id: packethandler.cc,v 1.3 2002/12/29 19:47:25 ahu Exp $";
+    rr.content = "PowerDNS $Id: packethandler.cc,v 1.4 2002/12/30 21:00:56 ahu Exp $";
     rr.ttl = 5;
     rr.qname=target;
     rr.qtype=13; // hinfo
@@ -167,7 +166,7 @@ int PacketHandler::doVersionRequest(DNSPacket *p, DNSPacket *r, string &target)
 {
   DNSResourceRecord rr;
   if(p->qtype.getCode()==QType::TXT && target=="version.bind") {// TXT
-    rr.content="Served by POWERDNS "VERSION" $Id: packethandler.cc,v 1.3 2002/12/29 19:47:25 ahu Exp $";
+    rr.content="Served by POWERDNS "VERSION" $Id: packethandler.cc,v 1.4 2002/12/30 21:00:56 ahu Exp $";
     rr.ttl=5;
     rr.qname=target;
     rr.qtype=QType::TXT; // TXT
@@ -443,8 +442,6 @@ int PacketHandler::doNotify(DNSPacket *p)
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but slave support is disabled in the configuration"<<endl;
     return RCode::NotImp;
   }
-  SOAData sd;
-  sd.serial=0;
   DNSBackend *db=0;
   DomainInfo di;
   if(!B.getDomainInfo(p->qdomain,di) || !(db=di.backend)) {
@@ -466,14 +463,15 @@ int PacketHandler::doNotify(DNSPacket *p)
     return RCode::ServFail;
   }
        
-  if(theirserial<=sd.serial) {
+
+  if(theirserial<=di.serial) {
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from master "<<p->getRemote()<<", we are up to date: "<<
-      theirserial<<"<="<<sd.serial<<endl;
+      theirserial<<"<="<<di.serial<<endl;
     return RCode::NoError;
   }
   else {
-    L<<Logger::Error<<"Received valid NOTIFY for "<<p->qdomain<<" (id="<<sd.domain_id<<") from master "<<p->getRemote()<<": "<<
-      theirserial<<" > "<<sd.serial<<endl;
+    L<<Logger::Error<<"Received valid NOTIFY for "<<p->qdomain<<" (id="<<di.id<<") from master "<<p->getRemote()<<": "<<
+      theirserial<<" > "<<di.serial<<endl;
 
     Communicator.addSuckRequest(p->qdomain, p->getRemote());
   }
index fee693d55ded82865a8396e34ec8f1c0edee887d..2b7166b1f79c51e0353859f86bb68164e8ae2613 100644 (file)
@@ -70,7 +70,7 @@ public:
   DNSPacket *question(DNSPacket *); //!< hand us a DNS packet with a question, we give you an answer
   PacketHandler(); 
   ~PacketHandler(); // defined in packethandler.cc, and does --count
-  static int numRunning(){return s_count;}; //!< Returns the number of running PacketHandlers
+  static int numRunning(){return s_count;}; //!< Returns the number of running PacketHandlers. Called by Distributor
  
   void soaMagic(DNSResourceRecord *rr);
   DNSBackend *getBackend();
index 61293af7b6b9ceeb75f52f5c104012f970dfee70..c15eb38d03b41083cf196470215b075562de5188 100644 (file)
@@ -446,6 +446,9 @@ TCPNameserver::TCPNameserver()
 
     sockaddr_in6 locala;
     locala.sin6_port=ntohs(arg().asNum("local-port"));
+    locala.sin6_family=AF_INET6;
+    locala.sin6_flowinfo=0;
+
 
     if(!inet_pton(AF_INET6, laddr->c_str(), (void *)&locala.sin6_addr)) {
       addrinfo *addrinfos;
@@ -466,6 +469,7 @@ TCPNameserver::TCPNameserver()
       exit(1);  
     }
 
+
     if(bind(s, (const sockaddr*)&locala, sizeof(locala))<0) {
       L<<Logger::Error<<"binding to TCP socket: "<<strerror(errno)<<endl;
       throw AhuException("Unable to bind to TCPv6 socket");
index 6ad8e5b39de24302a2cd7d62c8880c60d52b6f6f..5e146c0af1be6df648a8c8e398ca7ece5509d24e 100644 (file)
@@ -46,7 +46,10 @@ class BackendReporter;
 
 /** This is a very magic backend that allows us to load modules dynamically,
     and query them in order. This is persistent over all UeberBackend instantiations
-    across multiple threads. Very magic */
+    across multiple threads. 
+
+    The UeberBackend is transparent for exceptions, which should fall straight through.
+*/
 
 class UeberBackend : public DNSBackend
 {
index aad34a3308eb74f5da26cce82ef1b3f31a36e48a..8d13f2406f1aeca9b295f6dd6f1564cf900670f4 100644 (file)
@@ -26,6 +26,7 @@
 #endif // WIN32
 
 #ifdef NEED_POSIX_TYPEDEF
+typedef unsigned char u_int8_t;
 typedef unsigned short int u_int16_t;
 typedef unsigned int u_int32_t;
 #endif