kextsock.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  **/
00020 
00021 #include <config.h>
00022 
00023 #include <sys/types.h>
00024 #include <sys/socket.h>
00025 #include <sys/times.h>
00026 #include <netinet/in.h>
00027 #include <arpa/inet.h>
00028 #include <sys/un.h>
00029 
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #include <fcntl.h>
00033 
00034 #include <netdb.h>
00035 
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 
00039 #include <qglobal.h>
00040 #include <qstring.h>
00041 #include <qiodevice.h>
00042 #include <qsocketnotifier.h>
00043 #include <qguardedptr.h>
00044 
00045 #include "kresolver.h"
00046 
00047 #include "kdebug.h"
00048 #include "kextsock.h"
00049 #include "ksockaddr.h"
00050 #include "ksocks.h"
00051 
00052 #ifdef __CYGWIN__
00053 #include "netsupp.h"
00054 #endif 
00055 
00056 using namespace KNetwork;
00057 
00058 //
00059 // Internal class definitions
00060 //
00061 
00062 class KExtendedSocketPrivate
00063 {
00064 public:
00065   int flags;            // socket flags
00066   int status;           // status
00067   int syserror;         // the system error value
00068 
00069   timeval timeout;      // connection/acception timeout
00070 
00071   KResolver resRemote;      // the resolved addresses
00072   KResolver resLocal;       // binding resolution
00073   unsigned current;     // used by the asynchronous connection
00074 
00075   ::KSocketAddress *local;  // local socket address
00076   ::KSocketAddress *peer;   // peer socket address
00077 
00078   QSocketNotifier *qsnIn, *qsnOut;
00079   int inMaxSize, outMaxSize;
00080   bool emitRead : 1, emitWrite : 1;
00081   mutable bool addressReusable : 1, ipv6only : 1;
00082 
00083   KExtendedSocketPrivate() :
00084     flags(0), status(0), syserror(0),
00085     current(0), local(0), peer(0),
00086     qsnIn(0), qsnOut(0), inMaxSize(-1), outMaxSize(-1), emitRead(false), emitWrite(false),
00087     addressReusable(false), ipv6only(false)
00088   {
00089     timeout.tv_sec = timeout.tv_usec = 0;
00090   }
00091 };
00092 
00093 // translate KExtendedSocket flags into KResolver ones
00094 static bool process_flags(int flags, int& socktype, int& familyMask, int& outflags)
00095 {
00096   switch (flags & (KExtendedSocket::streamSocket | KExtendedSocket::datagramSocket | KExtendedSocket::rawSocket))
00097     {
00098     case 0:
00099       /* No flags given, use default */
00100 
00101     case KExtendedSocket::streamSocket:
00102       /* streaming socket requested */
00103       socktype = SOCK_STREAM;
00104       break;
00105 
00106     case KExtendedSocket::datagramSocket:
00107       /* datagram packet socket requested */
00108       socktype = SOCK_DGRAM;
00109       break;
00110 
00111     case KExtendedSocket::rawSocket:
00112       /* raw socket requested. I wouldn't do this if I were you... */
00113       socktype = SOCK_RAW;
00114       break;
00115 
00116     default:
00117       /* the flags were used in an invalid manner */
00118       return false;
00119     }
00120 
00121   if (flags & KExtendedSocket::knownSocket)
00122     {
00123       familyMask = 0;
00124       if ((flags & KExtendedSocket::unixSocket) == KExtendedSocket::unixSocket)
00125     familyMask |= KResolver::UnixFamily;
00126 
00127       switch ((flags & (KExtendedSocket::ipv6Socket|KExtendedSocket::ipv4Socket)))
00128     {
00129     case KExtendedSocket::ipv4Socket:
00130       familyMask |= KResolver::IPv4Family;
00131       break;
00132     case KExtendedSocket::ipv6Socket:
00133       familyMask |= KResolver::IPv6Family;
00134       break;
00135     case KExtendedSocket::inetSocket:
00136       familyMask |= KResolver::InternetFamily;
00137       break;
00138     }
00139 
00140       // those are all the families we know about
00141     }
00142   else
00143     familyMask = KResolver::KnownFamily;
00144 
00145   /* check other flags */
00146   outflags = (flags & KExtendedSocket::passiveSocket ? KResolver::Passive : 0) |
00147     (flags & KExtendedSocket::canonName ? KResolver::CanonName : 0) |
00148     (flags & KExtendedSocket::noResolve ? KResolver::NoResolve : 0);
00149 
00150   if (getenv("KDE_NO_IPV6"))
00151     familyMask &= ~KResolver::IPv6Family;
00152 
00153   return true;
00154 }
00155 
00156 // "skips" at most len bytes from file descriptor fd
00157 // that is, we will try and read that much data and discard
00158 // it. We will stop when we have read those or when the read
00159 // function returns error
00160 static int skipData(int fd, unsigned len)
00161 {
00162   char buf[1024];
00163   unsigned skipped = 0;
00164   while (len)
00165     {
00166       int count = sizeof(buf);
00167       if ((unsigned)count > len)
00168     count = len;
00169       count = KSocks::self()->read(fd, buf, count);
00170       if (count == -1)
00171     return -1;
00172       else
00173     {
00174       len -= count;
00175       skipped += count;
00176     }
00177     }
00178   return skipped;
00179 }
00180 
00181 /*
00182  * class KExtendedSocket
00183  */
00184 
00185 // default constructor
00186 KExtendedSocket::KExtendedSocket() :
00187   sockfd(-1), d(new KExtendedSocketPrivate)
00188 {
00189 }
00190 
00191 // constructor with hostname
00192 KExtendedSocket::KExtendedSocket(const QString& host, int port, int flags) :
00193   sockfd(-1), d(new KExtendedSocketPrivate)
00194 {
00195   setAddress(host, port);
00196   setSocketFlags(flags);
00197 }
00198 
00199 // same
00200 KExtendedSocket::KExtendedSocket(const QString& host, const QString& service, int flags) :
00201   sockfd(-1), d(new KExtendedSocketPrivate)
00202 {
00203   setAddress(host, service);
00204   setSocketFlags(flags);
00205 }
00206 
00207 // destroy the class
00208 KExtendedSocket::~KExtendedSocket()
00209 {
00210   closeNow();
00211 
00212   if (d->local != NULL)
00213     delete d->local;
00214   if (d->peer != NULL)
00215     delete d->peer;
00216 
00217   if (d->qsnIn != NULL)
00218     delete d->qsnIn;
00219   if (d->qsnOut != NULL)
00220     delete d->qsnOut;
00221 
00222   delete d;
00223 }
00224 
00225 void KExtendedSocket::reset()
00226 {
00227   closeNow();
00228   release();
00229   d->current = 0;
00230   d->status = nothing;
00231   d->syserror = 0;
00232 }
00233 
00234 int KExtendedSocket::socketStatus() const
00235 {
00236   return d->status;
00237 }
00238 
00239 void KExtendedSocket::setSocketStatus(int newstatus)
00240 {
00241   d->status = newstatus;
00242 }
00243 
00244 void KExtendedSocket::setError(int errorcode, int syserror)
00245 {
00246   setStatus(errorcode);
00247   d->syserror = syserror;
00248 }
00249 
00250 int KExtendedSocket::systemError() const
00251 {
00252   return d->syserror;
00253 }
00254 
00255 /*
00256  * Sets socket flags
00257  * This is only allowed if we are in nothing state
00258  */
00259 int KExtendedSocket::setSocketFlags(int flags)
00260 {
00261   if (d->status > nothing)
00262     return -1;          // error!
00263 
00264   return d->flags = flags;
00265 }
00266 
00267 int KExtendedSocket::socketFlags() const
00268 {
00269   return d->flags;
00270 }
00271 
00272 /*
00273  * Sets socket target hostname
00274  * This is only allowed if we are in nothing state
00275  */
00276 bool KExtendedSocket::setHost(const QString& host)
00277 {
00278   if (d->status > nothing)
00279     return false;       // error!
00280 
00281   d->resRemote.setNodeName(host);
00282   return true;
00283 }
00284 
00285 /*
00286  * returns the hostname
00287  */
00288 QString KExtendedSocket::host() const
00289 {
00290   return d->resRemote.nodeName();
00291 }
00292 
00293 /*
00294  * Sets the socket target port/service
00295  * Same thing: only state 'nothing'
00296  */
00297 bool KExtendedSocket::setPort(int port)
00298 {
00299   return setPort(QString::number(port));
00300 }
00301 
00302 bool KExtendedSocket::setPort(const QString& service)
00303 {
00304   if (d->status > nothing)
00305     return false;       // error
00306 
00307   d->resRemote.setServiceName(service);
00308   return true;
00309 }
00310 
00311 /*
00312  * returns the service port number
00313  */
00314 QString KExtendedSocket::port() const
00315 {
00316   return d->resRemote.serviceName();
00317 }
00318 
00319 /*
00320  * sets the address
00321  */
00322 bool KExtendedSocket::setAddress(const QString& host, int port)
00323 {
00324   return setHost(host) && setPort(port);
00325 }
00326 
00327 /*
00328  * the same
00329  */
00330 bool KExtendedSocket::setAddress(const QString& host, const QString& serv)
00331 {
00332   return setHost(host) && setPort(serv);
00333 }
00334 
00335 /*
00336  * Sets the bind hostname
00337  * This is only valid in the 'nothing' state and if this is not a
00338  * passiveSocket socket
00339  */
00340 bool KExtendedSocket::setBindHost(const QString& host)
00341 {
00342   if (d->status > nothing || d->flags & passiveSocket)
00343     return false;       // error
00344 
00345   d->resLocal.setServiceName(host);
00346   return true;
00347 }
00348 
00349 /*
00350  * Unsets the bind hostname
00351  * same thing
00352  */
00353 bool KExtendedSocket::unsetBindHost()
00354 {
00355   return setBindHost(QString::null);
00356 }
00357 
00358 /*
00359  * returns the binding host
00360  */
00361 QString KExtendedSocket::bindHost() const
00362 {
00363   return d->resLocal.serviceName();
00364 }
00365 
00366 /*
00367  * Sets the bind port
00368  * Same condition as setBindHost
00369  */
00370 bool KExtendedSocket::setBindPort(int port)
00371 {
00372   return setBindPort(QString::number(port));
00373 }
00374 
00375 bool KExtendedSocket::setBindPort(const QString& service)
00376 {
00377   if (d->status > nothing || d->flags & passiveSocket)
00378     return false;       // error
00379 
00380   d->resLocal.setServiceName(service);
00381   return true;
00382 }
00383 
00384 /*
00385  * unsets the bind port
00386  */
00387 bool KExtendedSocket::unsetBindPort()
00388 {
00389   return setBindPort(QString::null);
00390 }
00391 
00392 /*
00393  * returns the binding port
00394  */
00395 QString KExtendedSocket::bindPort() const
00396 {
00397   return d->resLocal.serviceName();
00398 }
00399 
00400 /*
00401  * sets the binding address
00402  */
00403 bool KExtendedSocket::setBindAddress(const QString& host, int port)
00404 {
00405   return setBindHost(host) && setBindPort(port);
00406 }
00407 
00408 /*
00409  * same
00410  */
00411 bool KExtendedSocket::setBindAddress(const QString& host, const QString& service)
00412 {
00413   return setBindHost(host) && setBindPort(service);
00414 }
00415 
00416 /*
00417  * unsets binding address
00418  */
00419 bool KExtendedSocket::unsetBindAddress()
00420 {
00421   return unsetBindHost() && unsetBindPort();
00422 }
00423 
00424 /*
00425  * sets the timeout for the connection
00426  */
00427 bool KExtendedSocket::setTimeout(int secs, int usecs)
00428 {
00429   if (d->status >= connected)   // closed?
00430     return false;
00431 
00432   d->timeout.tv_sec = secs;
00433   d->timeout.tv_usec = usecs;
00434   return true;
00435 }
00436 
00437 /*
00438  * returns the timeout
00439  */
00440 timeval KExtendedSocket::timeout() const
00441 {
00442   return d->timeout;
00443 }
00444 
00445 /*
00446  * Sets the blocking mode on this socket
00447  */
00448 bool KExtendedSocket::setBlockingMode(bool enable)
00449 {
00450   cleanError();
00451   if (d->status < created)
00452     return false;
00453 
00454   if (sockfd == -1)
00455     return false;       // error!
00456 
00457   int fdflags = fcntl(sockfd, F_GETFL, 0);
00458   if (fdflags == -1)
00459     return false;       // error!
00460 
00461   if (!enable)
00462     fdflags |= O_NONBLOCK;
00463   else
00464     fdflags &= ~O_NONBLOCK;
00465 
00466   if (fcntl(sockfd, F_SETFL, fdflags) == -1)
00467     {
00468       setError(IO_UnspecifiedError, errno);
00469       return false;
00470     }
00471   return true;
00472 }
00473 
00474 /*
00475  * Returns the blocking mode on the socket
00476  */
00477 bool KExtendedSocket::blockingMode()
00478 {
00479   cleanError();
00480   if (d->status < created)
00481     return false;       // sockets not created are in blocking mode
00482 
00483   if (sockfd == -1)
00484     return false;       // error
00485 
00486   int fdflags = fcntl(sockfd, F_GETFL, 0);
00487   if (fdflags == -1)
00488     {
00489       setError(IO_UnspecifiedError, errno);
00490       return false;
00491     }
00492   return (fdflags & O_NONBLOCK) == 0; // non-blocking == false
00493 }
00494 
00495 /*
00496  * Sets the reusability flag for this socket in the OS
00497  */
00498 bool KExtendedSocket::setAddressReusable(bool enable)
00499 {
00500   cleanError();
00501   d->addressReusable = enable;
00502   if (d->status < created)
00503     return true;
00504 
00505   if (sockfd == -1)
00506     return true;
00507 
00508   if (!setAddressReusable(sockfd, enable))
00509     {
00510       setError(IO_UnspecifiedError, errno);
00511       return false;
00512     }
00513   return true;
00514 }
00515 
00516 bool KExtendedSocket::setAddressReusable(int fd, bool enable)
00517 {
00518   if (fd == -1)
00519     return false;
00520 
00521   int on = enable;      // just to be on the safe side
00522 
00523   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
00524     return false;
00525   return true;
00526 }
00527 
00528 /*
00529  * Retrieves the reusability flag for this socket
00530  */
00531 bool KExtendedSocket::addressReusable()
00532 {
00533   cleanError();
00534   if (d->status < created)
00535     return d->addressReusable;
00536 
00537   if (sockfd == -1)
00538     return d->addressReusable;
00539 
00540   int on;
00541   socklen_t onsiz = sizeof(on);
00542   if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, &onsiz) == -1)
00543     {
00544       setError(IO_UnspecifiedError, errno);
00545       return false;
00546     }
00547 
00548   return on != 0;
00549 }
00550 
00551 /*
00552  * Set the IPV6_V6ONLY flag
00553  */
00554 bool KExtendedSocket::setIPv6Only(bool enable)
00555 {
00556 #ifdef IPV6_V6ONLY
00557   cleanError();
00558 
00559   d->ipv6only = enable;
00560   if (sockfd == -1)
00561     return true;        // can't set on a non-existing socket
00562 
00563   int on = enable;
00564 
00565   if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
00566          (char *)&on, sizeof(on)) == -1)
00567     {
00568       setError(IO_UnspecifiedError, errno);
00569       return false;
00570     }
00571   else
00572     return true;
00573 
00574 #else
00575   // we don't have the IPV6_V6ONLY constant in this system
00576   d->ipv6only = enable;
00577 
00578   setError(IO_UnspecifiedError, ENOSYS);
00579   return false;         // can't set if we don't know about this flag
00580 #endif
00581 }
00582 
00583 /*
00584  * retrieve the IPV6_V6ONLY flag
00585  */
00586 bool KExtendedSocket::isIPv6Only()
00587 {
00588 #ifdef IPV6_V6ONLY
00589   cleanError();
00590 
00591   if (d->status < created || sockfd == -1)
00592     return d->ipv6only;
00593 
00594   int on;
00595   socklen_t onsiz = sizeof(on);
00596   if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
00597          (char *)&on, &onsiz) == -1)
00598     {
00599       setError(IO_UnspecifiedError, errno);
00600       return false;
00601     }
00602 
00603   return d->ipv6only = on;
00604 
00605 #else
00606   // we don't have the constant
00607   setError(IO_UnspecifiedError, ENOSYS);
00608   return false;
00609 #endif
00610 }
00611 
00612 /*
00613  * Sets the buffer sizes in this socket
00614  * Also, we create or delete the socket notifiers
00615  */
00616 bool KExtendedSocket::setBufferSize(int rsize, int wsize)
00617 {
00618   cleanError();
00619   if (d->status < created)
00620     return false;
00621 
00622   if (sockfd == -1)
00623     return false;
00624 
00625   if (d->flags & passiveSocket)
00626     return false;       // no I/O on passive sockets
00627 
00628   if (rsize < -2)
00629     return false;
00630 
00631   if (wsize < -2)
00632     return false;
00633 
00634   // LOCK BUFFER MUTEX
00635 
00636   // The input socket notifier is always enabled
00637   // That happens because we want to be notified of when the socket gets
00638   // closed
00639   if (d->qsnIn == NULL)
00640     {
00641       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
00642       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
00643       d->qsnIn->setEnabled(true);
00644     }
00645 
00646   if (rsize == 0 && d->flags & inputBufferedSocket)
00647     {
00648       // user wants to disable input buffering
00649       d->flags &= ~inputBufferedSocket;
00650 
00651       consumeReadBuffer(readBufferSize(), NULL, true);
00652       d->inMaxSize = 0;
00653     }
00654   else if (rsize != -2)
00655     {
00656       // enabling input buffering
00657       if (rsize)
00658     d->flags |= inputBufferedSocket;
00659       d->inMaxSize = rsize;
00660 
00661       if (rsize > 0 && (unsigned)rsize < readBufferSize())
00662     // input buffer has more data than the new size; discard
00663     consumeReadBuffer(readBufferSize() - rsize, NULL, true);
00664 
00665     }
00666 
00667   if (wsize == 0 && d->flags & outputBufferedSocket)
00668     {
00669       // disabling output buffering
00670       d->flags &= ~outputBufferedSocket;
00671       if (d->qsnOut && !d->emitWrite)
00672     d->qsnOut->setEnabled(false);
00673       consumeWriteBuffer(writeBufferSize());
00674       d->outMaxSize = 0;
00675     }
00676   else if (wsize != -2)
00677     {
00678       // enabling input buffering
00679       if (wsize)
00680     d->flags |= outputBufferedSocket;
00681       d->outMaxSize = wsize;
00682 
00683       if (wsize > 0 && (unsigned)wsize < writeBufferSize())
00684     // output buffer is bigger than it is to become; shrink
00685     consumeWriteBuffer(writeBufferSize() - wsize);
00686 
00687       if (d->qsnOut == NULL)
00688     {
00689       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
00690       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
00691       // if the class is being created now, there's nothing to write yet
00692       // so socketActivityWrite() will get called once and disable
00693       // the notifier
00694     }
00695     }
00696 
00697   // UNLOCK BUFFER MUTEX
00698 
00699   setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw));
00700 
00701   // check we didn't turn something off we shouldn't
00702   if (d->emitWrite && d->qsnOut == NULL)
00703     {
00704       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
00705       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
00706     }
00707 
00708   return true;
00709 }
00710 
00711 /*
00712  * Finds the local address for this socket
00713  * if we have done this already, we return it. Otherwise, we'll have
00714  * to find the socket name
00715  */
00716 const ::KSocketAddress *KExtendedSocket::localAddress()
00717 {
00718   if (d->local != NULL)
00719     return d->local;
00720   if (d->status < bound)
00721     return NULL;
00722 
00723   return d->local = localAddress(sockfd);
00724 }
00725 
00726 /*
00727  * Same thing, but for peer address. Which means this does not work on
00728  * passiveSocket and that we require to be connected already. Also note that
00729  * the behavior on connectionless sockets is not defined here.
00730  */
00731 const ::KSocketAddress* KExtendedSocket::peerAddress()
00732 {
00733   if (d->peer != NULL)
00734     return d->peer;
00735   if (d->flags & passiveSocket || d->status < connected)
00736     return NULL;
00737 
00738   return d->peer = peerAddress(sockfd);
00739 }
00740 
00741 /*
00742  * Perform the lookup on the addresses given
00743  */
00744 int KExtendedSocket::lookup()
00745 {
00746   if (startAsyncLookup() != 0)
00747     return -1;
00748 
00749   if (!d->resRemote.wait() || !d->resLocal.wait())
00750     {
00751       d->status = nothing;
00752       return -1;
00753     }
00754 
00755   d->status = lookupDone;
00756   if (d->resRemote.error() != KResolver::NoError)
00757     return d->resRemote.error();
00758   if (d->resLocal.error() != KResolver::NoError)
00759     return d->resLocal.error();
00760   return 0;
00761 }
00762 
00763 /*
00764  * Performs an asynchronous lookup on the given address(es)
00765  */
00766 int KExtendedSocket::startAsyncLookup()
00767 {
00768   cleanError();
00769   if (d->status > lookupInProgress)
00770     return -1;
00771   if (d->status == lookupInProgress)
00772     // already in progress
00773     return 0;
00774 
00775   /* check socket type flags */
00776   int socktype, familyMask, flags;
00777   if (!process_flags(d->flags, socktype, familyMask, flags))
00778     return -2;
00779 
00780   // perform the global lookup before
00781   if (!d->resRemote.isRunning())
00782     {
00783       d->resRemote.setFlags(flags);
00784       d->resRemote.setFamily(familyMask);
00785       d->resRemote.setSocketType(socktype);
00786       QObject::connect(&d->resRemote, SIGNAL(finished(KResolverResults)), 
00787                this, SLOT(dnsResultsReady()));
00788 
00789       if (!d->resRemote.start())
00790     {
00791       setError(IO_LookupError, d->resRemote.error());
00792       return d->resRemote.error();
00793     }
00794     }
00795 
00796   if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning())
00797     {
00798       /* keep flags, but make this passive */
00799       flags |= KResolver::Passive;
00800       d->resLocal.setFlags(flags);
00801       d->resLocal.setFamily(familyMask);
00802       d->resLocal.setSocketType(socktype);
00803       QObject::connect(&d->resLocal, SIGNAL(finished(KResolverResults)), 
00804                this, SLOT(dnsResultsReady()));
00805 
00806       if (!d->resLocal.start())
00807     {
00808       setError(IO_LookupError, d->resLocal.error());
00809       return d->resLocal.error();
00810     }
00811     }
00812 
00813   // if we are here, there were no errors
00814   if (d->resRemote.isRunning() || d->resLocal.isRunning())
00815     d->status = lookupInProgress; // only if there actually is a running lookup
00816   else
00817     {
00818       d->status = lookupDone;
00819       emit lookupFinished(d->resRemote.results().count() + 
00820               d->resLocal.results().count());
00821     }
00822   return 0;
00823 }
00824 
00825 void KExtendedSocket::cancelAsyncLookup()
00826 {
00827   cleanError();
00828   if (d->status != lookupInProgress)
00829     return;         // what's to cancel?
00830 
00831   d->status = nothing;
00832   d->resLocal.cancel(false);
00833   d->resRemote.cancel(false);
00834 }
00835 
00836 int KExtendedSocket::listen(int N)
00837 {
00838   cleanError();
00839   if ((d->flags & passiveSocket) == 0 || d->status >= listening)
00840     return -2;
00841   if (d->status < lookupDone)
00842     if (lookup() != 0)
00843       return -2;        // error!
00844   if (d->resRemote.error())
00845     return -2;
00846   
00847   // doing the loop:
00848   KResolverResults::const_iterator it;
00849   KResolverResults res = d->resRemote.results();
00850   for (it = res.begin(); it != res.end(); ++it)
00851     {
00852       //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl;
00853       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
00854       if (sockfd == -1)
00855     {
00856       // socket failed creating
00857       //kdDebug(170) << "Failed to create: " << perror << endl;
00858       continue;
00859     }
00860     
00861       fcntl(sockfd, F_SETFD, FD_CLOEXEC);
00862 
00863       if (d->addressReusable)
00864     setAddressReusable(sockfd, true);
00865       setIPv6Only(d->ipv6only);
00866       cleanError();
00867       if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1)
00868     {
00869       //kdDebug(170) << "Failed to bind: " << perror << endl;
00870 	  ::close(sockfd);
00871       sockfd = -1;
00872       continue;
00873     }
00874 
00875       // ok, socket has bound
00876       // kdDebug(170) << "Socket bound: " << sockfd << endl;
00877 
00878       d->status = bound;
00879       break;
00880     }
00881 
00882   if (sockfd == -1)
00883     {
00884       setError(IO_ListenError, errno);
00885       //kdDebug(170) << "Listen error - sockfd is -1 " << endl;
00886       return -1;
00887     }
00888 
00889   d->status = bound;
00890   setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00891 
00892   int retval = KSocks::self()->listen(sockfd, N);
00893   if (retval == -1)
00894     setError(IO_ListenError, errno);
00895   else
00896     {
00897       d->status = listening;
00898       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
00899       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
00900     }
00901   return retval == -1 ? -1 : 0;
00902 }
00903 
00904 int KExtendedSocket::accept(KExtendedSocket *&sock)
00905 {
00906   cleanError();
00907   sock = NULL;
00908   if ((d->flags & passiveSocket) == 0 || d->status >= accepting)
00909     return -2;
00910   if (d->status < listening)
00911     if (listen() < 0)
00912       return -2;        // error!
00913 
00914   // let's see
00915   // if we have a timeout in place, we have to place this socket in non-blocking
00916   // mode
00917   bool block = blockingMode();
00918   struct sockaddr sa;
00919   ksocklen_t len = sizeof(sa);
00920   sock = NULL;
00921 
00922   if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0)
00923     {
00924       fd_set set;
00925 
00926       setBlockingMode(false);   // turn on non-blocking
00927       FD_ZERO(&set);
00928       FD_SET(sockfd, &set);
00929 
00930       //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n",
00931       //         sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
00932       // check if there is anything to accept now
00933       int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout);
00934       if (retval == -1)
00935     {
00936       setError(IO_UnspecifiedError, errno);
00937       return -1;        // system error
00938     }
00939       else if (retval == 0 || !FD_ISSET(sockfd, &set))
00940     {
00941       setError(IO_TimeOutError, 0);
00942       return -3;        // timeout
00943     }
00944     }
00945 
00946   // it's common stuff here
00947   int newfd = KSocks::self()->accept(sockfd, &sa, &len);
00948 
00949   if (newfd == -1)
00950     {
00951       setError(IO_AcceptError, errno);
00952       kdWarning(170) << "Error accepting on socket " << sockfd << ":"
00953              << perror << endl;
00954       return -1;
00955     }
00956 
00957   fcntl(newfd, F_SETFD, FD_CLOEXEC);
00958 
00959   //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd);
00960 
00961   setBlockingMode(block);   // restore blocking mode
00962 
00963   sock = new KExtendedSocket;
00964   sock->d->status = connected;
00965   sock->sockfd = newfd;
00966   sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00967   sock->setBufferSize(0, 0);    // always unbuffered here. User can change that later
00968 
00969   return 0;
00970 }
00971 
00972 /*
00973  * tries to connect
00974  *
00975  * FIXME!
00976  * This function is critical path. It has to be cleaned up and made faster
00977  */
00978 int KExtendedSocket::connect()
00979 {
00980   cleanError();
00981   if (d->flags & passiveSocket || d->status >= connected)
00982     return -2;
00983   if (d->status < lookupDone)
00984     if (lookup() != 0)
00985       return -2;
00986 
00987   timeval end, now;
00988   // Ok, things are a little tricky here
00989   // Let me explain
00990   // getaddrinfo() will return several different families of sockets
00991   // When we have to bind before we connect, we have to make sure we're binding
00992   // and connecting to the same family, or things won't work
00993 
00994   bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
00995   if (doingtimeout)
00996     {
00997       gettimeofday(&end, NULL);
00998       end.tv_usec += d->timeout.tv_usec;
00999       end.tv_sec += d->timeout.tv_sec;
01000       if (end.tv_usec > 1000*1000)
01001     {
01002       end.tv_usec -= 1000*1000;
01003       end.tv_sec++;
01004     }
01005 //  kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n",
01006 //           d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec);
01007     }
01008 
01009   KResolverResults remote = d->resRemote.results(),
01010     local = d->resLocal.results();
01011   KResolverResults::const_iterator it, it2;
01012   //kdDebug(170) << "Starting connect to " << host() << '|' << port() 
01013   //             << ": have " << local.count() << " local entries and "
01014   //             << remote.count() << " remote" << endl;
01015   for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
01016     {
01017       //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl;
01018       if (it2 != local.end())
01019     {
01020 //    //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl;
01021       if ((*it).family() != (*it2).family())
01022         // differing families, scan local for a matching family
01023         for (it2 = local.begin(); it2 != local.end(); ++it2)
01024           if ((*it).family() == (*it2).family())
01025         break;
01026 
01027       if ((*it).family() != (*it2).family())
01028         {
01029           // no matching families for this
01030           //kdDebug(170) << "No matching family for bind socket\n";
01031           it2 = local.begin();
01032           continue;
01033         }
01034 
01035       //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl;
01036       errno = 0;
01037       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01038       setError(IO_ConnectError, errno);
01039       if (sockfd == -1)
01040         continue;       // cannot create this socket
01041           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01042       if (d->addressReusable)
01043         setAddressReusable(sockfd, true);
01044       setIPv6Only(d->ipv6only);
01045       cleanError();
01046       if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
01047         {
01048           //kdDebug(170) << "Bind failed: " << perror << endl;
01049 	      ::close(sockfd);
01050           sockfd = -1;
01051           continue;
01052         }
01053     }
01054       else
01055     {
01056       // no need to bind, just create
01057       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01058       if (sockfd == -1)
01059         {
01060           setError(IO_ConnectError, errno);
01061           continue;
01062         }
01063           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01064       if (d->addressReusable)
01065         setAddressReusable(sockfd, true);
01066       setIPv6Only(d->ipv6only);
01067       cleanError();
01068     }
01069 
01070 //      kdDebug(170) << "Socket " << sockfd << " created" << endl;
01071       d->status = created;
01072 
01073       // check if we have to do timeout
01074       if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
01075     {
01076       fd_set rd, wr;
01077 
01078       setBlockingMode(false);
01079 
01080       // now try and connect
01081       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01082         {
01083           // this could be EWOULDBLOCK
01084           if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01085         {
01086           //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl;
01087           setError(IO_ConnectError, errno);
01088 		  ::close(sockfd);
01089           sockfd = -1;
01090           continue; // nope, another error
01091         }
01092 
01093           FD_ZERO(&rd);
01094           FD_ZERO(&wr);
01095           FD_SET(sockfd, &rd);
01096           FD_SET(sockfd, &wr);
01097 
01098           int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
01099           if (retval == -1)
01100         {
01101           setError(IO_FatalError, errno);
01102           continue; // system error
01103         }
01104           else if (retval == 0)
01105         {
01106 		  ::close(sockfd);
01107           sockfd = -1;
01108 //        kdDebug(170) << "Time out while trying to connect to " <<
01109 //          (*it).address().toString() << endl;
01110           d->status = lookupDone;
01111           setError(IO_TimeOutError, 0);
01112           return -3;    // time out
01113         }
01114 
01115           // adjust remaining time
01116           gettimeofday(&now, NULL);
01117           d->timeout.tv_sec = end.tv_sec - now.tv_sec;
01118           d->timeout.tv_usec = end.tv_usec - now.tv_usec;
01119           if (d->timeout.tv_usec < 0)
01120         {
01121           d->timeout.tv_usec += 1000*1000;
01122           d->timeout.tv_sec--;
01123         }
01124 //        kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n",
01125 //               sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
01126 
01127           // this means that an event occurred in the socket
01128           int errcode;
01129           socklen_t len = sizeof(errcode);
01130           retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
01131                   &len);
01132           if (retval == -1 || errcode != 0)
01133         {
01134           // socket did not connect
01135           //kdDebug(170) << "Socket " << sockfd << " did not connect: "
01136           //        << strerror(errcode) << endl;
01137 		  ::close(sockfd);
01138           sockfd = -1;
01139 
01140           // this is HIGHLY UNLIKELY
01141           if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
01142             {
01143               d->status = lookupDone;
01144               setError(IO_TimeOutError, 0);
01145               return -3; // time out
01146             }
01147 
01148           setError(IO_ConnectError, errcode);
01149           continue;
01150         }
01151         }
01152 
01153       // getting here means it connected
01154       // setBufferSize() takes care of creating the socket notifiers
01155       setBlockingMode(true);
01156       d->status = connected;
01157       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01158       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01159             d->flags & outputBufferedSocket ? -1 : 0);
01160       emit connectionSuccess();
01161 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01162       return 0;
01163     }
01164       else
01165     {
01166       // without timeouts
01167       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01168         {
01169           //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString() 
01170           //       << " did not connect: " << perror << endl;
01171           setError(IO_ConnectError, errno);
01172 	      ::close(sockfd);
01173           sockfd = -1;
01174           continue;
01175         }
01176 
01177       d->status = connected;
01178       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01179       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01180             d->flags & outputBufferedSocket ? -1 : 0);
01181       emit connectionSuccess();
01182 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01183       return 0;     // it connected
01184     }
01185     }
01186 
01187   // getting here means no socket connected or stuff like that
01188   emit connectionFailed(d->syserror);
01189   //kdDebug(170) << "Failed to connect\n";
01190   return -1;
01191 }
01192 
01193 int KExtendedSocket::startAsyncConnect()
01194 {
01195   cleanError();
01196   // check status
01197   if (d->status >= connected || d->flags & passiveSocket)
01198     return -2;
01199 
01200   if (d->status == connecting)
01201     // already on async connect
01202     return 0;
01203 
01204   // check if we have to do lookup
01205   // if we do, then we'll use asynchronous lookup and use
01206   // signal lookupFinished to do connection
01207   if (d->status < lookupDone)
01208     {
01209       QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01210       if (d->status < lookupInProgress)
01211     return startAsyncLookup();
01212       else
01213     return 0;       // we still have to wait
01214     }
01215 
01216   // here we have d->status >= lookupDone and <= connecting
01217   // we can do our connection
01218   d->status = connecting;
01219   QGuardedPtr<QObject> p = this;
01220   connectionEvent();
01221   if (!p) 
01222     return -1; // We have been deleted.
01223   if (d->status < connecting)
01224     return -1;
01225   return 0;
01226 }
01227 
01228 void KExtendedSocket::cancelAsyncConnect()
01229 {
01230   if (d->status != connecting)
01231     return;
01232 
01233   if (sockfd != -1)
01234     {
01235       // we have a waiting connection
01236       if (d->qsnIn)
01237     delete d->qsnIn;
01238       if (d->qsnOut)
01239     delete d->qsnOut;
01240       d->qsnIn = d->qsnOut = NULL;
01241 
01242       ::close(sockfd);
01243       sockfd = -1;
01244     }
01245   d->status = lookupDone;
01246 }
01247 
01248 bool KExtendedSocket::open(int mode)
01249 {
01250   if (mode != IO_Raw | IO_ReadWrite)
01251     return false;       // invalid open mode
01252 
01253   if (d->flags & passiveSocket)
01254     return listen() == 0;
01255   else if (d->status < connecting)
01256     return connect() == 0;
01257   else
01258     return false;
01259 }
01260 
01261 void KExtendedSocket::close()
01262 {
01263   if (sockfd == -1 || d->status >= closing)
01264     return;         // nothing to close
01265 
01266   // LOCK BUFFER MUTEX
01267   if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
01268     {
01269       // write buffer not empty, go into closing state
01270       d->status = closing;
01271       if (d->qsnIn)
01272     delete d->qsnIn;
01273       d->qsnIn = NULL;
01274       // we keep the outgoing socket notifier because we want
01275       // to send data, but not receive
01276     }
01277   else
01278     {
01279       // nope, write buffer is empty
01280       // we can close now
01281       if (d->qsnIn)
01282     delete d->qsnIn;
01283       if (d->qsnOut)
01284     delete d->qsnOut;
01285       d->qsnIn = d->qsnOut = NULL;
01286 
01287       ::close(sockfd);
01288       d->status = done;
01289       emit closed(readBufferSize() != 0 ? availRead : 0);
01290     }
01291   // UNLOCK BUFFER MUTEX
01292 }
01293 
01294 
01295 void KExtendedSocket::closeNow()
01296 {
01297   if (d->status >= done)
01298     return;         // nothing to close
01299 
01300   // close the socket
01301   delete d->qsnIn;
01302   delete d->qsnOut;
01303   d->qsnIn = d-&g