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->qsnOut = NULL;
01304 
01305   if (d->status > connecting && sockfd != -1)
01306     {
01307       ::close(sockfd);
01308       sockfd = -1;
01309     }
01310   else if (d->status == connecting)
01311     cancelAsyncConnect();
01312   else if (d->status == lookupInProgress)
01313     cancelAsyncLookup();
01314 
01315   d->status = done;
01316 
01317   emit closed(closedNow |
01318           (readBufferSize() != 0 ? availRead : 0) |
01319           (writeBufferSize() != 0 ? dirtyWrite : 0));
01320 }
01321 
01322 void KExtendedSocket::release()
01323 {
01324   // release our hold on the socket
01325   sockfd = -1;
01326   d->status = done;
01327 
01328   d->resRemote.cancel(false);
01329   d->resLocal.cancel(false);
01330 
01331   if (d->local != NULL)
01332     delete d->local;
01333   if (d->peer != NULL)
01334     delete d->peer;
01335 
01336   d->peer = d->local = NULL;
01337 
01338   if (d->qsnIn != NULL)
01339     delete d->qsnIn;
01340   if (d->qsnOut != NULL)
01341     delete d->qsnOut;
01342 
01343   d->qsnIn = d->qsnOut = NULL;
01344 
01345   // now that the socket notificators are done with, we can flush out the buffers
01346   consumeReadBuffer(readBufferSize(), NULL, true);
01347   consumeWriteBuffer(writeBufferSize());
01348 
01349   // don't delete d
01350   // leave that for the destructor
01351 }
01352 
01353 void KExtendedSocket::flush()
01354 {
01355   cleanError();
01356   if (d->status < connected || d->status >= done || d->flags & passiveSocket)
01357     return;
01358 
01359   if (sockfd == -1)
01360     return;
01361 
01362   if ((d->flags & outputBufferedSocket) == 0)
01363     return;         // nothing to do
01364 
01365   // LOCK MUTEX
01366 
01367   unsigned written = 0;
01368   unsigned offset = outBufIndex; // this happens only for the first
01369   while (writeBufferSize() - written > 0)
01370     {
01371       // we have to write each output buffer in outBuf
01372       // but since we can have several very small buffers, we can make things
01373       // better by concatenating a few of them into a big buffer
01374       // question is: how big should that buffer be? 16 kB should be enough
01375 
01376       QByteArray buf(16384);
01377       QByteArray *a = outBuf.first();
01378       unsigned count = 0;
01379 
01380       while (a && count + (a->size() - offset) <= buf.size())
01381     {
01382       memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
01383       count += a->size() - offset;
01384       offset = 0;
01385       a = outBuf.next();
01386     }
01387 
01388       // see if we can still fit more
01389       if (a && count < buf.size())
01390     {
01391       // getting here means this buffer (a) is larger than
01392       // (buf.size() - count) (even for count == 0).
01393       memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
01394       offset += buf.size() - count;
01395       count = buf.size();
01396     }
01397 
01398       // now try to write those bytes
01399       int wrote = KSocks::self()->write(sockfd, buf, count);
01400 
01401       if (wrote == -1)
01402     {
01403       // could be EAGAIN (EWOULDBLOCK)
01404       setError(IO_WriteError, errno);
01405       break;
01406     }
01407       written += wrote;
01408 
01409       if ((unsigned)wrote != count)
01410     break;
01411     }
01412   if (written)
01413     {
01414       consumeWriteBuffer(written);
01415       emit bytesWritten(written);
01416     }
01417 
01418   // UNLOCK MUTEX
01419 }
01420 
01421 
01422 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen)
01423 {
01424   cleanError();
01425   if (d->status < connected || d->flags & passiveSocket)
01426     return -2;
01427 
01428   int retval;
01429 
01430   if ((d->flags & inputBufferedSocket) == 0)
01431     {
01432       // we aren't buffering this socket, so just pass along
01433       // the call to the real read method
01434 
01435       if (sockfd == -1)
01436     return -2;
01437       if (data)
01438     retval = KSocks::self()->read(sockfd, data, maxlen);
01439       else
01440     retval = skipData(sockfd, maxlen);
01441       if (retval == -1)
01442     setError(IO_ReadError, errno);
01443     }
01444   else
01445     {
01446       // this socket is being buffered. So read from the buffer
01447 
01448       // LOCK BUFFER MUTEX
01449 
01450       retval = consumeReadBuffer(maxlen, data);
01451       if (retval == 0)
01452     {
01453       // consumeReadBuffer returns 0 only if the buffer is
01454       // empty
01455       if (sockfd == -1)
01456         return 0;       // buffer is clear now, indicate EOF
01457       setError(IO_ReadError, EWOULDBLOCK);
01458       retval = -1;
01459     }
01460 
01461       // UNLOCK BUFFER MUTEX
01462 
01463     }
01464   return retval;
01465 }
01466 
01467 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len)
01468 {
01469   cleanError();
01470   if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
01471     return -2;
01472   if (sockfd == -1)
01473     return -2;
01474 
01475   if (len == 0)
01476     return 0;           // what's to write?
01477 
01478   int retval;
01479 
01480   if ((d->flags & outputBufferedSocket) == 0)
01481     {
01482       // socket not buffered. Just call write
01483       retval = KSocks::self()->write(sockfd, data, len);
01484       if (retval == -1)
01485     setError(IO_WriteError, errno);
01486       else
01487     emit bytesWritten(retval);
01488     }
01489   else
01490     {
01491       // socket is buffered. Feed the write buffer
01492 
01493       // LOCK BUFFER MUTEX
01494 
01495       register unsigned wsize = writeBufferSize();
01496       if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning
01497     {
01498       // buffer is full!
01499       setError(IO_WriteError, EWOULDBLOCK);
01500       retval = -1;
01501     }
01502       else
01503     {
01504       if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
01505         // we cannot write all data. Write just as much as to fill the buffer
01506         len = d->outMaxSize - wsize;
01507 
01508       // len > 0 here
01509       retval = feedWriteBuffer(len, data);
01510       if (wsize == 0 || d->emitWrite)
01511         // buffer was empty, which means that the notifier is probably disabled
01512         d->qsnOut->setEnabled(true);
01513     }
01514 
01515       // UNLOCK BUFFER MUTEX
01516     }
01517 
01518   return retval;
01519 }
01520 
01521 int KExtendedSocket::peekBlock(char *data, uint maxlen)
01522 {
01523   if (d->status < connected || d->flags & passiveSocket)
01524     return -2;
01525   if (sockfd == -1)
01526     return -2;
01527 
01528   // need to LOCK MUTEX around this call...
01529 
01530   if (d->flags & inputBufferedSocket)
01531     return consumeReadBuffer(maxlen, data, false);
01532 
01533   return 0;
01534 }
01535 
01536 int KExtendedSocket::unreadBlock(const char *, uint)
01537 {
01538   // Always return -1, indicating this is not supported
01539   setError(IO_ReadError, ENOSYS);
01540   return -1;
01541 }
01542 
01543 int KExtendedSocket::bytesAvailable() const
01544 {
01545   if (d->status < connected || d->flags & passiveSocket)
01546     return -2;
01547 
01548   // as of now, we don't do any extra processing
01549   // we only work in input-buffered sockets
01550   if (d->flags & inputBufferedSocket)
01551     return KBufferedIO::bytesAvailable();
01552 
01553   return 0;         // TODO: FIONREAD ioctl
01554 }
01555 
01556 int KExtendedSocket::waitForMore(int msecs)
01557 {
01558   cleanError();
01559   if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
01560     return -2;
01561   if (sockfd == -1)
01562     return -2;
01563 
01564   fd_set rd;
01565   FD_ZERO(&rd);
01566   FD_SET(sockfd, &rd);
01567   timeval tv;
01568   tv.tv_sec = msecs / 1000;
01569   tv.tv_usec = (msecs % 1000) * 1000;
01570 
01571   int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
01572   if (retval == -1)
01573     {
01574       setError(IO_FatalError, errno);
01575       return -1;
01576     }
01577   else if (retval != 0)
01578     socketActivityRead();   // do read processing
01579 
01580   return bytesAvailable();
01581 }
01582 
01583 int KExtendedSocket::getch()
01584 {
01585   unsigned char c;
01586   int retval;
01587   retval = readBlock((char*)&c, sizeof(c));
01588 
01589   if (retval < 0)
01590     return retval;
01591   return c;
01592 }
01593 
01594 int KExtendedSocket::putch(int ch)
01595 {
01596   unsigned char c = (char)ch;
01597   return writeBlock((char*)&c, sizeof(c));
01598 }
01599 
01600 // sets the emission of the readyRead signal
01601 void KExtendedSocket::enableRead(bool enable)
01602 {
01603   // check if we can disable the socket notifier
01604   // saves us a few cycles
01605   // this is so because in buffering mode, we rely on these signals
01606   // being emitted to do our I/O. We couldn't disable them here
01607   if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
01608     d->qsnIn->setEnabled(false);
01609   else if (enable && d->qsnIn)
01610     // we can enable it always
01611     d->qsnIn->setEnabled(true);
01612   d->emitRead = enable;
01613 }
01614 
01615 // sets the emission of the readyWrite signal
01616 void KExtendedSocket::enableWrite(bool enable)
01617 {
01618   // same thing as above
01619   if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
01620     d->qsnOut->setEnabled(false);
01621   else if (enable && d->qsnOut)
01622     // we can enable it always
01623     d->qsnOut->setEnabled(true);
01624   d->emitWrite = enable;
01625 }
01626 
01627 // protected slot
01628 // this is connected to d->qsnIn::activated(int)
01629 void KExtendedSocket::socketActivityRead()
01630 {
01631   if (d->flags & passiveSocket)
01632     {
01633       emit readyAccept();
01634       return;
01635     }
01636   if (d->status == connecting)
01637     {
01638       connectionEvent();
01639       return;
01640     }
01641   if (d->status != connected)
01642     return;
01643 
01644   // do we need to do I/O here?
01645   if (d->flags & inputBufferedSocket)
01646     {
01647       // aye. Do read from the socket and feed our buffer
01648       QByteArray a;
01649       char buf[1024];
01650       int len, totalread = 0;
01651 
01652       // LOCK MUTEX
01653 
01654       unsigned cursize = readBufferSize();
01655 
01656       if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
01657     {
01658       do
01659         {
01660           // check that we can read that many bytes
01661           if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
01662         // no, that would overrun the buffer
01663         // note that this will also make us exit the loop
01664         len = d->inMaxSize - (cursize + totalread);
01665           else
01666         len = sizeof(buf);
01667 
01668           len = KSocks::self()->read(sockfd, buf, len);
01669           if (len > 0)
01670         {
01671           // normal read operation
01672           a.resize(a.size() + len);
01673           memcpy(a.data() + totalread, buf, len);
01674           totalread += len; // totalread == a.size() now
01675         }
01676           else if (len == 0)
01677         {
01678           // EOF condition here
01679 		  ::close(sockfd);
01680           sockfd = -1;  // we're closed
01681           d->qsnIn->deleteLater();
01682           delete d->qsnOut;
01683           d->qsnIn = d->qsnOut = NULL;
01684           d->status = done;
01685           emit closed(involuntary |
01686                   (readBufferSize() ? availRead : 0) |
01687                   (writeBufferSize() ? dirtyWrite : 0));
01688           return;
01689         }
01690           else
01691         {
01692           // error!
01693           setError(IO_ReadError, errno);
01694           return;
01695         }
01696           // will loop only for normal read operations
01697         }
01698       while (len == sizeof(buf));
01699 
01700       feedReadBuffer(a.size(), a.data());
01701     }
01702 
01703       // UNLOCK MUTEX
01704     }
01705   else
01706     {
01707       // No input buffering, but the notifier fired
01708       // That means that either there is data to be read or that the 
01709       // socket closed.
01710 
01711       // try to read one byte. If we can't, then the socket got closed
01712 
01713       char c;
01714       int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
01715       if (len == 0)
01716     {
01717       // yes, it's an EOF condition
01718       d->qsnIn->setEnabled(false);
01719 	  ::close(sockfd);
01720       sockfd = -1;
01721       d->status = done;
01722       emit closed(involuntary);
01723       return;
01724     }
01725     }
01726 
01727   if (d->emitRead)
01728     emit readyRead();
01729 }
01730 
01731 void KExtendedSocket::socketActivityWrite()
01732 {
01733   if (d->flags & passiveSocket)
01734     return;
01735   if (d->status == connecting)
01736     {
01737       connectionEvent();
01738       return;
01739     }
01740   if (d->status != connected && d->status != closing)
01741     return;
01742 
01743   flush();
01744 
01745   bool empty = writeBufferSize() == 0;
01746 
01747   if (d->emitWrite && empty)
01748     emit readyWrite();
01749   else if (!d->emitWrite)
01750     {
01751       // check if we can disable the notifier
01752       d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send
01753     }
01754   if (d->status == closing && empty)
01755     {
01756       // done sending the missing data!
01757       d->status = done;
01758 
01759       delete d->qsnOut;
01760       ::close(sockfd);
01761 
01762       d->qsnOut = NULL;
01763       sockfd = -1;
01764       emit closed(delayed | (readBufferSize() ? availRead : 0));
01765     }
01766 }
01767 
01768 // this function is called whenever we have a "connection event"
01769 // that is, whenever our asynchronously connecting socket throws
01770 // an event
01771 void KExtendedSocket::connectionEvent()
01772 {
01773   if (d->status != connecting)
01774     return;         // move along. There's nothing to see here
01775 
01776   KResolverResults remote = d->resRemote.results();
01777   if (remote.count() == 0)
01778     {
01779       // We have a problem! Abort?
01780       kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
01781       return;
01782     }
01783 
01784   int errcode = 0;
01785 
01786   if (sockfd != -1)
01787     {
01788       // our socket has activity
01789       // find out what it was
01790       int retval;
01791       socklen_t len = sizeof(errcode);
01792       retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
01793 
01794       if (retval == -1 || errcode != 0)
01795     {
01796       // socket activity and there was error?
01797       // that means the socket probably did not connect
01798       if (d->qsnIn)
01799         delete d->qsnIn;
01800       if (d->qsnOut)
01801         delete d->qsnOut;
01802 	  ::close(sockfd);
01803 
01804       sockfd = -1;
01805       d->qsnIn = d->qsnOut = NULL;
01806       d->current++;
01807       setError(IO_ConnectError, errcode);
01808     }
01809       else
01810     {
01811       // hmm, socket activity and there was no error?
01812       // that means it connected
01813       // YAY!
01814       cleanError();
01815       d->status = connected;
01816       setBlockingMode(true);
01817       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01818       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01819             d->flags & outputBufferedSocket ? -1 : 0);
01820       emit connectionSuccess();
01821       return;
01822     }
01823     }
01824 
01825   // ok, we have to try something here
01826   // and sockfd == -1
01827   KResolverResults local = d->resLocal.results();
01828   unsigned localidx = 0;
01829   for ( ; d->current < remote.count(); d->current++)
01830     {
01831       // same code as in connect()
01832       if (local.count() != 0)
01833     {
01834       // scan bindres for a local resuls family
01835       for (localidx = 0; localidx < local.count(); localidx++)
01836         if (remote[d->current].family() == local[localidx].family())
01837           break;
01838 
01839       if (remote[d->current].family() != local[localidx].family())
01840         {
01841           // no matching families for this
01842           continue;
01843         }
01844 
01845       errno = 0;
01846       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01847                 remote[d->current].protocol());
01848       setError(IO_ConnectError, errno);
01849       errcode = errno;
01850       if (sockfd == -1)
01851         continue;       // cannot create this socket
01852           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01853       if (d->addressReusable)
01854         setAddressReusable(sockfd, true);
01855       setIPv6Only(d->ipv6only);
01856       cleanError();
01857       if (KSocks::self()->bind(sockfd, local[localidx].address(), 
01858                    local[localidx].length()) == -1)
01859         {
01860 	      ::close(sockfd);
01861           sockfd = -1;
01862           continue;
01863         }
01864     }
01865       else
01866     {
01867       // no need to bind, just create
01868       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01869                 remote[d->current].protocol());
01870       if (sockfd == -1)
01871         {
01872           setError(IO_ConnectError, errno);
01873           errcode = errno;
01874           continue;
01875         }
01876           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01877       if (d->addressReusable)
01878         setAddressReusable(sockfd, true);
01879       setIPv6Only(d->ipv6only);
01880       cleanError();
01881     }
01882 
01883       if (KSocks::self()->hasWorkingAsyncConnect())
01884         setBlockingMode(false);
01885       if (KSocks::self()->connect(sockfd, remote[d->current].address(), 
01886                   remote[d->current].length()) == -1)
01887     {
01888       if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01889         {
01890           setError(IO_ConnectError, errno);
01891 	      ::close(sockfd);
01892           sockfd = -1;
01893           errcode = errno;
01894           continue;
01895         }
01896 
01897       // error here is either EWOULDBLOCK or EINPROGRESS
01898       // so, it is a good condition
01899       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
01900       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
01901       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
01902       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
01903 
01904       // ok, let the Qt event loop do the selecting for us
01905       return;
01906     }
01907 
01908       // eh, what?
01909       // the non-blocking socket returned valid connection?
01910       // already?
01911       // I suppose that could happen...
01912       cleanError();
01913       d->status = connected;
01914       setBlockingMode(true);
01915       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01916       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01917             d->flags & outputBufferedSocket ? -1 : 0);
01918       emit connectionSuccess();
01919       return;
01920     }
01921 
01922   // if we got here, it means that there are no more options to connect
01923   d->status = lookupDone;   // go back
01924   emit connectionFailed(errcode);
01925 }
01926 
01927 void KExtendedSocket::dnsResultsReady()
01928 {
01929   // check that this function was called in a valid state
01930   if (d->status != lookupInProgress)
01931     return;
01932 
01933   // valid state. Are results fully ready?
01934   if (d->resRemote.isRunning() || d->resLocal.isRunning())
01935     // no, still waiting for answer in one of the lookups
01936     return;
01937 
01938   // ok, we have all results
01939   // count how many results we have
01940   int n = d->resRemote.results().count() + d->resLocal.results().count();
01941 
01942   if (n)
01943     {
01944       d->status = lookupDone;
01945       cleanError();
01946     }
01947   else
01948     {
01949       d->status = nothing;
01950       setError(IO_LookupError, KResolver::NoName);
01951     }
01952 
01953   emit lookupFinished(n);
01954 
01955   return;
01956 }
01957 
01958 void KExtendedSocket::startAsyncConnectSlot()
01959 {
01960   QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01961 
01962   if (d->status == lookupDone)
01963     startAsyncConnect();
01964 }
01965 
01966 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host,
01967                  QString &port, int flags)
01968 {
01969   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01970 
01971   int err;
01972   char h[NI_MAXHOST], s[NI_MAXSERV];
01973 
01974   h[0] = s[0] = '\0';
01975 
01976   err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
01977   host = QString::fromUtf8(h);
01978   port = QString::fromUtf8(s);
01979 
01980   return err;
01981 }
01982 
01983 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port,
01984                  int flags)
01985 {
01986   return resolve(sock->data, sock->datasize, host, port, flags);
01987 }
01988 
01989 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port,
01990                         int userflags, int *error)
01991 {
01992   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01993 
01994   int socktype, familyMask, flags;
01995   unsigned i;
01996   QPtrList<KAddressInfo> l;
01997 
01998   /* check socket type flags */
01999   if (!process_flags(userflags, socktype, familyMask, flags))
02000     return l;
02001 
02002 //  kdDebug(170) << "Performing lookup on " << host << "|" << port << endl;
02003   KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
02004   if (res.error())
02005     {
02006       if (error)
02007     *error = res.error();
02008       return l;
02009     }
02010 
02011   for (i = 0; i < res.count(); i++)
02012     {
02013       KAddressInfo *ai = new KAddressInfo();
02014 
02015       // I should have known that using addrinfo was going to come
02016       // and bite me back some day...
02017       ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
02018       memset(ai->ai, 0, sizeof(addrinfo));
02019 
02020       ai->ai->ai_family = res[i].family();
02021       ai->ai->ai_socktype = res[i].socketType();
02022       ai->ai->ai_protocol = res[i].protocol();
02023       QString canon = res[i].canonicalName();
02024       if (!canon.isEmpty())
02025     {
02026       ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
02027       strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional
02028     }
02029       if ((ai->ai->ai_addrlen = res[i].length()))
02030     {
02031       ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
02032       memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
02033     }
02034       else
02035     {
02036       ai->ai->ai_addr = 0;
02037     }
02038 
02039       ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
02040 
02041       l.append(ai);
02042     }
02043 
02044   if ( error )
02045       *error = 0;               // all is fine!
02046 
02047   return l;
02048 }
02049 
02050 ::KSocketAddress *KExtendedSocket::localAddress(int fd)
02051 {
02052   ::KSocketAddress *local;
02053   struct sockaddr static_sa, *sa = &static_sa;
02054   ksocklen_t len = sizeof(static_sa);
02055 
02056   /* find out the socket length, in advance
02057    * we use a sockaddr allocated on the heap just not to pass down
02058    * a NULL pointer to the first call. Some systems are reported to
02059    * set len to 0 if we pass NULL as the sockaddr */
02060   if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02061     return NULL;        // error!
02062 
02063   /* was it enough? */
02064   if (len > sizeof(static_sa)
02065 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02066       || sa->sa_len > sizeof(static_sa)
02067 #endif
02068       )
02069     {
02070       /* nope, malloc a new socket with the proper size */
02071 
02072 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02073       if (sa->sa_len != len)
02074         len = sa->sa_len;
02075 #endif
02076 
02077       sa = (sockaddr*)malloc(len);
02078       if (sa == NULL)
02079     return NULL;        // out of memory
02080 
02081       if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02082     {
02083       free(sa);
02084       return NULL;
02085     }
02086 
02087       local = ::KSocketAddress::newAddress(sa, len);
02088       free(sa);
02089     }
02090   else
02091     local = ::KSocketAddress::newAddress(sa, len);
02092 
02093   return local;
02094 }
02095 
02096 /* This is exactly the same code as localAddress, except
02097  * we call getpeername here */
02098 ::KSocketAddress *KExtendedSocket::peerAddress(int fd)
02099 {
02100   ::KSocketAddress *peer;
02101   struct sockaddr static_sa, *sa = &static_sa;
02102   ksocklen_t len = sizeof(static_sa);
02103 
02104   /* find out the socket length, in advance
02105    * we use a sockaddr allocated on the heap just not to pass down
02106    * a NULL pointer to the first call. Some systems are reported to
02107    * set len to 0 if we pass NULL as the sockaddr */
02108   if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02109     return NULL;        // error!
02110 
02111   /* was it enough? */
02112   if (len > sizeof(static_sa)
02113 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02114       || sa->sa_len > sizeof(static_sa)
02115 #endif
02116       )
02117     {
02118       /* nope, malloc a new socket with the proper size */
02119 
02120 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02121       if (sa->sa_len != len)
02122         len = sa->sa_len;
02123 #endif
02124 
02125       sa = (sockaddr*)malloc(len);
02126       if (sa == NULL)
02127     return NULL;        // out of memory
02128 
02129       if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02130     {
02131       free(sa);
02132       return NULL;
02133     }
02134 
02135       peer = ::KSocketAddress::newAddress(sa, len);
02136       free(sa);
02137     }
02138   else
02139     peer = ::KSocketAddress::newAddress(sa, len);
02140 
02141   return peer;
02142 }
02143 
02144 QString KExtendedSocket::strError(int code, int syserr)
02145 {
02146   const char * msg;
02147   if (code == IO_LookupError)
02148     msg = gai_strerror(syserr);
02149   else
02150     msg = strerror(syserr);
02151 
02152   return QString::fromLocal8Bit(msg);
02153 }
02154 
02155 
02156 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
02157 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
02158 
02159 /*
02160  * class KAddressInfo
02161  */
02162 
02163 #if 0
02164 KAddressInfo::KAddressInfo(addrinfo *p)
02165 {
02166    ai = (addrinfo *) malloc(sizeof(addrinfo));
02167    memcpy(ai, p, sizeof(addrinfo));
02168    ai->ai_next = NULL;
02169    if (p->ai_canonname)
02170    {
02171       ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
02172       strcpy(ai->ai_canonname, p->ai_canonname);
02173    }
02174    if (p->ai_addr && p->ai_addrlen)
02175    {
02176       ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
02177       memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
02178    }
02179    else
02180    {
02181       ai->ai_addr = 0;
02182       ai->ai_addrlen = 0;
02183    }
02184 
02185    addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
02186 }
02187 #endif
02188 KAddressInfo::~KAddressInfo()
02189 {
02190   if (ai && ai->ai_canonname)
02191     free(ai->ai_canonname);
02192 
02193   if (ai && ai->ai_addr)
02194     free(ai->ai_addr);  
02195 
02196   if (ai)
02197     free(ai);
02198   delete addr;
02199 }
02200 
02201 int KAddressInfo::flags() const
02202 {
02203   return ai->ai_flags;
02204 }
02205 
02206 int KAddressInfo::family() const
02207 {
02208   return ai->ai_family;
02209 }
02210 
02211 int KAddressInfo::socktype() const
02212 {
02213   return ai->ai_socktype;
02214 }
02215 
02216 int KAddressInfo::protocol() const
02217 {
02218   return ai->ai_protocol;
02219 }
02220 
02221 const char* KAddressInfo::canonname() const
02222 {
02223   return ai->ai_canonname;
02224 }
02225 
02226 void KExtendedSocket::virtual_hook( int id, void* data )
02227 { KBufferedIO::virtual_hook( id, data ); }
02228 
02229 #include "kextsock.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys