kdecore Library API Documentation

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., 59 Temple Place - Suite 330,
00018  *  Boston, MA 02111-1307, 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 using namespace KNetwork;
00053 
00054 //
00055 // Internal class definitions
00056 //
00057 
00058 class KExtendedSocketPrivate
00059 {
00060 public:
00061   int flags;            // socket flags
00062   int status;           // status
00063   int syserror;         // the system error value
00064 
00065   timeval timeout;      // connection/acception timeout
00066 
00067   KResolver resRemote;      // the resolved addresses
00068   KResolver resLocal;       // binding resolution
00069   unsigned current;     // used by the asynchronous connection
00070 
00071   ::KSocketAddress *local;  // local socket address
00072   ::KSocketAddress *peer;   // peer socket address
00073 
00074   QSocketNotifier *qsnIn, *qsnOut;
00075   int inMaxSize, outMaxSize;
00076   bool emitRead : 1, emitWrite : 1;
00077   mutable bool addressReusable : 1, ipv6only : 1;
00078 
00079   KExtendedSocketPrivate() :
00080     flags(0), status(0), syserror(0),
00081     current(0), local(0), peer(0),
00082     qsnIn(0), qsnOut(0), inMaxSize(-1), outMaxSize(-1), emitRead(false), emitWrite(false),
00083     addressReusable(false), ipv6only(false)
00084   {
00085     timeout.tv_sec = timeout.tv_usec = 0;
00086   }
00087 };
00088 
00089 // translate KExtendedSocket flags into KResolver ones
00090 static bool process_flags(int flags, int& socktype, int& familyMask, int& outflags)
00091 {
00092   switch (flags & (KExtendedSocket::streamSocket | KExtendedSocket::datagramSocket | KExtendedSocket::rawSocket))
00093     {
00094     case 0:
00095       /* No flags given, use default */
00096 
00097     case KExtendedSocket::streamSocket:
00098       /* streaming socket requested */
00099       socktype = SOCK_STREAM;
00100       break;
00101 
00102     case KExtendedSocket::datagramSocket:
00103       /* datagram packet socket requested */
00104       socktype = SOCK_DGRAM;
00105       break;
00106 
00107     case KExtendedSocket::rawSocket:
00108       /* raw socket requested. I wouldn't do this if I were you... */
00109       socktype = SOCK_RAW;
00110       break;
00111 
00112     default:
00113       /* the flags were used in an invalid manner */
00114       return false;
00115     }
00116 
00117   if (flags & KExtendedSocket::knownSocket)
00118     {
00119       familyMask = 0;
00120       if ((flags & KExtendedSocket::unixSocket) == KExtendedSocket::unixSocket)
00121     familyMask |= KResolver::UnixFamily;
00122 
00123       switch ((flags & (KExtendedSocket::ipv6Socket|KExtendedSocket::ipv4Socket)))
00124     {
00125     case KExtendedSocket::ipv4Socket:
00126       familyMask |= KResolver::IPv4Family;
00127       break;
00128     case KExtendedSocket::ipv6Socket:
00129       familyMask |= KResolver::IPv6Family;
00130       break;
00131     case KExtendedSocket::inetSocket:
00132       familyMask |= KResolver::InternetFamily;
00133       break;
00134     }
00135 
00136       // those are all the families we know about
00137     }
00138   else
00139     familyMask = KResolver::KnownFamily;
00140 
00141   /* check other flags */
00142   outflags = (flags & KExtendedSocket::passiveSocket ? KResolver::Passive : 0) |
00143     (flags & KExtendedSocket::canonName ? KResolver::CanonName : 0) |
00144     (flags & KExtendedSocket::noResolve ? KResolver::NoResolve : 0);
00145 
00146   if (getenv("KDE_NO_IPV6"))
00147     familyMask &= ~KResolver::IPv6Family;
00148 
00149   return true;
00150 }
00151 
00152 // "skips" at most len bytes from file descriptor fd
00153 // that is, we will try and read that much data and discard
00154 // it. We will stop when we have read those or when the read
00155 // function returns error
00156 static int skipData(int fd, unsigned len)
00157 {
00158   char buf[1024];
00159   unsigned skipped = 0;
00160   while (len)
00161     {
00162       int count = sizeof(buf);
00163       if ((unsigned)count > len)
00164     count = len;
00165       count = KSocks::self()->read(fd, buf, count);
00166       if (count == -1)
00167     return -1;
00168       else
00169     {
00170       len -= count;
00171       skipped += count;
00172     }
00173     }
00174   return skipped;
00175 }
00176 
00177 /*
00178  * class KExtendedSocket
00179  */
00180 
00181 // default constructor
00182 KExtendedSocket::KExtendedSocket() :
00183   sockfd(-1), d(new KExtendedSocketPrivate)
00184 {
00185 }
00186 
00187 // constructor with hostname
00188 KExtendedSocket::KExtendedSocket(const QString& host, int port, int flags) :
00189   sockfd(-1), d(new KExtendedSocketPrivate)
00190 {
00191   setAddress(host, port);
00192   setSocketFlags(flags);
00193 }
00194 
00195 // same
00196 KExtendedSocket::KExtendedSocket(const QString& host, const QString& service, int flags) :
00197   sockfd(-1), d(new KExtendedSocketPrivate)
00198 {
00199   setAddress(host, service);
00200   setSocketFlags(flags);
00201 }
00202 
00203 // destroy the class
00204 KExtendedSocket::~KExtendedSocket()
00205 {
00206   closeNow();
00207 
00208   if (d->local != NULL)
00209     delete d->local;
00210   if (d->peer != NULL)
00211     delete d->peer;
00212 
00213   if (d->qsnIn != NULL)
00214     delete d->qsnIn;
00215   if (d->qsnOut != NULL)
00216     delete d->qsnOut;
00217 
00218   delete d;
00219 }
00220 
00221 void KExtendedSocket::reset()
00222 {
00223   closeNow();
00224   release();
00225   d->current = 0;
00226   d->status = nothing;
00227   d->syserror = 0;
00228 }
00229 
00230 int KExtendedSocket::socketStatus() const
00231 {
00232   return d->status;
00233 }
00234 
00235 void KExtendedSocket::setSocketStatus(int newstatus)
00236 {
00237   d->status = newstatus;
00238 }
00239 
00240 void KExtendedSocket::setError(int errorcode, int syserror)
00241 {
00242   setStatus(errorcode);
00243   d->syserror = syserror;
00244 }
00245 
00246 int KExtendedSocket::systemError() const
00247 {
00248   return d->syserror;
00249 }
00250 
00251 /*
00252  * Sets socket flags
00253  * This is only allowed if we are in nothing state
00254  */
00255 int KExtendedSocket::setSocketFlags(int flags)
00256 {
00257   if (d->status > nothing)
00258     return -1;          // error!
00259 
00260   return d->flags = flags;
00261 }
00262 
00263 int KExtendedSocket::socketFlags() const
00264 {
00265   return d->flags;
00266 }
00267 
00268 /*
00269  * Sets socket target hostname
00270  * This is only allowed if we are in nothing state
00271  */
00272 bool KExtendedSocket::setHost(const QString& host)
00273 {
00274   if (d->status > nothing)
00275     return false;       // error!
00276 
00277   d->resRemote.setNodeName(host);
00278   return true;
00279 }
00280 
00281 /*
00282  * returns the hostname
00283  */
00284 QString KExtendedSocket::host() const
00285 {
00286   return d->resRemote.nodeName();
00287 }
00288 
00289 /*
00290  * Sets the socket target port/service
00291  * Same thing: only state 'nothing'
00292  */
00293 bool KExtendedSocket::setPort(int port)
00294 {
00295   return setPort(QString::number(port));
00296 }
00297 
00298 bool KExtendedSocket::setPort(const QString& service)
00299 {
00300   if (d->status > nothing)
00301     return false;       // error
00302 
00303   d->resRemote.setServiceName(service);
00304   return true;
00305 }
00306 
00307 /*
00308  * returns the service port number
00309  */
00310 QString KExtendedSocket::port() const
00311 {
00312   return d->resRemote.serviceName();
00313 }
00314 
00315 /*
00316  * sets the address
00317  */
00318 bool KExtendedSocket::setAddress(const QString& host, int port)
00319 {
00320   return setHost(host) && setPort(port);
00321 }
00322 
00323 /*
00324  * the same
00325  */
00326 bool KExtendedSocket::setAddress(const QString& host, const QString& serv)
00327 {
00328   return setHost(host) && setPort(serv);
00329 }
00330 
00331 /*
00332  * Sets the bind hostname
00333  * This is only valid in the 'nothing' state and if this is not a
00334  * passiveSocket socket
00335  */
00336 bool KExtendedSocket::setBindHost(const QString& host)
00337 {
00338   if (d->status > nothing || d->flags & passiveSocket)
00339     return false;       // error
00340 
00341   d->resLocal.setServiceName(host);
00342   return true;
00343 }
00344 
00345 /*
00346  * Unsets the bind hostname
00347  * same thing
00348  */
00349 bool KExtendedSocket::unsetBindHost()
00350 {
00351   return setBindHost(QString::null);
00352 }
00353 
00354 /*
00355  * returns the binding host
00356  */
00357 QString KExtendedSocket::bindHost() const
00358 {
00359   return d->resLocal.serviceName();
00360 }
00361 
00362 /*
00363  * Sets the bind port
00364  * Same condition as setBindHost
00365  */
00366 bool KExtendedSocket::setBindPort(int port)
00367 {
00368   return setBindPort(QString::number(port));
00369 }
00370 
00371 bool KExtendedSocket::setBindPort(const QString& service)
00372 {
00373   if (d->status > nothing || d->flags & passiveSocket)
00374     return false;       // error
00375 
00376   d->resLocal.setServiceName(service);
00377   return true;
00378 }
00379 
00380 /*
00381  * unsets the bind port
00382  */
00383 bool KExtendedSocket::unsetBindPort()
00384 {
00385   return setBindPort(QString::null);
00386 }
00387 
00388 /*
00389  * returns the binding port
00390  */
00391 QString KExtendedSocket::bindPort() const
00392 {
00393   return d->resLocal.serviceName();
00394 }
00395 
00396 /*
00397  * sets the binding address
00398  */
00399 bool KExtendedSocket::setBindAddress(const QString& host, int port)
00400 {
00401   return setBindHost(host) && setBindPort(port);
00402 }
00403 
00404 /*
00405  * same
00406  */
00407 bool KExtendedSocket::setBindAddress(const QString& host, const QString& service)
00408 {
00409   return setBindHost(host) && setBindPort(service);
00410 }
00411 
00412 /*
00413  * unsets binding address
00414  */
00415 bool KExtendedSocket::unsetBindAddress()
00416 {
00417   return unsetBindHost() && unsetBindPort();
00418 }
00419 
00420 /*
00421  * sets the timeout for the connection
00422  */
00423 bool KExtendedSocket::setTimeout(int secs, int usecs)
00424 {
00425   if (d->status >= connected)   // closed?
00426     return false;
00427 
00428   d->timeout.tv_sec = secs;
00429   d->timeout.tv_usec = usecs;
00430   return true;
00431 }
00432 
00433 /*
00434  * returns the timeout
00435  */
00436 timeval KExtendedSocket::timeout() const
00437 {
00438   return d->timeout;
00439 }
00440 
00441 /*
00442  * Sets the blocking mode on this socket
00443  */
00444 bool KExtendedSocket::setBlockingMode(bool enable)
00445 {
00446   cleanError();
00447   if (d->status < created)
00448     return false;
00449 
00450   if (sockfd == -1)
00451     return false;       // error!
00452 
00453   int fdflags = fcntl(sockfd, F_GETFL, 0);
00454   if (fdflags == -1)
00455     return false;       // error!
00456 
00457   if (!enable)
00458     fdflags |= O_NONBLOCK;
00459   else
00460     fdflags &= ~O_NONBLOCK;
00461 
00462   if (fcntl(sockfd, F_SETFL, fdflags) == -1)
00463     {
00464       setError(IO_UnspecifiedError, errno);
00465       return false;
00466     }
00467   return true;
00468 }
00469 
00470 /*
00471  * Returns the blocking mode on the socket
00472  */
00473 bool KExtendedSocket::blockingMode()
00474 {
00475   cleanError();
00476   if (d->status < created)
00477     return false;       // sockets not created are in blocking mode
00478 
00479   if (sockfd == -1)
00480     return false;       // error
00481 
00482   int fdflags = fcntl(sockfd, F_GETFL, 0);
00483   if (fdflags == -1)
00484     {
00485       setError(IO_UnspecifiedError, errno);
00486       return false;
00487     }
00488   return (fdflags & O_NONBLOCK) == 0; // non-blocking == false
00489 }
00490 
00491 /*
00492  * Sets the reusability flag for this socket in the OS
00493  */
00494 bool KExtendedSocket::setAddressReusable(bool enable)
00495 {
00496   cleanError();
00497   d->addressReusable = enable;
00498   if (d->status < created)
00499     return true;
00500 
00501   if (sockfd == -1)
00502     return true;
00503 
00504   if (!setAddressReusable(sockfd, enable))
00505     {
00506       setError(IO_UnspecifiedError, errno);
00507       return false;
00508     }
00509   return true;
00510 }
00511 
00512 bool KExtendedSocket::setAddressReusable(int fd, bool enable)
00513 {
00514   if (fd == -1)
00515     return false;
00516 
00517   int on = enable;      // just to be on the safe side
00518 
00519   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
00520     return false;
00521   return true;
00522 }
00523 
00524 /*
00525  * Retrieves the reusability flag for this socket
00526  */
00527 bool KExtendedSocket::addressReusable()
00528 {
00529   cleanError();
00530   if (d->status < created)
00531     return d->addressReusable;
00532 
00533   if (sockfd == -1)
00534     return d->addressReusable;
00535 
00536   int on;
00537   socklen_t onsiz = sizeof(on);
00538   if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, &onsiz) == -1)
00539     {
00540       setError(IO_UnspecifiedError, errno);
00541       return false;
00542     }
00543 
00544   return on != 0;
00545 }
00546 
00547 /*
00548  * Set the IPV6_V6ONLY flag
00549  */
00550 bool KExtendedSocket::setIPv6Only(bool enable)
00551 {
00552 #ifdef IPV6_V6ONLY
00553   cleanError();
00554 
00555   d->ipv6only = enable;
00556   if (sockfd == -1)
00557     return true;        // can't set on a non-existing socket
00558 
00559   int on = enable;
00560 
00561   if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
00562          (char *)&on, sizeof(on)) == -1)
00563     {
00564       setError(IO_UnspecifiedError, errno);
00565       return false;
00566     }
00567   else
00568     return true;
00569 
00570 #else
00571   // we don't have the IPV6_V6ONLY constant in this system
00572   d->ipv6only = enable;
00573 
00574   setError(IO_UnspecifiedError, ENOSYS);
00575   return false;         // can't set if we don't know about this flag
00576 #endif
00577 }
00578 
00579 /*
00580  * retrieve the IPV6_V6ONLY flag
00581  */
00582 bool KExtendedSocket::isIPv6Only()
00583 {
00584 #ifdef IPV6_V6ONLY
00585   cleanError();
00586 
00587   if (d->status < created || sockfd == -1)
00588     return d->ipv6only;
00589 
00590   int on;
00591   socklen_t onsiz = sizeof(on);
00592   if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
00593          (char *)&on, &onsiz) == -1)
00594     {
00595       setError(IO_UnspecifiedError, errno);
00596       return false;
00597     }
00598 
00599   return d->ipv6only = on;
00600 
00601 #else
00602   // we don't have the constant
00603   setError(IO_UnspecifiedError, ENOSYS);
00604   return false;
00605 #endif
00606 }
00607 
00608 /*
00609  * Sets the buffer sizes in this socket
00610  * Also, we create or delete the socket notifiers
00611  */
00612 bool KExtendedSocket::setBufferSize(int rsize, int wsize)
00613 {
00614   cleanError();
00615   if (d->status < created)
00616     return false;
00617 
00618   if (sockfd == -1)
00619     return false;
00620 
00621   if (d->flags & passiveSocket)
00622     return false;       // no I/O on passive sockets
00623 
00624   if (rsize < -2)
00625     return false;
00626 
00627   if (wsize < -2)
00628     return false;
00629 
00630   // LOCK BUFFER MUTEX
00631 
00632   // The input socket notifier is always enabled
00633   // That happens because we want to be notified of when the socket gets
00634   // closed
00635   if (d->qsnIn == NULL)
00636     {
00637       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
00638       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
00639       d->qsnIn->setEnabled(true);
00640     }
00641 
00642   if (rsize == 0 && d->flags & inputBufferedSocket)
00643     {
00644       // user wants to disable input buffering
00645       d->flags &= ~inputBufferedSocket;
00646 
00647       consumeReadBuffer(readBufferSize(), NULL, true);
00648       d->inMaxSize = 0;
00649     }
00650   else if (rsize != -2)
00651     {
00652       // enabling input buffering
00653       if (rsize)
00654     d->flags |= inputBufferedSocket;
00655       d->inMaxSize = rsize;
00656 
00657       if (rsize > 0 && (unsigned)rsize < readBufferSize())
00658     // input buffer has more data than the new size; discard
00659     consumeReadBuffer(readBufferSize() - rsize, NULL, true);
00660 
00661     }
00662 
00663   if (wsize == 0 && d->flags & outputBufferedSocket)
00664     {
00665       // disabling output buffering
00666       d->flags &= ~outputBufferedSocket;
00667       if (d->qsnOut && !d->emitWrite)
00668     d->qsnOut->setEnabled(false);
00669       consumeWriteBuffer(writeBufferSize());
00670       d->outMaxSize = 0;
00671     }
00672   else if (wsize != -2)
00673     {
00674       // enabling input buffering
00675       if (wsize)
00676     d->flags |= outputBufferedSocket;
00677       d->outMaxSize = wsize;
00678 
00679       if (wsize > 0 && (unsigned)wsize < writeBufferSize())
00680     // output buffer is bigger than it is to become; shrink
00681     consumeWriteBuffer(writeBufferSize() - wsize);
00682 
00683       if (d->qsnOut == NULL)
00684     {
00685       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
00686       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
00687       // if the class is being created now, there's nothing to write yet
00688       // so socketActivityWrite() will get called once and disable
00689       // the notifier
00690     }
00691     }
00692 
00693   // UNLOCK BUFFER MUTEX
00694 
00695   setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw));
00696 
00697   // check we didn't turn something off we shouldn't
00698   if (d->emitWrite && d->qsnOut == NULL)
00699     {
00700       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
00701       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
00702     }
00703 
00704   return true;
00705 }
00706 
00707 /*
00708  * Finds the local address for this socket
00709  * if we have done this already, we return it. Otherwise, we'll have
00710  * to find the socket name
00711  */
00712 const ::KSocketAddress *KExtendedSocket::localAddress()
00713 {
00714   if (d->local != NULL)
00715     return d->local;
00716   if (d->status < bound)
00717     return NULL;
00718 
00719   return d->local = localAddress(sockfd);
00720 }
00721 
00722 /*
00723  * Same thing, but for peer address. Which means this does not work on
00724  * passiveSocket and that we require to be connected already. Also note that
00725  * the behavior on connectionless sockets is not defined here.
00726  */
00727 const ::KSocketAddress* KExtendedSocket::peerAddress()
00728 {
00729   if (d->peer != NULL)
00730     return d->peer;
00731   if (d->flags & passiveSocket || d->status < connected)
00732     return NULL;
00733 
00734   return d->peer = peerAddress(sockfd);
00735 }
00736 
00737 /*
00738  * Perform the lookup on the addresses given
00739  */
00740 int KExtendedSocket::lookup()
00741 {
00742   if (startAsyncLookup() != 0)
00743     return -1;
00744 
00745   if (!d->resRemote.wait() || !d->resLocal.wait())
00746     {
00747       d->status = nothing;
00748       return -1;
00749     }
00750 
00751   d->status = lookupDone;
00752   return 0;
00753 }
00754 
00755 /*
00756  * Performs an asynchronous lookup on the given address(es)
00757  */
00758 int KExtendedSocket::startAsyncLookup()
00759 {
00760   cleanError();
00761   if (d->status > lookupInProgress)
00762     return -1;
00763   if (d->status == lookupInProgress)
00764     // already in progress
00765     return 0;
00766 
00767   /* check socket type flags */
00768   int socktype, familyMask, flags;
00769   if (!process_flags(d->flags, socktype, familyMask, flags))
00770     return -2;
00771 
00772   // perform the global lookup before
00773   if (!d->resRemote.isRunning())
00774     {
00775       d->resRemote.setFlags(flags);
00776       d->resRemote.setFamily(familyMask);
00777       d->resRemote.setSocketType(socktype);
00778       QObject::connect(&d->resRemote, SIGNAL(finished(KResolverResults)), 
00779                this, SLOT(dnsResultsReady()));
00780 
00781       if (!d->resRemote.start())
00782     {
00783       setError(IO_LookupError, d->resRemote.error());
00784       return d->resRemote.error();
00785     }
00786     }
00787 
00788   if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning())
00789     {
00790       /* keep flags, but make this passive */
00791       flags |= KResolver::Passive;
00792       d->resLocal.setFlags(flags);
00793       d->resLocal.setFamily(familyMask);
00794       d->resLocal.setSocketType(socktype);
00795       QObject::connect(&d->resLocal, SIGNAL(finished(KResolverResults)), 
00796                this, SLOT(dnsResultsReady()));
00797 
00798       if (!d->resLocal.start())
00799     {
00800       setError(IO_LookupError, d->resLocal.error());
00801       return d->resLocal.error();
00802     }
00803     }
00804 
00805   // if we are here, there were no errors
00806   if (d->resRemote.isRunning() || d->resLocal.isRunning())
00807     d->status = lookupInProgress; // only if there actually is a running lookup
00808   else
00809     {
00810       d->status = lookupDone;
00811       emit lookupFinished(d->resRemote.results().count() + 
00812               d->resLocal.results().count());
00813     }
00814   return 0;
00815 }
00816 
00817 void KExtendedSocket::cancelAsyncLookup()
00818 {
00819   cleanError();
00820   if (d->status != lookupInProgress)
00821     return;         // what's to cancel?
00822 
00823   d->status = nothing;
00824   d->resLocal.cancel(false);
00825   d->resRemote.cancel(false);
00826 }
00827 
00828 int KExtendedSocket::listen(int N)
00829 {
00830   cleanError();
00831   if ((d->flags & passiveSocket) == 0 || d->status >= listening)
00832     return -2;
00833   if (d->status < lookupDone)
00834     if (lookup() != 0)
00835       return -2;        // error!
00836   if (d->resRemote.error())
00837     return -2;
00838   
00839   // doing the loop:
00840   KResolverResults::const_iterator it;
00841   KResolverResults res = d->resRemote.results();
00842   for (it = res.begin(); it != res.end(); ++it)
00843     {
00844       //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl;
00845       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
00846       if (sockfd == -1)
00847     {
00848       // socket failed creating
00849       //kdDebug(170) << "Failed to create: " << perror << endl;
00850       continue;
00851     }
00852     
00853       fcntl(sockfd, F_SETFD, FD_CLOEXEC);
00854 
00855       if (d->addressReusable)
00856     setAddressReusable(sockfd, true);
00857       setIPv6Only(d->ipv6only);
00858       cleanError();
00859       if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1)
00860     {
00861       //kdDebug(170) << "Failed to bind: " << perror << endl;
00862       ::close(sockfd);
00863       sockfd = -1;
00864       continue;
00865     }
00866 
00867       // ok, socket has bound
00868       // kdDebug(170) << "Socket bound: " << sockfd << endl;
00869 
00870       d->status = bound;
00871       break;
00872     }
00873 
00874   if (sockfd == -1)
00875     {
00876       setError(IO_ListenError, errno);
00877       //kdDebug(170) << "Listen error - sockfd is -1 " << endl;
00878       return -1;
00879     }
00880 
00881   d->status = bound;
00882   setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00883 
00884   int retval = KSocks::self()->listen(sockfd, N);
00885   if (retval == -1)
00886     setError(IO_ListenError, errno);
00887   else
00888     {
00889       d->status = listening;
00890       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
00891       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
00892     }
00893   return retval == -1 ? -1 : 0;
00894 }
00895 
00896 int KExtendedSocket::accept(KExtendedSocket *&sock)
00897 {
00898   cleanError();
00899   sock = NULL;
00900   if ((d->flags & passiveSocket) == 0 || d->status >= accepting)
00901     return -2;
00902   if (d->status < listening)
00903     if (listen() < 0)
00904       return -2;        // error!
00905 
00906   // let's see
00907   // if we have a timeout in place, we have to place this socket in non-blocking
00908   // mode
00909   bool block = blockingMode();
00910   struct sockaddr sa;
00911   ksocklen_t len = sizeof(sa);
00912   sock = NULL;
00913 
00914   if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0)
00915     {
00916       fd_set set;
00917 
00918       setBlockingMode(false);   // turn on non-blocking
00919       FD_ZERO(&set);
00920       FD_SET(sockfd, &set);
00921 
00922       //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n",
00923       //         sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
00924       // check if there is anything to accept now
00925       int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout);
00926       if (retval == -1)
00927     {
00928       setError(IO_UnspecifiedError, errno);
00929       return -1;        // system error
00930     }
00931       else if (retval == 0 || !FD_ISSET(sockfd, &set))
00932     {
00933       setError(IO_TimeOutError, 0);
00934       return -3;        // timeout
00935     }
00936     }
00937 
00938   // it's common stuff here
00939   int newfd = KSocks::self()->accept(sockfd, &sa, &len);
00940 
00941   if (newfd == -1)
00942     {
00943       setError(IO_AcceptError, errno);
00944       kdWarning(170) << "Error accepting on socket " << sockfd << ":"
00945              << perror << endl;
00946       return -1;
00947     }
00948 
00949   fcntl(newfd, F_SETFD, FD_CLOEXEC);
00950 
00951   //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd);
00952 
00953   setBlockingMode(block);   // restore blocking mode
00954 
00955   sock = new KExtendedSocket;
00956   sock->d->status = connected;
00957   sock->sockfd = newfd;
00958   sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00959   sock->setBufferSize(0, 0);    // always unbuffered here. User can change that later
00960 
00961   return 0;
00962 }
00963 
00964 /*
00965  * tries to connect
00966  *
00967  * FIXME!
00968  * This function is critical path. It has to be cleaned up and made faster
00969  */
00970 int KExtendedSocket::connect()
00971 {
00972   cleanError();
00973   if (d->flags & passiveSocket || d->status >= connected)
00974     return -2;
00975   if (d->status < lookupDone)
00976     if (lookup() != 0)
00977       return -2;
00978 
00979   timeval end, now;
00980   // Ok, things are a little tricky here
00981   // Let me explain
00982   // getaddrinfo() will return several different families of sockets
00983   // When we have to bind before we connect, we have to make sure we're binding
00984   // and connecting to the same family, or things won't work
00985 
00986   bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
00987   if (doingtimeout)
00988     {
00989       gettimeofday(&end, NULL);
00990       end.tv_usec += d->timeout.tv_usec;
00991       end.tv_sec += d->timeout.tv_sec;
00992       if (end.tv_usec > 1000*1000)
00993     {
00994       end.tv_usec -= 1000*1000;
00995       end.tv_sec++;
00996     }
00997 //  kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n",
00998 //           d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec);
00999     }
01000 
01001   KResolverResults remote = d->resRemote.results(),
01002     local = d->resLocal.results();
01003   KResolverResults::const_iterator it, it2;
01004   //kdDebug(170) << "Starting connect to " << host() << '|' << port() 
01005   //             << ": have " << local.count() << " local entries and "
01006   //             << remote.count() << " remote" << endl;
01007   for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
01008     {
01009       //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl;
01010       if (it2 != local.end())
01011     {
01012 //    //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl;
01013       if ((*it).family() != (*it2).family())
01014         // differing families, scan local for a matching family
01015         for (it2 = local.begin(); it2 != local.end(); ++it2)
01016           if ((*it).family() == (*it2).family())
01017         break;
01018 
01019       if ((*it).family() != (*it2).family())
01020         {
01021           // no matching families for this
01022           //kdDebug(170) << "No matching family for bind socket\n";
01023           it2 = local.begin();
01024           continue;
01025         }
01026 
01027       //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl;
01028       errno = 0;
01029       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01030       setError(IO_ConnectError, errno);
01031       if (sockfd == -1)
01032         continue;       // cannot create this socket
01033           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01034       if (d->addressReusable)
01035         setAddressReusable(sockfd, true);
01036       setIPv6Only(d->ipv6only);
01037       cleanError();
01038       if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
01039         {
01040           //kdDebug(170) << "Bind failed: " << perror << endl;
01041           ::close(sockfd);
01042           sockfd = -1;
01043           continue;
01044         }
01045     }
01046       else
01047     {
01048       // no need to bind, just create
01049       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01050       if (sockfd == -1)
01051         {
01052           setError(IO_ConnectError, errno);
01053           continue;
01054         }
01055           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01056       if (d->addressReusable)
01057         setAddressReusable(sockfd, true);
01058       setIPv6Only(d->ipv6only);
01059       cleanError();
01060     }
01061 
01062 //      kdDebug(170) << "Socket " << sockfd << " created" << endl;
01063       d->status = created;
01064 
01065       // check if we have to do timeout
01066       if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
01067     {
01068       fd_set rd, wr;
01069 
01070       setBlockingMode(false);
01071 
01072       // now try and connect
01073       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01074         {
01075           // this could be EWOULDBLOCK
01076           if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01077         {
01078           //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl;
01079           setError(IO_ConnectError, errno);
01080           ::close(sockfd);
01081           sockfd = -1;
01082           continue; // nope, another error
01083         }
01084 
01085           FD_ZERO(&rd);
01086           FD_ZERO(&wr);
01087           FD_SET(sockfd, &rd);
01088           FD_SET(sockfd, &wr);
01089 
01090           int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
01091           if (retval == -1)
01092         {
01093           setError(IO_FatalError, errno);
01094           continue; // system error
01095         }
01096           else if (retval == 0)
01097         {
01098           ::close(sockfd);
01099           sockfd = -1;
01100 //        kdDebug(170) << "Time out while trying to connect to " <<
01101 //          (*it).address().toString() << endl;
01102           d->status = lookupDone;
01103           setError(IO_TimeOutError, 0);
01104           return -3;    // time out
01105         }
01106 
01107           // adjust remaining time
01108           gettimeofday(&now, NULL);
01109           d->timeout.tv_sec = end.tv_sec - now.tv_sec;
01110           d->timeout.tv_usec = end.tv_usec - now.tv_usec;
01111           if (d->timeout.tv_usec < 0)
01112         {
01113           d->timeout.tv_usec += 1000*1000;
01114           d->timeout.tv_sec--;
01115         }
01116 //        kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n",
01117 //               sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
01118 
01119           // this means that an event occurred in the socket
01120           int errcode;
01121           socklen_t len = sizeof(errcode);
01122           retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
01123                   &len);
01124           if (retval == -1 || errcode != 0)
01125         {
01126           // socket did not connect
01127           //kdDebug(170) << "Socket " << sockfd << " did not connect: "
01128           //        << strerror(errcode) << endl;
01129           ::close(sockfd);
01130           sockfd = -1;
01131 
01132           // this is HIGHLY UNLIKELY
01133           if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
01134             {
01135               d->status = lookupDone;
01136               setError(IO_TimeOutError, 0);
01137               return -3; // time out
01138             }
01139 
01140           setError(IO_ConnectError, errcode);
01141           continue;
01142         }
01143         }
01144 
01145       // getting here means it connected
01146       // setBufferSize() takes care of creating the socket notifiers
01147       setBlockingMode(true);
01148       d->status = connected;
01149       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01150       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01151             d->flags & outputBufferedSocket ? -1 : 0);
01152       emit connectionSuccess();
01153 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01154       return 0;
01155     }
01156       else
01157     {
01158       // without timeouts
01159       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01160         {
01161           //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString() 
01162           //       << " did not connect: " << perror << endl;
01163           setError(IO_ConnectError, errno);
01164           ::close(sockfd);
01165           sockfd = -1;
01166           continue;
01167         }
01168 
01169       d->status = connected;
01170       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01171       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01172             d->flags & outputBufferedSocket ? -1 : 0);
01173       emit connectionSuccess();
01174 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01175       return 0;     // it connected
01176     }
01177     }
01178 
01179   // getting here means no socket connected or stuff like that
01180   emit connectionFailed(d->syserror);
01181   //kdDebug(170) << "Failed to connect\n";
01182   return -1;
01183 }
01184 
01185 int KExtendedSocket::startAsyncConnect()
01186 {
01187   cleanError();
01188   // check status
01189   if (d->status >= connected || d->flags & passiveSocket)
01190     return -2;
01191 
01192   if (d->status == connecting)
01193     // already on async connect
01194     return 0;
01195 
01196   // check if we have to do lookup
01197   // if we do, then we'll use asynchronous lookup and use
01198   // signal lookupFinished to do connection
01199   if (d->status < lookupDone)
01200     {
01201       QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01202       if (d->status < lookupInProgress)
01203     return startAsyncLookup();
01204       else
01205     return 0;       // we still have to wait
01206     }
01207 
01208   // here we have d->status >= lookupDone and <= connecting
01209   // we can do our connection
01210   d->status = connecting;
01211   QGuardedPtr<QObject> p = this;
01212   connectionEvent();
01213   if (!p) 
01214     return -1; // We have been deleted.
01215   if (d->status < connecting)
01216     return -1;
01217   return 0;
01218 }
01219 
01220 void KExtendedSocket::cancelAsyncConnect()
01221 {
01222   if (d->status != connecting)
01223     return;
01224 
01225   if (sockfd != -1)
01226     {
01227       // we have a waiting connection
01228       if (d->qsnIn)
01229     delete d->qsnIn;
01230       if (d->qsnOut)
01231     delete d->qsnOut;
01232       d->qsnIn = d->qsnOut = NULL;
01233 
01234       ::close(sockfd);
01235       sockfd = -1;
01236     }
01237   d->status = lookupDone;
01238 }
01239 
01240 bool KExtendedSocket::open(int mode)
01241 {
01242   if (mode != IO_Raw | IO_ReadWrite)
01243     return false;       // invalid open mode
01244 
01245   if (d->flags & passiveSocket)
01246     return listen() == 0;
01247   else if (d->status < connecting)
01248     return connect() == 0;
01249   else
01250     return false;
01251 }
01252 
01253 void KExtendedSocket::close()
01254 {
01255   if (sockfd == -1 || d->status >= closing)
01256     return;         // nothing to close
01257 
01258   // LOCK BUFFER MUTEX
01259   if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
01260     {
01261       // write buffer not empty, go into closing state
01262       d->status = closing;
01263       if (d->qsnIn)
01264     delete d->qsnIn;
01265       d->qsnIn = NULL;
01266       // we keep the outgoing socket notifier because we want
01267       // to send data, but not receive
01268     }
01269   else
01270     {
01271       // nope, write buffer is empty
01272       // we can close now
01273       if (d->qsnIn)
01274     delete d->qsnIn;
01275       if (d->qsnOut)
01276     delete d->qsnOut;
01277       d->qsnIn = d->qsnOut = NULL;
01278 
01279       ::close(sockfd);
01280       d->status = done;
01281       emit closed(readBufferSize() != 0 ? availRead : 0);
01282     }
01283   // UNLOCK BUFFER MUTEX
01284 }
01285 
01286 
01287 void KExtendedSocket::closeNow()
01288 {
01289   if (d->status >= done)
01290     return;         // nothing to close
01291 
01292   // close the socket
01293   delete d->qsnIn;
01294   delete d->qsnOut;
01295   d->qsnIn = d->qsnOut = NULL;
01296 
01297   if (d->status > connecting && sockfd != -1)
01298     {
01299       ::close(sockfd);
01300       sockfd = -1;
01301     }
01302   else if (d->status == connecting)
01303     cancelAsyncConnect();
01304   else if (d->status == lookupInProgress)
01305     cancelAsyncLookup();
01306 
01307   d->status = done;
01308 
01309   emit closed(closedNow |
01310           (readBufferSize() != 0 ? availRead : 0) |
01311           (writeBufferSize() != 0 ? dirtyWrite : 0));
01312 }
01313 
01314 void KExtendedSocket::release()
01315 {
01316   // release our hold on the socket
01317   sockfd = -1;
01318   d->status = done;
01319 
01320   d->resRemote.cancel(false);
01321   d->resLocal.cancel(false);
01322 
01323   if (d->local != NULL)
01324     delete d->local;
01325   if (d->peer != NULL)
01326     delete d->peer;
01327 
01328   d->peer = d->local = NULL;
01329 
01330   if (d->qsnIn != NULL)
01331     delete d->qsnIn;
01332   if (d->qsnOut != NULL)
01333     delete d->qsnOut;
01334 
01335   d->qsnIn = d->qsnOut = NULL;
01336 
01337   // now that the socket notificators are done with, we can flush out the buffers
01338   consumeReadBuffer(readBufferSize(), NULL, true);
01339   consumeWriteBuffer(writeBufferSize());
01340 
01341   // don't delete d
01342   // leave that for the destructor
01343 }
01344 
01345 void KExtendedSocket::flush()
01346 {
01347   cleanError();
01348   if (d->status < connected || d->status >= done || d->flags & passiveSocket)
01349     return;
01350 
01351   if (sockfd == -1)
01352     return;
01353 
01354   if ((d->flags & outputBufferedSocket) == 0)
01355     return;         // nothing to do
01356 
01357   // LOCK MUTEX
01358 
01359   unsigned written = 0;
01360   unsigned offset = outBufIndex; // this happens only for the first
01361   while (writeBufferSize() - written > 0)
01362     {
01363       // we have to write each output buffer in outBuf
01364       // but since we can have several very small buffers, we can make things
01365       // better by concatenating a few of them into a big buffer
01366       // question is: how big should that buffer be? 16 kB should be enough
01367 
01368       QByteArray buf(16384);
01369       QByteArray *a = outBuf.first();
01370       unsigned count = 0;
01371 
01372       while (a && count + (a->size() - offset) <= buf.size())
01373     {
01374       memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
01375       count += a->size() - offset;
01376       offset = 0;
01377       a = outBuf.next();
01378     }
01379 
01380       // see if we can still fit more
01381       if (a && count < buf.size())
01382     {
01383       // getting here means this buffer (a) is larger than
01384       // (buf.size() - count) (even for count == 0).
01385       memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
01386       offset += buf.size() - count;
01387       count = buf.size();
01388     }
01389 
01390       // now try to write those bytes
01391       int wrote = KSocks::self()->write(sockfd, buf, count);
01392 
01393       if (wrote == -1)
01394     {
01395       // could be EAGAIN (EWOULDBLOCK)
01396       setError(IO_WriteError, errno);
01397       break;
01398     }
01399       written += wrote;
01400 
01401       if ((unsigned)wrote != count)
01402     break;
01403     }
01404   if (written)
01405     {
01406       consumeWriteBuffer(written);
01407       emit bytesWritten(written);
01408     }
01409 
01410   // UNLOCK MUTEX
01411 }
01412 
01413 
01414 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen)
01415 {
01416   cleanError();
01417   if (d->status < connected || d->flags & passiveSocket)
01418     return -2;
01419 
01420   int retval;
01421 
01422   if ((d->flags & inputBufferedSocket) == 0)
01423     {
01424       // we aren't buffering this socket, so just pass along
01425       // the call to the real read method
01426 
01427       if (sockfd == -1)
01428     return -2;
01429       if (data)
01430     retval = KSocks::self()->read(sockfd, data, maxlen);
01431       else
01432     retval = skipData(sockfd, maxlen);
01433       if (retval == -1)
01434     setError(IO_ReadError, errno);
01435     }
01436   else
01437     {
01438       // this socket is being buffered. So read from the buffer
01439 
01440       // LOCK BUFFER MUTEX
01441 
01442       retval = consumeReadBuffer(maxlen, data);
01443       if (retval == 0)
01444     {
01445       // consumeReadBuffer returns 0 only if the buffer is
01446       // empty
01447       if (sockfd == -1)
01448         return 0;       // buffer is clear now, indicate EOF
01449       setError(IO_ReadError, EWOULDBLOCK);
01450       retval = -1;
01451     }
01452 
01453       // UNLOCK BUFFER MUTEX
01454 
01455     }
01456   return retval;
01457 }
01458 
01459 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len)
01460 {
01461   cleanError();
01462   if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
01463     return -2;
01464   if (sockfd == -1)
01465     return -2;
01466 
01467   if (len == 0)
01468     return 0;           // what's to write?
01469 
01470   int retval;
01471 
01472   if ((d->flags & outputBufferedSocket) == 0)
01473     {
01474       // socket not buffered. Just call write
01475       retval = KSocks::self()->write(sockfd, data, len);
01476       if (retval == -1)
01477     setError(IO_WriteError, errno);
01478       else
01479     emit bytesWritten(retval);
01480     }
01481   else
01482     {
01483       // socket is buffered. Feed the write buffer
01484 
01485       // LOCK BUFFER MUTEX
01486 
01487       register unsigned wsize = writeBufferSize();
01488       if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning
01489     {
01490       // buffer is full!
01491       setError(IO_WriteError, EWOULDBLOCK);
01492       retval = -1;
01493     }
01494       else
01495     {
01496       if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
01497         // we cannot write all data. Write just as much as to fill the buffer
01498         len = d->outMaxSize - wsize;
01499 
01500       // len > 0 here
01501       retval = feedWriteBuffer(len, data);
01502       if (wsize == 0 || d->emitWrite)
01503         // buffer was empty, which means that the notifier is probably disabled
01504         d->qsnOut->setEnabled(true);
01505     }
01506 
01507       // UNLOCK BUFFER MUTEX
01508     }
01509 
01510   return retval;
01511 }
01512 
01513 int KExtendedSocket::peekBlock(char *data, uint maxlen)
01514 {
01515   if (d->status < connected || d->flags & passiveSocket)
01516     return -2;
01517   if (sockfd == -1)
01518     return -2;
01519 
01520   // need to LOCK MUTEX around this call...
01521 
01522   if (d->flags & inputBufferedSocket)
01523     return consumeReadBuffer(maxlen, data, false);
01524 
01525   return 0;
01526 }
01527 
01528 int KExtendedSocket::unreadBlock(const char *, uint)
01529 {
01530   // Always return -1, indicating this is not supported
01531   setError(IO_ReadError, ENOSYS);
01532   return -1;
01533 }
01534 
01535 int KExtendedSocket::bytesAvailable() const
01536 {
01537   if (d->status < connected || d->flags & passiveSocket)
01538     return -2;
01539 
01540   // as of now, we don't do any extra processing
01541   // we only work in input-buffered sockets
01542   if (d->flags & inputBufferedSocket)
01543     return KBufferedIO::bytesAvailable();
01544 
01545   return 0;         // TODO: FIONREAD ioctl
01546 }
01547 
01548 int KExtendedSocket::waitForMore(int msecs)
01549 {
01550   cleanError();
01551   if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
01552     return -2;
01553   if (sockfd == -1)
01554     return -2;
01555 
01556   fd_set rd;
01557   FD_ZERO(&rd);
01558   FD_SET(sockfd, &rd);
01559   timeval tv;
01560   tv.tv_sec = msecs / 1000;
01561   tv.tv_usec = (msecs % 1000) * 1000;
01562 
01563   int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
01564   if (retval == -1)
01565     {
01566       setError(IO_FatalError, errno);
01567       return -1;
01568     }
01569   else if (retval != 0)
01570     socketActivityRead();   // do read processing
01571 
01572   return bytesAvailable();
01573 }
01574 
01575 int KExtendedSocket::getch()
01576 {
01577   unsigned char c;
01578   int retval;
01579   retval = readBlock((char*)&c, sizeof(c));
01580 
01581   if (retval < 0)
01582     return retval;
01583   return c;
01584 }
01585 
01586 int KExtendedSocket::putch(int ch)
01587 {
01588   unsigned char c = (char)ch;
01589   return writeBlock((char*)&c, sizeof(c));
01590 }
01591 
01592 // sets the emission of the readyRead signal
01593 void KExtendedSocket::enableRead(bool enable)
01594 {
01595   // check if we can disable the socket notifier
01596   // saves us a few cycles
01597   // this is so because in buffering mode, we rely on these signals
01598   // being emitted to do our I/O. We couldn't disable them here
01599   if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
01600     d->qsnIn->setEnabled(false);
01601   else if (enable && d->qsnIn)
01602     // we can enable it always
01603     d->qsnIn->setEnabled(true);
01604   d->emitRead = enable;
01605 }
01606 
01607 // sets the emission of the readyWrite signal
01608 void KExtendedSocket::enableWrite(bool enable)
01609 {
01610   // same thing as above
01611   if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
01612     d->qsnOut->setEnabled(false);
01613   else if (enable && d->qsnOut)
01614     // we can enable it always
01615     d->qsnOut->setEnabled(true);
01616   d->emitWrite = enable;
01617 }
01618 
01619 // protected slot
01620 // this is connected to d->qsnIn::activated(int)
01621 void KExtendedSocket::socketActivityRead()
01622 {
01623   if (d->flags & passiveSocket)
01624     {
01625       emit readyAccept();
01626       return;
01627     }
01628   if (d->status == connecting)
01629     {
01630       connectionEvent();
01631       return;
01632     }
01633   if (d->status != connected)
01634     return;
01635 
01636   // do we need to do I/O here?
01637   if (d->flags & inputBufferedSocket)
01638     {
01639       // aye. Do read from the socket and feed our buffer
01640       QByteArray a;
01641       char buf[1024];
01642       int len, totalread = 0;
01643 
01644       // LOCK MUTEX
01645 
01646       unsigned cursize = readBufferSize();
01647 
01648       if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
01649     {
01650       do
01651         {
01652           // check that we can read that many bytes
01653           if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
01654         // no, that would overrun the buffer
01655         // note that this will also make us exit the loop
01656         len = d->inMaxSize - (cursize + totalread);
01657           else
01658         len = sizeof(buf);
01659 
01660           len = KSocks::self()->read(sockfd, buf, len);
01661           if (len > 0)
01662         {
01663           // normal read operation
01664           a.resize(a.size() + len);
01665           memcpy(a.data() + totalread, buf, len);
01666           totalread += len; // totalread == a.size() now
01667         }
01668           else if (len == 0)
01669         {
01670           // EOF condition here
01671           ::close(sockfd);
01672           sockfd = -1;  // we're closed
01673           d->qsnIn->deleteLater();
01674           delete d->qsnOut;
01675           d->qsnIn = d->qsnOut = NULL;
01676           d->status = done;
01677           emit closed(involuntary |
01678                   (readBufferSize() ? availRead : 0) |
01679                   (writeBufferSize() ? dirtyWrite : 0));
01680           return;
01681         }
01682           else
01683         {
01684           // error!
01685           setError(IO_ReadError, errno);
01686           return;
01687         }
01688           // will loop only for normal read operations
01689         }
01690       while (len == sizeof(buf));
01691 
01692       feedReadBuffer(a.size(), a.data());
01693     }
01694 
01695       // UNLOCK MUTEX
01696     }
01697   else
01698     {
01699       // No input buffering, but the notifier fired
01700       // That means that either there is data to be read or that the 
01701       // socket closed.
01702 
01703       // try to read one byte. If we can't, then the socket got closed
01704 
01705       char c;
01706       int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
01707       if (len == 0)
01708     {
01709       // yes, it's an EOF condition
01710       d->qsnIn->setEnabled(false);
01711       ::close(sockfd);
01712       sockfd = -1;
01713       d->status = done;
01714       emit closed(involuntary);
01715       return;
01716     }
01717     }
01718 
01719   if (d->emitRead)
01720     emit readyRead();
01721 }
01722 
01723 void KExtendedSocket::socketActivityWrite()
01724 {
01725   if (d->flags & passiveSocket)
01726     return;
01727   if (d->status == connecting)
01728     {
01729       connectionEvent();
01730       return;
01731     }
01732   if (d->status != connected && d->status != closing)
01733     return;
01734 
01735   flush();
01736 
01737   bool empty = writeBufferSize() == 0;
01738 
01739   if (d->emitWrite && empty)
01740     emit readyWrite();
01741   else if (!d->emitWrite)
01742     {
01743       // check if we can disable the notifier
01744       d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send
01745     }
01746   if (d->status == closing && empty)
01747     {
01748       // done sending the missing data!
01749       d->status = done;
01750 
01751       delete d->qsnOut;
01752       ::close(sockfd);
01753 
01754       d->qsnOut = NULL;
01755       sockfd = -1;
01756       emit closed(delayed | (readBufferSize() ? availRead : 0));
01757     }
01758 }
01759 
01760 // this function is called whenever we have a "connection event"
01761 // that is, whenever our asynchronously connecting socket throws
01762 // an event
01763 void KExtendedSocket::connectionEvent()
01764 {
01765   if (d->status != connecting)
01766     return;         // move along. There's nothing to see here
01767 
01768   KResolverResults remote = d->resRemote.results();
01769   if (remote.count() == 0)
01770     {
01771       // We have a problem! Abort?
01772       kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
01773       return;
01774     }
01775 
01776   int errcode = 0;
01777 
01778   if (sockfd != -1)
01779     {
01780       // our socket has activity
01781       // find out what it was
01782       int retval;
01783       socklen_t len = sizeof(errcode);
01784       retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
01785 
01786       if (retval == -1 || errcode != 0)
01787     {
01788       // socket activity and there was error?
01789       // that means the socket probably did not connect
01790       if (d->qsnIn)
01791         delete d->qsnIn;
01792       if (d->qsnOut)
01793         delete d->qsnOut;
01794       ::close(sockfd);
01795 
01796       sockfd = -1;
01797       d->qsnIn = d->qsnOut = NULL;
01798       setError(IO_ConnectError, errcode);
01799     }
01800       else
01801     {
01802       // hmm, socket activity and there was no error?
01803       // that means it connected
01804       // YAY!
01805       cleanError();
01806       d->status = connected;
01807       setBlockingMode(true);
01808       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01809       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01810             d->flags & outputBufferedSocket ? -1 : 0);
01811       emit connectionSuccess();
01812       return;
01813     }
01814     }
01815 
01816   // ok, we have to try something here
01817   // and sockfd == -1
01818   KResolverResults local = d->resLocal.results();
01819   unsigned localidx = 0;
01820   for ( ; d->current < remote.count(); d->current++)
01821     {
01822       // same code as in connect()
01823       if (local.count() != 0)
01824     {
01825       // scan bindres for a local resuls family
01826       for (localidx = 0; localidx < local.count(); localidx++)
01827         if (remote[d->current].family() == local[localidx].family())
01828           break;
01829 
01830       if (remote[d->current].family() != local[localidx].family())
01831         {
01832           // no matching families for this
01833           continue;
01834         }
01835 
01836       errno = 0;
01837       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01838                 remote[d->current].protocol());
01839       setError(IO_ConnectError, errno);
01840       errcode = errno;
01841       if (sockfd == -1)
01842         continue;       // cannot create this socket
01843           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01844       if (d->addressReusable)
01845         setAddressReusable(sockfd, true);
01846       setIPv6Only(d->ipv6only);
01847       cleanError();
01848       if (KSocks::self()->bind(sockfd, local[localidx].address(), 
01849                    local[localidx].length()) == -1)
01850         {
01851           ::close(sockfd);
01852           sockfd = -1;
01853           continue;
01854         }
01855     }
01856       else
01857     {
01858       // no need to bind, just create
01859       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01860                 remote[d->current].protocol());
01861       if (sockfd == -1)
01862         {
01863           setError(IO_ConnectError, errno);
01864           errcode = errno;
01865           continue;
01866         }
01867           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01868       if (d->addressReusable)
01869         setAddressReusable(sockfd, true);
01870       setIPv6Only(d->ipv6only);
01871       cleanError();
01872     }
01873 
01874       if (KSocks::self()->hasWorkingAsyncConnect())
01875         setBlockingMode(false);
01876       if (KSocks::self()->connect(sockfd, remote[d->current].address(), 
01877                   remote[d->current].length()) == -1)
01878     {
01879       if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01880         {
01881           setError(IO_ConnectError, errno);
01882           ::close(sockfd);
01883           sockfd = -1;
01884           errcode = errno;
01885           continue;
01886         }
01887 
01888       // error here is either EWOULDBLOCK or EINPROGRESS
01889       // so, it is a good condition
01890       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
01891       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
01892       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
01893       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
01894 
01895       // ok, let the Qt event loop do the selecting for us
01896       return;
01897     }
01898 
01899       // eh, what?
01900       // the non-blocking socket returned valid connection?
01901       // already?
01902       // I suppose that could happen...
01903       cleanError();
01904       d->status = connected;
01905       setBlockingMode(true);
01906       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01907       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01908             d->flags & outputBufferedSocket ? -1 : 0);
01909       emit connectionSuccess();
01910       return;
01911     }
01912 
01913   // if we got here, it means that there are no more options to connect
01914   d->status = lookupDone;   // go back
01915   emit connectionFailed(errcode);
01916 }
01917 
01918 void KExtendedSocket::dnsResultsReady()
01919 {
01920   // check that this function was called in a valid state
01921   if (d->status != lookupInProgress)
01922     return;
01923 
01924   // valid state. Are results fully ready?
01925   if (d->resRemote.isRunning() || d->resLocal.isRunning())
01926     // no, still waiting for answer in one of the lookups
01927     return;
01928 
01929   // ok, we have all results
01930   // count how many results we have
01931   int n = d->resRemote.results().count() + d->resLocal.results().count();
01932 
01933   if (n)
01934     {
01935       d->status = lookupDone;
01936       cleanError();
01937     }
01938   else
01939     {
01940       d->status = nothing;
01941       setError(IO_LookupError, KResolver::NoName);
01942     }
01943 
01944   emit lookupFinished(n);
01945 
01946   return;
01947 }
01948 
01949 void KExtendedSocket::startAsyncConnectSlot()
01950 {
01951   QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01952 
01953   if (d->status == lookupDone)
01954     startAsyncConnect();
01955 }
01956 
01957 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host,
01958                  QString &port, int flags)
01959 {
01960   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01961 
01962   int err;
01963   char h[NI_MAXHOST], s[NI_MAXSERV];
01964 
01965   h[0] = s[0] = '\0';
01966 
01967   err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
01968   host = QString::fromUtf8(h);
01969   port = QString::fromUtf8(s);
01970 
01971   return err;
01972 }
01973 
01974 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port,
01975                  int flags)
01976 {
01977   return resolve(sock->data, sock->datasize, host, port, flags);
01978 }
01979 
01980 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port,
01981                         int userflags, int *error)
01982 {
01983   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01984 
01985   int socktype, familyMask, flags;
01986   unsigned i;
01987   QPtrList<KAddressInfo> l;
01988 
01989   /* check socket type flags */
01990   if (!process_flags(userflags, socktype, familyMask, flags))
01991     return l;
01992 
01993 //  kdDebug(170) << "Performing lookup on " << host << "|" << port << endl;
01994   KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
01995   if (res.error())
01996     {
01997       if (error)
01998     *error = res.error();
01999       return l;
02000     }
02001 
02002   for (i = 0; i < res.count(); i++)
02003     {
02004       KAddressInfo *ai = new KAddressInfo();
02005 
02006       // I should have known that using addrinfo was going to come
02007       // and bite me back some day...
02008       ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
02009       memset(ai->ai, 0, sizeof(addrinfo));
02010 
02011       ai->ai->ai_family = res[i].family();
02012       ai->ai->ai_socktype = res[i].socketType();
02013       ai->ai->ai_protocol = res[i].protocol();
02014       QString canon = res[i].canonicalName();
02015       if (!canon.isEmpty())
02016     {
02017       ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
02018       strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional
02019     }
02020       if ((ai->ai->ai_addrlen = res[i].length()))
02021     {
02022       ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
02023       memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
02024     }
02025       else
02026     {
02027       ai->ai->ai_addr = 0;
02028     }
02029 
02030       ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
02031 
02032       l.append(ai);
02033     }
02034 
02035   if ( error )
02036       *error = 0;               // all is fine!
02037 
02038   return l;
02039 }
02040 
02041 ::KSocketAddress *KExtendedSocket::localAddress(int fd)
02042 {
02043   ::KSocketAddress *local;
02044   struct sockaddr static_sa, *sa = &static_sa;
02045   ksocklen_t len = sizeof(static_sa);
02046 
02047   /* find out the socket length, in advance
02048    * we use a sockaddr allocated on the heap just not to pass down
02049    * a NULL pointer to the first call. Some systems are reported to
02050    * set len to 0 if we pass NULL as the sockaddr */
02051   if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02052     return NULL;        // error!
02053 
02054   /* was it enough? */
02055   if (len > sizeof(static_sa)
02056 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02057       || sa->sa_len > sizeof(static_sa)
02058 #endif
02059       )
02060     {
02061       /* nope, malloc a new socket with the proper size */
02062 
02063 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02064       if (sa->sa_len != len)
02065         len = sa->sa_len;
02066 #endif
02067 
02068       sa = (sockaddr*)malloc(len);
02069       if (sa == NULL)
02070     return NULL;        // out of memory
02071 
02072       if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02073     {
02074       free(sa);
02075       return NULL;
02076     }
02077 
02078       local = ::KSocketAddress::newAddress(sa, len);
02079       free(sa);
02080     }
02081   else
02082     local = ::KSocketAddress::newAddress(sa, len);
02083 
02084   return local;
02085 }
02086 
02087 /* This is exactly the same code as localAddress, except
02088  * we call getpeername here */
02089 ::KSocketAddress *KExtendedSocket::peerAddress(int fd)
02090 {
02091   ::KSocketAddress *peer;
02092   struct sockaddr static_sa, *sa = &static_sa;
02093   ksocklen_t len = sizeof(static_sa);
02094 
02095   /* find out the socket length, in advance
02096    * we use a sockaddr allocated on the heap just not to pass down
02097    * a NULL pointer to the first call. Some systems are reported to
02098    * set len to 0 if we pass NULL as the sockaddr */
02099   if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02100     return NULL;        // error!
02101 
02102   /* was it enough? */
02103   if (len > sizeof(static_sa)
02104 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02105       || sa->sa_len > sizeof(static_sa)
02106 #endif
02107       )
02108     {
02109       /* nope, malloc a new socket with the proper size */
02110 
02111 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02112       if (sa->sa_len != len)
02113         len = sa->sa_len;
02114 #endif
02115 
02116       sa = (sockaddr*)malloc(len);
02117       if (sa == NULL)
02118     return NULL;        // out of memory
02119 
02120       if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02121     {
02122       free(sa);
02123       return NULL;
02124     }
02125 
02126       peer = ::KSocketAddress::newAddress(sa, len);
02127       free(sa);
02128     }
02129   else
02130     peer = ::KSocketAddress::newAddress(sa, len);
02131 
02132   return peer;
02133 }
02134 
02135 QString KExtendedSocket::strError(int code, int syserr)
02136 {
02137   const char * msg;
02138   if (code == IO_LookupError)
02139     msg = gai_strerror(syserr);
02140   else
02141     msg = strerror(syserr);
02142 
02143   return QString::fromLocal8Bit(msg);
02144 }
02145 
02146 
02147 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
02148 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
02149 
02150 /*
02151  * class KAddressInfo
02152  */
02153 
02154 #if 0
02155 KAddressInfo::KAddressInfo(addrinfo *p)
02156 {
02157    ai = (addrinfo *) malloc(sizeof(addrinfo));
02158    memcpy(ai, p, sizeof(addrinfo));
02159    ai->ai_next = NULL;
02160    if (p->ai_canonname)
02161    {
02162       ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
02163       strcpy(ai->ai_canonname, p->ai_canonname);
02164    }
02165    if (p->ai_addr && p->ai_addrlen)
02166    {
02167       ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
02168       memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
02169    }
02170    else
02171    {
02172       ai->ai_addr = 0;
02173       ai->ai_addrlen = 0;
02174    }
02175 
02176    addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
02177 }
02178 #endif
02179 KAddressInfo::~KAddressInfo()
02180 {
02181   if (ai && ai->ai_canonname)
02182     free(ai->ai_canonname);
02183 
02184   if (ai && ai->ai_addr)
02185     free(ai->ai_addr);  
02186 
02187   if (ai)
02188     free(ai);
02189   delete addr;
02190 }
02191 
02192 int KAddressInfo::flags() const
02193 {
02194   return ai->ai_flags;
02195 }
02196 
02197 int KAddressInfo::family() const
02198 {
02199   return ai->ai_family;
02200 }
02201 
02202 int KAddressInfo::socktype() const
02203 {
02204   return ai->ai_socktype;
02205 }
02206 
02207 int KAddressInfo::protocol() const
02208 {
02209   return ai->ai_protocol;
02210 }
02211 
02212 const char* KAddressInfo::canonname() const
02213 {
02214   return ai->ai_canonname;
02215 }
02216 
02217 void KExtendedSocket::virtual_hook( int id, void* data )
02218 { KBufferedIO::virtual_hook( id, data ); }
02219 
02220 #include "kextsock.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Jul 22 10:16:17 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003