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