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