kdecore Library API Documentation

kextsock.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2000-2005 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   if (d->resRemote.error() != KResolver::NoError)
00753     return d->resRemote.error();
00754   if (d->resLocal.error() != KResolver::NoError)
00755     return d->resLocal.error();
00756   return 0;
00757 }
00758 
00759 /*
00760  * Performs an asynchronous lookup on the given address(es)
00761  */
00762 int KExtendedSocket::startAsyncLookup()
00763 {
00764   cleanError();
00765   if (d->status > lookupInProgress)
00766     return -1;
00767   if (d->status == lookupInProgress)
00768     // already in progress
00769     return 0;
00770 
00771   /* check socket type flags */
00772   int socktype, familyMask, flags;
00773   if (!process_flags(d->flags, socktype, familyMask, flags))
00774     return -2;
00775 
00776   // perform the global lookup before
00777   if (!d->resRemote.isRunning())
00778     {
00779       d->resRemote.setFlags(flags);
00780       d->resRemote.setFamily(familyMask);
00781       d->resRemote.setSocketType(socktype);
00782       QObject::connect(&d->resRemote, SIGNAL(finished(KResolverResults)), 
00783                this, SLOT(dnsResultsReady()));
00784 
00785       if (!d->resRemote.start())
00786     {
00787       setError(IO_LookupError, d->resRemote.error());
00788       return d->resRemote.error();
00789     }
00790     }
00791 
00792   if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning())
00793     {
00794       /* keep flags, but make this passive */
00795       flags |= KResolver::Passive;
00796       d->resLocal.setFlags(flags);
00797       d->resLocal.setFamily(familyMask);
00798       d->resLocal.setSocketType(socktype);
00799       QObject::connect(&d->resLocal, SIGNAL(finished(KResolverResults)), 
00800                this, SLOT(dnsResultsReady()));
00801 
00802       if (!d->resLocal.start())
00803     {
00804       setError(IO_LookupError, d->resLocal.error());
00805       return d->resLocal.error();
00806     }
00807     }
00808 
00809   // if we are here, there were no errors
00810   if (d->resRemote.isRunning() || d->resLocal.isRunning())
00811     d->status = lookupInProgress; // only if there actually is a running lookup
00812   else
00813     {
00814       d->status = lookupDone;
00815       emit lookupFinished(d->resRemote.results().count() + 
00816               d->resLocal.results().count());
00817     }
00818   return 0;
00819 }
00820 
00821 void KExtendedSocket::cancelAsyncLookup()
00822 {
00823   cleanError();
00824   if (d->status != lookupInProgress)
00825     return;         // what's to cancel?
00826 
00827   d->status = nothing;
00828   d->resLocal.cancel(false);
00829   d->resRemote.cancel(false);
00830 }
00831 
00832 int KExtendedSocket::listen(int N)
00833 {
00834   cleanError();
00835   if ((d->flags & passiveSocket) == 0 || d->status >= listening)
00836     return -2;
00837   if (d->status < lookupDone)
00838     if (lookup() != 0)
00839       return -2;        // error!
00840   if (d->resRemote.error())
00841     return -2;
00842   
00843   // doing the loop:
00844   KResolverResults::const_iterator it;
00845   KResolverResults res = d->resRemote.results();
00846   for (it = res.begin(); it != res.end(); ++it)
00847     {
00848       //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl;
00849       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
00850       if (sockfd == -1)
00851     {
00852       // socket failed creating
00853       //kdDebug(170) << "Failed to create: " << perror << endl;
00854       continue;
00855     }
00856     
00857       fcntl(sockfd, F_SETFD, FD_CLOEXEC);
00858 
00859       if (d->addressReusable)
00860     setAddressReusable(sockfd, true);
00861       setIPv6Only(d->ipv6only);
00862       cleanError();
00863       if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1)
00864     {
00865       //kdDebug(170) << "Failed to bind: " << perror << endl;
00866       ::close(sockfd);
00867       sockfd = -1;
00868       continue;
00869     }
00870 
00871       // ok, socket has bound
00872       // kdDebug(170) << "Socket bound: " << sockfd << endl;
00873 
00874       d->status = bound;
00875       break;
00876     }
00877 
00878   if (sockfd == -1)
00879     {
00880       setError(IO_ListenError, errno);
00881       //kdDebug(170) << "Listen error - sockfd is -1 " << endl;
00882       return -1;
00883     }
00884 
00885   d->status = bound;
00886   setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00887 
00888   int retval = KSocks::self()->listen(sockfd, N);
00889   if (retval == -1)
00890     setError(IO_ListenError, errno);
00891   else
00892     {
00893       d->status = listening;
00894       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
00895       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
00896     }
00897   return retval == -1 ? -1 : 0;
00898 }
00899 
00900 int KExtendedSocket::accept(KExtendedSocket *&sock)
00901 {
00902   cleanError();
00903   sock = NULL;
00904   if ((d->flags & passiveSocket) == 0 || d->status >= accepting)
00905     return -2;
00906   if (d->status < listening)
00907     if (listen() < 0)
00908       return -2;        // error!
00909 
00910   // let's see
00911   // if we have a timeout in place, we have to place this socket in non-blocking
00912   // mode
00913   bool block = blockingMode();
00914   struct sockaddr sa;
00915   ksocklen_t len = sizeof(sa);
00916   sock = NULL;
00917 
00918   if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0)
00919     {
00920       fd_set set;
00921 
00922       setBlockingMode(false);   // turn on non-blocking
00923       FD_ZERO(&set);
00924       FD_SET(sockfd, &set);
00925 
00926       //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n",
00927       //         sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
00928       // check if there is anything to accept now
00929       int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout);
00930       if (retval == -1)
00931     {
00932       setError(IO_UnspecifiedError, errno);
00933       return -1;        // system error
00934     }
00935       else if (retval == 0 || !FD_ISSET(sockfd, &set))
00936     {
00937       setError(IO_TimeOutError, 0);
00938       return -3;        // timeout
00939     }
00940     }
00941 
00942   // it's common stuff here
00943   int newfd = KSocks::self()->accept(sockfd, &sa, &len);
00944 
00945   if (newfd == -1)
00946     {
00947       setError(IO_AcceptError, errno);
00948       kdWarning(170) << "Error accepting on socket " << sockfd << ":"
00949              << perror << endl;
00950       return -1;
00951     }
00952 
00953   fcntl(newfd, F_SETFD, FD_CLOEXEC);
00954 
00955   //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd);
00956 
00957   setBlockingMode(block);   // restore blocking mode
00958 
00959   sock = new KExtendedSocket;
00960   sock->d->status = connected;
00961   sock->sockfd = newfd;
00962   sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00963   sock->setBufferSize(0, 0);    // always unbuffered here. User can change that later
00964 
00965   return 0;
00966 }
00967 
00968 /*
00969  * tries to connect
00970  *
00971  * FIXME!
00972  * This function is critical path. It has to be cleaned up and made faster
00973  */
00974 int KExtendedSocket::connect()
00975 {
00976   cleanError();
00977   if (d->flags & passiveSocket || d->status >= connected)
00978     return -2;
00979   if (d->status < lookupDone)
00980     if (lookup() != 0)
00981       return -2;
00982 
00983   timeval end, now;
00984   // Ok, things are a little tricky here
00985   // Let me explain
00986   // getaddrinfo() will return several different families of sockets
00987   // When we have to bind before we connect, we have to make sure we're binding
00988   // and connecting to the same family, or things won't work
00989 
00990   bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
00991   if (doingtimeout)
00992     {
00993       gettimeofday(&end, NULL);
00994       end.tv_usec += d->timeout.tv_usec;
00995       end.tv_sec += d->timeout.tv_sec;
00996       if (end.tv_usec > 1000*1000)
00997     {
00998       end.tv_usec -= 1000*1000;
00999       end.tv_sec++;
01000     }
01001 //  kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n",
01002 //           d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec);
01003     }
01004 
01005   KResolverResults remote = d->resRemote.results(),
01006     local = d->resLocal.results();
01007   KResolverResults::const_iterator it, it2;
01008   //kdDebug(170) << "Starting connect to " << host() << '|' << port() 
01009   //             << ": have " << local.count() << " local entries and "
01010   //             << remote.count() << " remote" << endl;
01011   for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
01012     {
01013       //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl;
01014       if (it2 != local.end())
01015     {
01016 //    //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl;
01017       if ((*it).family() != (*it2).family())
01018         // differing families, scan local for a matching family
01019         for (it2 = local.begin(); it2 != local.end(); ++it2)
01020           if ((*it).family() == (*it2).family())
01021         break;
01022 
01023       if ((*it).family() != (*it2).family())
01024         {
01025           // no matching families for this
01026           //kdDebug(170) << "No matching family for bind socket\n";
01027           it2 = local.begin();
01028           continue;
01029         }
01030 
01031       //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl;
01032       errno = 0;
01033       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01034       setError(IO_ConnectError, errno);
01035       if (sockfd == -1)
01036         continue;       // cannot create this socket
01037           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01038       if (d->addressReusable)
01039         setAddressReusable(sockfd, true);
01040       setIPv6Only(d->ipv6only);
01041       cleanError();
01042       if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
01043         {
01044           //kdDebug(170) << "Bind failed: " << perror << endl;
01045           ::close(sockfd);
01046           sockfd = -1;
01047           continue;
01048         }
01049     }
01050       else
01051     {
01052       // no need to bind, just create
01053       sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01054       if (sockfd == -1)
01055         {
01056           setError(IO_ConnectError, errno);
01057           continue;
01058         }
01059           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01060       if (d->addressReusable)
01061         setAddressReusable(sockfd, true);
01062       setIPv6Only(d->ipv6only);
01063       cleanError();
01064     }
01065 
01066 //      kdDebug(170) << "Socket " << sockfd << " created" << endl;
01067       d->status = created;
01068 
01069       // check if we have to do timeout
01070       if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
01071     {
01072       fd_set rd, wr;
01073 
01074       setBlockingMode(false);
01075 
01076       // now try and connect
01077       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01078         {
01079           // this could be EWOULDBLOCK
01080           if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01081         {
01082           //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl;
01083           setError(IO_ConnectError, errno);
01084           ::close(sockfd);
01085           sockfd = -1;
01086           continue; // nope, another error
01087         }
01088 
01089           FD_ZERO(&rd);
01090           FD_ZERO(&wr);
01091           FD_SET(sockfd, &rd);
01092           FD_SET(sockfd, &wr);
01093 
01094           int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
01095           if (retval == -1)
01096         {
01097           setError(IO_FatalError, errno);
01098           continue; // system error
01099         }
01100           else if (retval == 0)
01101         {
01102           ::close(sockfd);
01103           sockfd = -1;
01104 //        kdDebug(170) << "Time out while trying to connect to " <<
01105 //          (*it).address().toString() << endl;
01106           d->status = lookupDone;
01107           setError(IO_TimeOutError, 0);
01108           return -3;    // time out
01109         }
01110 
01111           // adjust remaining time
01112           gettimeofday(&now, NULL);
01113           d->timeout.tv_sec = end.tv_sec - now.tv_sec;
01114           d->timeout.tv_usec = end.tv_usec - now.tv_usec;
01115           if (d->timeout.tv_usec < 0)
01116         {
01117           d->timeout.tv_usec += 1000*1000;
01118           d->timeout.tv_sec--;
01119         }
01120 //        kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n",
01121 //               sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
01122 
01123           // this means that an event occurred in the socket
01124           int errcode;
01125           socklen_t len = sizeof(errcode);
01126           retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
01127                   &len);
01128           if (retval == -1 || errcode != 0)
01129         {
01130           // socket did not connect
01131           //kdDebug(170) << "Socket " << sockfd << " did not connect: "
01132           //        << strerror(errcode) << endl;
01133           ::close(sockfd);
01134           sockfd = -1;
01135 
01136           // this is HIGHLY UNLIKELY
01137           if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
01138             {
01139               d->status = lookupDone;
01140               setError(IO_TimeOutError, 0);
01141               return -3; // time out
01142             }
01143 
01144           setError(IO_ConnectError, errcode);
01145           continue;
01146         }
01147         }
01148 
01149       // getting here means it connected
01150       // setBufferSize() takes care of creating the socket notifiers
01151       setBlockingMode(true);
01152       d->status = connected;
01153       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01154       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01155             d->flags & outputBufferedSocket ? -1 : 0);
01156       emit connectionSuccess();
01157 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01158       return 0;
01159     }
01160       else
01161     {
01162       // without timeouts
01163       if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01164         {
01165           //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString() 
01166           //       << " did not connect: " << perror << endl;
01167           setError(IO_ConnectError, errno);
01168           ::close(sockfd);
01169           sockfd = -1;
01170           continue;
01171         }
01172 
01173       d->status = connected;
01174       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01175       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01176             d->flags & outputBufferedSocket ? -1 : 0);
01177       emit connectionSuccess();
01178 //    kdDebug(170) << "Socket " << sockfd << " connected\n";
01179       return 0;     // it connected
01180     }
01181     }
01182 
01183   // getting here means no socket connected or stuff like that
01184   emit connectionFailed(d->syserror);
01185   //kdDebug(170) << "Failed to connect\n";
01186   return -1;
01187 }
01188 
01189 int KExtendedSocket::startAsyncConnect()
01190 {
01191   cleanError();
01192   // check status
01193   if (d->status >= connected || d->flags & passiveSocket)
01194     return -2;
01195 
01196   if (d->status == connecting)
01197     // already on async connect
01198     return 0;
01199 
01200   // check if we have to do lookup
01201   // if we do, then we'll use asynchronous lookup and use
01202   // signal lookupFinished to do connection
01203   if (d->status < lookupDone)
01204     {
01205       QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01206       if (d->status < lookupInProgress)
01207     return startAsyncLookup();
01208       else
01209     return 0;       // we still have to wait
01210     }
01211 
01212   // here we have d->status >= lookupDone and <= connecting
01213   // we can do our connection
01214   d->status = connecting;
01215   QGuardedPtr<QObject> p = this;
01216   connectionEvent();
01217   if (!p) 
01218     return -1; // We have been deleted.
01219   if (d->status < connecting)
01220     return -1;
01221   return 0;
01222 }
01223 
01224 void KExtendedSocket::cancelAsyncConnect()
01225 {
01226   if (d->status != connecting)
01227     return;
01228 
01229   if (sockfd != -1)
01230     {
01231       // we have a waiting connection
01232       if (d->qsnIn)
01233     delete d->qsnIn;
01234       if (d->qsnOut)
01235     delete d->qsnOut;
01236       d->qsnIn = d->qsnOut = NULL;
01237 
01238       ::close(sockfd);
01239       sockfd = -1;
01240     }
01241   d->status = lookupDone;
01242 }
01243 
01244 bool KExtendedSocket::open(int mode)
01245 {
01246   if (mode != IO_Raw | IO_ReadWrite)
01247     return false;       // invalid open mode
01248 
01249   if (d->flags & passiveSocket)
01250     return listen() == 0;
01251   else if (d->status < connecting)
01252     return connect() == 0;
01253   else
01254     return false;
01255 }
01256 
01257 void KExtendedSocket::close()
01258 {
01259   if (sockfd == -1 || d->status >= closing)
01260     return;         // nothing to close
01261 
01262   // LOCK BUFFER MUTEX
01263   if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
01264     {
01265       // write buffer not empty, go into closing state
01266       d->status = closing;
01267       if (d->qsnIn)
01268     delete d->qsnIn;
01269       d->qsnIn = NULL;
01270       // we keep the outgoing socket notifier because we want
01271       // to send data, but not receive
01272     }
01273   else
01274     {
01275       // nope, write buffer is empty
01276       // we can close now
01277       if (d->qsnIn)
01278     delete d->qsnIn;
01279       if (d->qsnOut)
01280     delete d->qsnOut;
01281       d->qsnIn = d->qsnOut = NULL;
01282 
01283       ::close(sockfd);
01284       d->status = done;
01285       emit closed(readBufferSize() != 0 ? availRead : 0);
01286     }
01287   // UNLOCK BUFFER MUTEX
01288 }
01289 
01290 
01291 void KExtendedSocket::closeNow()
01292 {
01293   if (d->status >= done)
01294     return;         // nothing to close
01295 
01296   // close the socket
01297   delete d->qsnIn;
01298   delete d->qsnOut;
01299   d->qsnIn = d->qsnOut = NULL;
01300 
01301   if (d->status > connecting && sockfd != -1)
01302     {
01303       ::close(sockfd);
01304       sockfd = -1;
01305     }
01306   else if (d->status == connecting)
01307     cancelAsyncConnect();
01308   else if (d->status == lookupInProgress)
01309     cancelAsyncLookup();
01310 
01311   d->status = done;
01312 
01313   emit closed(closedNow |
01314           (readBufferSize() != 0 ? availRead : 0) |
01315           (writeBufferSize() != 0 ? dirtyWrite : 0));
01316 }
01317 
01318 void KExtendedSocket::release()
01319 {
01320   // release our hold on the socket
01321   sockfd = -1;
01322   d->status = done;
01323 
01324   d->resRemote.cancel(false);
01325   d->resLocal.cancel(false);
01326 
01327   if (d->local != NULL)
01328     delete d->local;
01329   if (d->peer != NULL)
01330     delete d->peer;
01331 
01332   d->peer = d->local = NULL;
01333 
01334   if (d->qsnIn != NULL)
01335     delete d->qsnIn;
01336   if (d->qsnOut != NULL)
01337     delete d->qsnOut;
01338 
01339   d->qsnIn = d->qsnOut = NULL;
01340 
01341   // now that the socket notificators are done with, we can flush out the buffers
01342   consumeReadBuffer(readBufferSize(), NULL, true);
01343   consumeWriteBuffer(writeBufferSize());
01344 
01345   // don't delete d
01346   // leave that for the destructor
01347 }
01348 
01349 void KExtendedSocket::flush()
01350 {
01351   cleanError();
01352   if (d->status < connected || d->status >= done || d->flags & passiveSocket)
01353     return;
01354 
01355   if (sockfd == -1)
01356     return;
01357 
01358   if ((d->flags & outputBufferedSocket) == 0)
01359     return;         // nothing to do
01360 
01361   // LOCK MUTEX
01362 
01363   unsigned written = 0;
01364   unsigned offset = outBufIndex; // this happens only for the first
01365   while (writeBufferSize() - written > 0)
01366     {
01367       // we have to write each output buffer in outBuf
01368       // but since we can have several very small buffers, we can make things
01369       // better by concatenating a few of them into a big buffer
01370       // question is: how big should that buffer be? 16 kB should be enough
01371 
01372       QByteArray buf(16384);
01373       QByteArray *a = outBuf.first();
01374       unsigned count = 0;
01375 
01376       while (a && count + (a->size() - offset) <= buf.size())
01377     {
01378       memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
01379       count += a->size() - offset;
01380       offset = 0;
01381       a = outBuf.next();
01382     }
01383 
01384       // see if we can still fit more
01385       if (a && count < buf.size())
01386     {
01387       // getting here means this buffer (a) is larger than
01388       // (buf.size() - count) (even for count == 0).
01389       memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
01390       offset += buf.size() - count;
01391       count = buf.size();
01392     }
01393 
01394       // now try to write those bytes
01395       int wrote = KSocks::self()->write(sockfd, buf, count);
01396 
01397       if (wrote == -1)
01398     {
01399       // could be EAGAIN (EWOULDBLOCK)
01400       setError(IO_WriteError, errno);
01401       break;
01402     }
01403       written += wrote;
01404 
01405       if ((unsigned)wrote != count)
01406     break;
01407     }
01408   if (written)
01409     {
01410       consumeWriteBuffer(written);
01411       emit bytesWritten(written);
01412     }
01413 
01414   // UNLOCK MUTEX
01415 }
01416 
01417 
01418 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen)
01419 {
01420   cleanError();
01421   if (d->status < connected || d->flags & passiveSocket)
01422     return -2;
01423 
01424   int retval;
01425 
01426   if ((d->flags & inputBufferedSocket) == 0)
01427     {
01428       // we aren't buffering this socket, so just pass along
01429       // the call to the real read method
01430 
01431       if (sockfd == -1)
01432     return -2;
01433       if (data)
01434     retval = KSocks::self()->read(sockfd, data, maxlen);
01435       else
01436     retval = skipData(sockfd, maxlen);
01437       if (retval == -1)
01438     setError(IO_ReadError, errno);
01439     }
01440   else
01441     {
01442       // this socket is being buffered. So read from the buffer
01443 
01444       // LOCK BUFFER MUTEX
01445 
01446       retval = consumeReadBuffer(maxlen, data);
01447       if (retval == 0)
01448     {
01449       // consumeReadBuffer returns 0 only if the buffer is
01450       // empty
01451       if (sockfd == -1)
01452         return 0;       // buffer is clear now, indicate EOF
01453       setError(IO_ReadError, EWOULDBLOCK);
01454       retval = -1;
01455     }
01456 
01457       // UNLOCK BUFFER MUTEX
01458 
01459     }
01460   return retval;
01461 }
01462 
01463 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len)
01464 {
01465   cleanError();
01466   if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
01467     return -2;
01468   if (sockfd == -1)
01469     return -2;
01470 
01471   if (len == 0)
01472     return 0;           // what's to write?
01473 
01474   int retval;
01475 
01476   if ((d->flags & outputBufferedSocket) == 0)
01477     {
01478       // socket not buffered. Just call write
01479       retval = KSocks::self()->write(sockfd, data, len);
01480       if (retval == -1)
01481     setError(IO_WriteError, errno);
01482       else
01483     emit bytesWritten(retval);
01484     }
01485   else
01486     {
01487       // socket is buffered. Feed the write buffer
01488 
01489       // LOCK BUFFER MUTEX
01490 
01491       register unsigned wsize = writeBufferSize();
01492       if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning
01493     {
01494       // buffer is full!
01495       setError(IO_WriteError, EWOULDBLOCK);
01496       retval = -1;
01497     }
01498       else
01499     {
01500       if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
01501         // we cannot write all data. Write just as much as to fill the buffer
01502         len = d->outMaxSize - wsize;
01503 
01504       // len > 0 here
01505       retval = feedWriteBuffer(len, data);
01506       if (wsize == 0 || d->emitWrite)
01507         // buffer was empty, which means that the notifier is probably disabled
01508         d->qsnOut->setEnabled(true);
01509     }
01510 
01511       // UNLOCK BUFFER MUTEX
01512     }
01513 
01514   return retval;
01515 }
01516 
01517 int KExtendedSocket::peekBlock(char *data, uint maxlen)
01518 {
01519   if (d->status < connected || d->flags & passiveSocket)
01520     return -2;
01521   if (sockfd == -1)
01522     return -2;
01523 
01524   // need to LOCK MUTEX around this call...
01525 
01526   if (d->flags & inputBufferedSocket)
01527     return consumeReadBuffer(maxlen, data, false);
01528 
01529   return 0;
01530 }
01531 
01532 int KExtendedSocket::unreadBlock(const char *, uint)
01533 {
01534   // Always return -1, indicating this is not supported
01535   setError(IO_ReadError, ENOSYS);
01536   return -1;
01537 }
01538 
01539 int KExtendedSocket::bytesAvailable() const
01540 {
01541   if (d->status < connected || d->flags & passiveSocket)
01542     return -2;
01543 
01544   // as of now, we don't do any extra processing
01545   // we only work in input-buffered sockets
01546   if (d->flags & inputBufferedSocket)
01547     return KBufferedIO::bytesAvailable();
01548 
01549   return 0;         // TODO: FIONREAD ioctl
01550 }
01551 
01552 int KExtendedSocket::waitForMore(int msecs)
01553 {
01554   cleanError();
01555   if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
01556     return -2;
01557   if (sockfd == -1)
01558     return -2;
01559 
01560   fd_set rd;
01561   FD_ZERO(&rd);
01562   FD_SET(sockfd, &rd);
01563   timeval tv;
01564   tv.tv_sec = msecs / 1000;
01565   tv.tv_usec = (msecs % 1000) * 1000;
01566 
01567   int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
01568   if (retval == -1)
01569     {
01570       setError(IO_FatalError, errno);
01571       return -1;
01572     }
01573   else if (retval != 0)
01574     socketActivityRead();   // do read processing
01575 
01576   return bytesAvailable();
01577 }
01578 
01579 int KExtendedSocket::getch()
01580 {
01581   unsigned char c;
01582   int retval;
01583   retval = readBlock((char*)&c, sizeof(c));
01584 
01585   if (retval < 0)
01586     return retval;
01587   return c;
01588 }
01589 
01590 int KExtendedSocket::putch(int ch)
01591 {
01592   unsigned char c = (char)ch;
01593   return writeBlock((char*)&c, sizeof(c));
01594 }
01595 
01596 // sets the emission of the readyRead signal
01597 void KExtendedSocket::enableRead(bool enable)
01598 {
01599   // check if we can disable the socket notifier
01600   // saves us a few cycles
01601   // this is so because in buffering mode, we rely on these signals
01602   // being emitted to do our I/O. We couldn't disable them here
01603   if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
01604     d->qsnIn->setEnabled(false);
01605   else if (enable && d->qsnIn)
01606     // we can enable it always
01607     d->qsnIn->setEnabled(true);
01608   d->emitRead = enable;
01609 }
01610 
01611 // sets the emission of the readyWrite signal
01612 void KExtendedSocket::enableWrite(bool enable)
01613 {
01614   // same thing as above
01615   if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
01616     d->qsnOut->setEnabled(false);
01617   else if (enable && d->qsnOut)
01618     // we can enable it always
01619     d->qsnOut->setEnabled(true);
01620   d->emitWrite = enable;
01621 }
01622 
01623 // protected slot
01624 // this is connected to d->qsnIn::activated(int)
01625 void KExtendedSocket::socketActivityRead()
01626 {
01627   if (d->flags & passiveSocket)
01628     {
01629       emit readyAccept();
01630       return;
01631     }
01632   if (d->status == connecting)
01633     {
01634       connectionEvent();
01635       return;
01636     }
01637   if (d->status != connected)
01638     return;
01639 
01640   // do we need to do I/O here?
01641   if (d->flags & inputBufferedSocket)
01642     {
01643       // aye. Do read from the socket and feed our buffer
01644       QByteArray a;
01645       char buf[1024];
01646       int len, totalread = 0;
01647 
01648       // LOCK MUTEX
01649 
01650       unsigned cursize = readBufferSize();
01651 
01652       if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
01653     {
01654       do
01655         {
01656           // check that we can read that many bytes
01657           if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
01658         // no, that would overrun the buffer
01659         // note that this will also make us exit the loop
01660         len = d->inMaxSize - (cursize + totalread);
01661           else
01662         len = sizeof(buf);
01663 
01664           len = KSocks::self()->read(sockfd, buf, len);
01665           if (len > 0)
01666         {
01667           // normal read operation
01668           a.resize(a.size() + len);
01669           memcpy(a.data() + totalread, buf, len);
01670           totalread += len; // totalread == a.size() now
01671         }
01672           else if (len == 0)
01673         {
01674           // EOF condition here
01675           ::close(sockfd);
01676           sockfd = -1;  // we're closed
01677           d->qsnIn->deleteLater();
01678           delete d->qsnOut;
01679           d->qsnIn = d->qsnOut = NULL;
01680           d->status = done;
01681           emit closed(involuntary |
01682                   (readBufferSize() ? availRead : 0) |
01683                   (writeBufferSize() ? dirtyWrite : 0));
01684           return;
01685         }
01686           else
01687         {
01688           // error!
01689           setError(IO_ReadError, errno);
01690           return;
01691         }
01692           // will loop only for normal read operations
01693         }
01694       while (len == sizeof(buf));
01695 
01696       feedReadBuffer(a.size(), a.data());
01697     }
01698 
01699       // UNLOCK MUTEX
01700     }
01701   else
01702     {
01703       // No input buffering, but the notifier fired
01704       // That means that either there is data to be read or that the 
01705       // socket closed.
01706 
01707       // try to read one byte. If we can't, then the socket got closed
01708 
01709       char c;
01710       int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
01711       if (len == 0)
01712     {
01713       // yes, it's an EOF condition
01714       d->qsnIn->setEnabled(false);
01715       ::close(sockfd);
01716       sockfd = -1;
01717       d->status = done;
01718       emit closed(involuntary);
01719       return;
01720     }
01721     }
01722 
01723   if (d->emitRead)
01724     emit readyRead();
01725 }
01726 
01727 void KExtendedSocket::socketActivityWrite()
01728 {
01729   if (d->flags & passiveSocket)
01730     return;
01731   if (d->status == connecting)
01732     {
01733       connectionEvent();
01734       return;
01735     }
01736   if (d->status != connected && d->status != closing)
01737     return;
01738 
01739   flush();
01740 
01741   bool empty = writeBufferSize() == 0;
01742 
01743   if (d->emitWrite && empty)
01744     emit readyWrite();
01745   else if (!d->emitWrite)
01746     {
01747       // check if we can disable the notifier
01748       d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send
01749     }
01750   if (d->status == closing && empty)
01751     {
01752       // done sending the missing data!
01753       d->status = done;
01754 
01755       delete d->qsnOut;
01756       ::close(sockfd);
01757 
01758       d->qsnOut = NULL;
01759       sockfd = -1;
01760       emit closed(delayed | (readBufferSize() ? availRead : 0));
01761     }
01762 }
01763 
01764 // this function is called whenever we have a "connection event"
01765 // that is, whenever our asynchronously connecting socket throws
01766 // an event
01767 void KExtendedSocket::connectionEvent()
01768 {
01769   if (d->status != connecting)
01770     return;         // move along. There's nothing to see here
01771 
01772   KResolverResults remote = d->resRemote.results();
01773   if (remote.count() == 0)
01774     {
01775       // We have a problem! Abort?
01776       kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
01777       return;
01778     }
01779 
01780   int errcode = 0;
01781 
01782   if (sockfd != -1)
01783     {
01784       // our socket has activity
01785       // find out what it was
01786       int retval;
01787       socklen_t len = sizeof(errcode);
01788       retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
01789 
01790       if (retval == -1 || errcode != 0)
01791     {
01792       // socket activity and there was error?
01793       // that means the socket probably did not connect
01794       if (d->qsnIn)
01795         delete d->qsnIn;
01796       if (d->qsnOut)
01797         delete d->qsnOut;
01798       ::close(sockfd);
01799 
01800       sockfd = -1;
01801       d->qsnIn = d->qsnOut = NULL;
01802       d->current++;
01803       setError(IO_ConnectError, errcode);
01804     }
01805       else
01806     {
01807       // hmm, socket activity and there was no error?
01808       // that means it connected
01809       // YAY!
01810       cleanError();
01811       d->status = connected;
01812       setBlockingMode(true);
01813       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01814       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01815             d->flags & outputBufferedSocket ? -1 : 0);
01816       emit connectionSuccess();
01817       return;
01818     }
01819     }
01820 
01821   // ok, we have to try something here
01822   // and sockfd == -1
01823   KResolverResults local = d->resLocal.results();
01824   unsigned localidx = 0;
01825   for ( ; d->current < remote.count(); d->current++)
01826     {
01827       // same code as in connect()
01828       if (local.count() != 0)
01829     {
01830       // scan bindres for a local resuls family
01831       for (localidx = 0; localidx < local.count(); localidx++)
01832         if (remote[d->current].family() == local[localidx].family())
01833           break;
01834 
01835       if (remote[d->current].family() != local[localidx].family())
01836         {
01837           // no matching families for this
01838           continue;
01839         }
01840 
01841       errno = 0;
01842       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01843                 remote[d->current].protocol());
01844       setError(IO_ConnectError, errno);
01845       errcode = errno;
01846       if (sockfd == -1)
01847         continue;       // cannot create this socket
01848           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01849       if (d->addressReusable)
01850         setAddressReusable(sockfd, true);
01851       setIPv6Only(d->ipv6only);
01852       cleanError();
01853       if (KSocks::self()->bind(sockfd, local[localidx].address(), 
01854                    local[localidx].length()) == -1)
01855         {
01856           ::close(sockfd);
01857           sockfd = -1;
01858           continue;
01859         }
01860     }
01861       else
01862     {
01863       // no need to bind, just create
01864       sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01865                 remote[d->current].protocol());
01866       if (sockfd == -1)
01867         {
01868           setError(IO_ConnectError, errno);
01869           errcode = errno;
01870           continue;
01871         }
01872           fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01873       if (d->addressReusable)
01874         setAddressReusable(sockfd, true);
01875       setIPv6Only(d->ipv6only);
01876       cleanError();
01877     }
01878 
01879       if (KSocks::self()->hasWorkingAsyncConnect())
01880         setBlockingMode(false);
01881       if (KSocks::self()->connect(sockfd, remote[d->current].address(), 
01882                   remote[d->current].length()) == -1)
01883     {
01884       if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01885         {
01886           setError(IO_ConnectError, errno);
01887           ::close(sockfd);
01888           sockfd = -1;
01889           errcode = errno;
01890           continue;
01891         }
01892 
01893       // error here is either EWOULDBLOCK or EINPROGRESS
01894       // so, it is a good condition
01895       d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
01896       QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
01897       d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
01898       QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
01899 
01900       // ok, let the Qt event loop do the selecting for us
01901       return;
01902     }
01903 
01904       // eh, what?
01905       // the non-blocking socket returned valid connection?
01906       // already?
01907       // I suppose that could happen...
01908       cleanError();
01909       d->status = connected;
01910       setBlockingMode(true);
01911       setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01912       setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01913             d->flags & outputBufferedSocket ? -1 : 0);
01914       emit connectionSuccess();
01915       return;
01916     }
01917 
01918   // if we got here, it means that there are no more options to connect
01919   d->status = lookupDone;   // go back
01920   emit connectionFailed(errcode);
01921 }
01922 
01923 void KExtendedSocket::dnsResultsReady()
01924 {
01925   // check that this function was called in a valid state
01926   if (d->status != lookupInProgress)
01927     return;
01928 
01929   // valid state. Are results fully ready?
01930   if (d->resRemote.isRunning() || d->resLocal.isRunning())
01931     // no, still waiting for answer in one of the lookups
01932     return;
01933 
01934   // ok, we have all results
01935   // count how many results we have
01936   int n = d->resRemote.results().count() + d->resLocal.results().count();
01937 
01938   if (n)
01939     {
01940       d->status = lookupDone;
01941       cleanError();
01942     }
01943   else
01944     {
01945       d->status = nothing;
01946       setError(IO_LookupError, KResolver::NoName);
01947     }
01948 
01949   emit lookupFinished(n);
01950 
01951   return;
01952 }
01953 
01954 void KExtendedSocket::startAsyncConnectSlot()
01955 {
01956   QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01957 
01958   if (d->status == lookupDone)
01959     startAsyncConnect();
01960 }
01961 
01962 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host,
01963                  QString &port, int flags)
01964 {
01965   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01966 
01967   int err;
01968   char h[NI_MAXHOST], s[NI_MAXSERV];
01969 
01970   h[0] = s[0] = '\0';
01971 
01972   err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
01973   host = QString::fromUtf8(h);
01974   port = QString::fromUtf8(s);
01975 
01976   return err;
01977 }
01978 
01979 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port,
01980                  int flags)
01981 {
01982   return resolve(sock->data, sock->datasize, host, port, flags);
01983 }
01984 
01985 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port,
01986                         int userflags, int *error)
01987 {
01988   kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01989 
01990   int socktype, familyMask, flags;
01991   unsigned i;
01992   QPtrList<KAddressInfo> l;
01993 
01994   /* check socket type flags */
01995   if (!process_flags(userflags, socktype, familyMask, flags))
01996     return l;
01997 
01998 //  kdDebug(170) << "Performing lookup on " << host << "|" << port << endl;
01999   KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
02000   if (res.error())
02001     {
02002       if (error)
02003     *error = res.error();
02004       return l;
02005     }
02006 
02007   for (i = 0; i < res.count(); i++)
02008     {
02009       KAddressInfo *ai = new KAddressInfo();
02010 
02011       // I should have known that using addrinfo was going to come
02012       // and bite me back some day...
02013       ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
02014       memset(ai->ai, 0, sizeof(addrinfo));
02015 
02016       ai->ai->ai_family = res[i].family();
02017       ai->ai->ai_socktype = res[i].socketType();
02018       ai->ai->ai_protocol = res[i].protocol();
02019       QString canon = res[i].canonicalName();
02020       if (!canon.isEmpty())
02021     {
02022       ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
02023       strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional
02024     }
02025       if ((ai->ai->ai_addrlen = res[i].length()))
02026     {
02027       ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
02028       memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
02029     }
02030       else
02031     {
02032       ai->ai->ai_addr = 0;
02033     }
02034 
02035       ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
02036 
02037       l.append(ai);
02038     }
02039 
02040   if ( error )
02041       *error = 0;               // all is fine!
02042 
02043   return l;
02044 }
02045 
02046 ::KSocketAddress *KExtendedSocket::localAddress(int fd)
02047 {
02048   ::KSocketAddress *local;
02049   struct sockaddr static_sa, *sa = &static_sa;
02050   ksocklen_t len = sizeof(static_sa);
02051 
02052   /* find out the socket length, in advance
02053    * we use a sockaddr allocated on the heap just not to pass down
02054    * a NULL pointer to the first call. Some systems are reported to
02055    * set len to 0 if we pass NULL as the sockaddr */
02056   if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02057     return NULL;        // error!
02058 
02059   /* was it enough? */
02060   if (len > sizeof(static_sa)
02061 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02062       || sa->sa_len > sizeof(static_sa)
02063 #endif
02064       )
02065     {
02066       /* nope, malloc a new socket with the proper size */
02067 
02068 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02069       if (sa->sa_len != len)
02070         len = sa->sa_len;
02071 #endif
02072 
02073       sa = (sockaddr*)malloc(len);
02074       if (sa == NULL)
02075     return NULL;        // out of memory
02076 
02077       if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02078     {
02079       free(sa);
02080       return NULL;
02081     }
02082 
02083       local = ::KSocketAddress::newAddress(sa, len);
02084       free(sa);
02085     }
02086   else
02087     local = ::KSocketAddress::newAddress(sa, len);
02088 
02089   return local;
02090 }
02091 
02092 /* This is exactly the same code as localAddress, except
02093  * we call getpeername here */
02094 ::KSocketAddress *KExtendedSocket::peerAddress(int fd)
02095 {
02096   ::KSocketAddress *peer;
02097   struct sockaddr static_sa, *sa = &static_sa;
02098   ksocklen_t len = sizeof(static_sa);
02099 
02100   /* find out the socket length, in advance
02101    * we use a sockaddr allocated on the heap just not to pass down
02102    * a NULL pointer to the first call. Some systems are reported to
02103    * set len to 0 if we pass NULL as the sockaddr */
02104   if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02105     return NULL;        // error!
02106 
02107   /* was it enough? */
02108   if (len > sizeof(static_sa)
02109 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02110       || sa->sa_len > sizeof(static_sa)
02111 #endif
02112       )
02113     {
02114       /* nope, malloc a new socket with the proper size */
02115 
02116 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02117       if (sa->sa_len != len)
02118         len = sa->sa_len;
02119 #endif
02120 
02121       sa = (sockaddr*)malloc(len);
02122       if (sa == NULL)
02123     return NULL;        // out of memory
02124 
02125       if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02126     {
02127       free(sa);
02128       return NULL;
02129     }
02130 
02131       peer = ::KSocketAddress::newAddress(sa, len);
02132       free(sa);
02133     }
02134   else
02135     peer = ::KSocketAddress::newAddress(sa, len);
02136 
02137   return peer;
02138 }
02139 
02140 QString KExtendedSocket::strError(int code, int syserr)
02141 {
02142   const char * msg;
02143   if (code == IO_LookupError)
02144     msg = gai_strerror(syserr);
02145   else
02146     msg = strerror(syserr);
02147 
02148   return QString::fromLocal8Bit(msg);
02149 }
02150 
02151 
02152 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
02153 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
02154 
02155 /*
02156  * class KAddressInfo
02157  */
02158 
02159 #if 0
02160 KAddressInfo::KAddressInfo(addrinfo *p)
02161 {
02162    ai = (addrinfo *) malloc(sizeof(addrinfo));
02163    memcpy(ai, p, sizeof(addrinfo));
02164    ai->ai_next = NULL;
02165    if (p->ai_canonname)
02166    {
02167       ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
02168       strcpy(ai->ai_canonname, p->ai_canonname);
02169    }
02170    if (p->ai_addr && p->ai_addrlen)
02171    {
02172       ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
02173       memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
02174    }
02175    else
02176    {
02177       ai->ai_addr = 0;
02178       ai->ai_addrlen = 0;
02179    }
02180 
02181    addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
02182 }
02183 #endif
02184 KAddressInfo::~KAddressInfo()
02185 {
02186   if (ai && ai->ai_canonname)
02187     free(ai->ai_canonname);
02188 
02189   if (ai && ai->ai_addr)
02190     free(ai->ai_addr);  
02191 
02192   if (ai)
02193     free(ai);
02194   delete addr;
02195 }
02196 
02197 int KAddressInfo::flags() const
02198 {
02199   return ai->ai_flags;
02200 }
02201 
02202 int KAddressInfo::family() const
02203 {
02204   return ai->ai_family;
02205 }
02206 
02207 int KAddressInfo::socktype() const
02208 {
02209   return ai->ai_socktype;
02210 }
02211 
02212 int KAddressInfo::protocol() const
02213 {
02214   return ai->ai_protocol;
02215 }
02216 
02217 const char* KAddressInfo::canonname() const
02218 {
02219   return ai->ai_canonname;
02220 }
02221 
02222 void KExtendedSocket::virtual_hook( int id, void* data )
02223 { KBufferedIO::virtual_hook( id, data ); }
02224 
02225 #include "kextsock.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:09:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003