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 using namespace KNetwork;
00053
00054
00055
00056
00057
00058 class KExtendedSocketPrivate
00059 {
00060 public:
00061 int flags;
00062 int status;
00063 int syserror;
00064
00065 timeval timeout;
00066
00067 KResolver resRemote;
00068 KResolver resLocal;
00069 unsigned current;
00070
00071 ::KSocketAddress *local;
00072 ::KSocketAddress *peer;
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
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
00096
00097 case KExtendedSocket::streamSocket:
00098
00099 socktype = SOCK_STREAM;
00100 break;
00101
00102 case KExtendedSocket::datagramSocket:
00103
00104 socktype = SOCK_DGRAM;
00105 break;
00106
00107 case KExtendedSocket::rawSocket:
00108
00109 socktype = SOCK_RAW;
00110 break;
00111
00112 default:
00113
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
00137 }
00138 else
00139 familyMask = KResolver::KnownFamily;
00140
00141
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
00153
00154
00155
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
00179
00180
00181
00182 KExtendedSocket::KExtendedSocket() :
00183 sockfd(-1), d(new KExtendedSocketPrivate)
00184 {
00185 }
00186
00187
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
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
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
00253
00254
00255 int KExtendedSocket::setSocketFlags(int flags)
00256 {
00257 if (d->status > nothing)
00258 return -1;
00259
00260 return d->flags = flags;
00261 }
00262
00263 int KExtendedSocket::socketFlags() const
00264 {
00265 return d->flags;
00266 }
00267
00268
00269
00270
00271
00272 bool KExtendedSocket::setHost(const QString& host)
00273 {
00274 if (d->status > nothing)
00275 return false;
00276
00277 d->resRemote.setNodeName(host);
00278 return true;
00279 }
00280
00281
00282
00283
00284 QString KExtendedSocket::host() const
00285 {
00286 return d->resRemote.nodeName();
00287 }
00288
00289
00290
00291
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;
00302
00303 d->resRemote.setServiceName(service);
00304 return true;
00305 }
00306
00307
00308
00309
00310 QString KExtendedSocket::port() const
00311 {
00312 return d->resRemote.serviceName();
00313 }
00314
00315
00316
00317
00318 bool KExtendedSocket::setAddress(const QString& host, int port)
00319 {
00320 return setHost(host) && setPort(port);
00321 }
00322
00323
00324
00325
00326 bool KExtendedSocket::setAddress(const QString& host, const QString& serv)
00327 {
00328 return setHost(host) && setPort(serv);
00329 }
00330
00331
00332
00333
00334
00335
00336 bool KExtendedSocket::setBindHost(const QString& host)
00337 {
00338 if (d->status > nothing || d->flags & passiveSocket)
00339 return false;
00340
00341 d->resLocal.setServiceName(host);
00342 return true;
00343 }
00344
00345
00346
00347
00348
00349 bool KExtendedSocket::unsetBindHost()
00350 {
00351 return setBindHost(QString::null);
00352 }
00353
00354
00355
00356
00357 QString KExtendedSocket::bindHost() const
00358 {
00359 return d->resLocal.serviceName();
00360 }
00361
00362
00363
00364
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;
00375
00376 d->resLocal.setServiceName(service);
00377 return true;
00378 }
00379
00380
00381
00382
00383 bool KExtendedSocket::unsetBindPort()
00384 {
00385 return setBindPort(QString::null);
00386 }
00387
00388
00389
00390
00391 QString KExtendedSocket::bindPort() const
00392 {
00393 return d->resLocal.serviceName();
00394 }
00395
00396
00397
00398
00399 bool KExtendedSocket::setBindAddress(const QString& host, int port)
00400 {
00401 return setBindHost(host) && setBindPort(port);
00402 }
00403
00404
00405
00406
00407 bool KExtendedSocket::setBindAddress(const QString& host, const QString& service)
00408 {
00409 return setBindHost(host) && setBindPort(service);
00410 }
00411
00412
00413
00414
00415 bool KExtendedSocket::unsetBindAddress()
00416 {
00417 return unsetBindHost() && unsetBindPort();
00418 }
00419
00420
00421
00422
00423 bool KExtendedSocket::setTimeout(int secs, int usecs)
00424 {
00425 if (d->status >= connected)
00426 return false;
00427
00428 d->timeout.tv_sec = secs;
00429 d->timeout.tv_usec = usecs;
00430 return true;
00431 }
00432
00433
00434
00435
00436 timeval KExtendedSocket::timeout() const
00437 {
00438 return d->timeout;
00439 }
00440
00441
00442
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;
00452
00453 int fdflags = fcntl(sockfd, F_GETFL, 0);
00454 if (fdflags == -1)
00455 return false;
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
00472
00473 bool KExtendedSocket::blockingMode()
00474 {
00475 cleanError();
00476 if (d->status < created)
00477 return false;
00478
00479 if (sockfd == -1)
00480 return false;
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;
00489 }
00490
00491
00492
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;
00518
00519 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
00520 return false;
00521 return true;
00522 }
00523
00524
00525
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
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;
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
00572 d->ipv6only = enable;
00573
00574 setError(IO_UnspecifiedError, ENOSYS);
00575 return false;
00576 #endif
00577 }
00578
00579
00580
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
00603 setError(IO_UnspecifiedError, ENOSYS);
00604 return false;
00605 #endif
00606 }
00607
00608
00609
00610
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;
00623
00624 if (rsize < -2)
00625 return false;
00626
00627 if (wsize < -2)
00628 return false;
00629
00630
00631
00632
00633
00634
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
00645 d->flags &= ~inputBufferedSocket;
00646
00647 consumeReadBuffer(readBufferSize(), NULL, true);
00648 d->inMaxSize = 0;
00649 }
00650 else if (rsize != -2)
00651 {
00652
00653 if (rsize)
00654 d->flags |= inputBufferedSocket;
00655 d->inMaxSize = rsize;
00656
00657 if (rsize > 0 && (unsigned)rsize < readBufferSize())
00658
00659 consumeReadBuffer(readBufferSize() - rsize, NULL, true);
00660
00661 }
00662
00663 if (wsize == 0 && d->flags & outputBufferedSocket)
00664 {
00665
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
00675 if (wsize)
00676 d->flags |= outputBufferedSocket;
00677 d->outMaxSize = wsize;
00678
00679 if (wsize > 0 && (unsigned)wsize < writeBufferSize())
00680
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
00688
00689
00690 }
00691 }
00692
00693
00694
00695 setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw));
00696
00697
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
00709
00710
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
00724
00725
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
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
00757
00758 int KExtendedSocket::startAsyncLookup()
00759 {
00760 cleanError();
00761 if (d->status > lookupInProgress)
00762 return -1;
00763 if (d->status == lookupInProgress)
00764
00765 return 0;
00766
00767
00768 int socktype, familyMask, flags;
00769 if (!process_flags(d->flags, socktype, familyMask, flags))
00770 return -2;
00771
00772
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
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
00806 if (d->resRemote.isRunning() || d->resLocal.isRunning())
00807 d->status = lookupInProgress;
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;
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;
00836 if (d->resRemote.error())
00837 return -2;
00838
00839
00840 KResolverResults::const_iterator it;
00841 KResolverResults res = d->resRemote.results();
00842 for (it = res.begin(); it != res.end(); ++it)
00843 {
00844
00845 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
00846 if (sockfd == -1)
00847 {
00848
00849
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
00862 ::close(sockfd);
00863 sockfd = -1;
00864 continue;
00865 }
00866
00867
00868
00869
00870 d->status = bound;
00871 break;
00872 }
00873
00874 if (sockfd == -1)
00875 {
00876 setError(IO_ListenError, errno);
00877
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;
00905
00906
00907
00908
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);
00919 FD_ZERO(&set);
00920 FD_SET(sockfd, &set);
00921
00922
00923
00924
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;
00930 }
00931 else if (retval == 0 || !FD_ISSET(sockfd, &set))
00932 {
00933 setError(IO_TimeOutError, 0);
00934 return -3;
00935 }
00936 }
00937
00938
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
00952
00953 setBlockingMode(block);
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);
00960
00961 return 0;
00962 }
00963
00964
00965
00966
00967
00968
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
00981
00982
00983
00984
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
00998
00999 }
01000
01001 KResolverResults remote = d->resRemote.results(),
01002 local = d->resLocal.results();
01003 KResolverResults::const_iterator it, it2;
01004
01005
01006
01007 for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
01008 {
01009
01010 if (it2 != local.end())
01011 {
01012
01013 if ((*it).family() != (*it2).family())
01014
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
01022
01023 it2 = local.begin();
01024 continue;
01025 }
01026
01027
01028 errno = 0;
01029 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01030 setError(IO_ConnectError, errno);
01031 if (sockfd == -1)
01032 continue;
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
01041 ::close(sockfd);
01042 sockfd = -1;
01043 continue;
01044 }
01045 }
01046 else
01047 {
01048
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
01063 d->status = created;
01064
01065
01066 if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
01067 {
01068 fd_set rd, wr;
01069
01070 setBlockingMode(false);
01071
01072
01073 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01074 {
01075
01076 if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01077 {
01078
01079 setError(IO_ConnectError, errno);
01080 ::close(sockfd);
01081 sockfd = -1;
01082 continue;
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;
01095 }
01096 else if (retval == 0)
01097 {
01098 ::close(sockfd);
01099 sockfd = -1;
01100
01101
01102 d->status = lookupDone;
01103 setError(IO_TimeOutError, 0);
01104 return -3;
01105 }
01106
01107
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
01117
01118
01119
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
01127
01128
01129 ::close(sockfd);
01130 sockfd = -1;
01131
01132
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;
01138 }
01139
01140 setError(IO_ConnectError, errcode);
01141 continue;
01142 }
01143 }
01144
01145
01146
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
01154 return 0;
01155 }
01156 else
01157 {
01158
01159 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01160 {
01161
01162
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
01175 return 0;
01176 }
01177 }
01178
01179
01180 emit connectionFailed(d->syserror);
01181
01182 return -1;
01183 }
01184
01185 int KExtendedSocket::startAsyncConnect()
01186 {
01187 cleanError();
01188
01189 if (d->status >= connected || d->flags & passiveSocket)
01190 return -2;
01191
01192 if (d->status == connecting)
01193
01194 return 0;
01195
01196
01197
01198
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;
01206 }
01207
01208
01209
01210 d->status = connecting;
01211 QGuardedPtr<QObject> p = this;
01212 connectionEvent();
01213 if (!p)
01214 return -1;
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
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;
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;
01257
01258
01259 if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
01260 {
01261
01262 d->status = closing;
01263 if (d->qsnIn)
01264 delete d->qsnIn;
01265 d->qsnIn = NULL;
01266
01267
01268 }
01269 else
01270 {
01271
01272
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
01284 }
01285
01286
01287 void KExtendedSocket::closeNow()
01288 {
01289 if (d->status >= done)
01290 return;
01291
01292
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
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
01338 consumeReadBuffer(readBufferSize(), NULL, true);
01339 consumeWriteBuffer(writeBufferSize());
01340
01341
01342
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;
01356
01357
01358
01359 unsigned written = 0;
01360 unsigned offset = outBufIndex;
01361 while (writeBufferSize() - written > 0)
01362 {
01363
01364
01365
01366
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
01381 int wrote = KSocks::self()->write(sockfd, buf, count);
01382
01383 if (wrote == -1)
01384 {
01385
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
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
01415
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
01429
01430
01431
01432 retval = consumeReadBuffer(maxlen, data);
01433 if (retval == 0)
01434 {
01435
01436
01437 if (sockfd == -1)
01438 return 0;
01439 setError(IO_ReadError, EWOULDBLOCK);
01440 retval = -1;
01441 }
01442
01443
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;
01459
01460 int retval;
01461
01462 if ((d->flags & outputBufferedSocket) == 0)
01463 {
01464
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
01474
01475
01476
01477 register unsigned wsize = writeBufferSize();
01478 if (d->outMaxSize == (int)wsize)
01479 {
01480
01481 setError(IO_WriteError, EWOULDBLOCK);
01482 retval = -1;
01483 }
01484 else
01485 {
01486 if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
01487
01488 len = d->outMaxSize - wsize;
01489
01490
01491 retval = feedWriteBuffer(len, data);
01492 if (wsize == 0 || d->emitWrite)
01493
01494 d->qsnOut->setEnabled(true);
01495 }
01496
01497
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
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
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
01531
01532 if (d->flags & inputBufferedSocket)
01533 return KBufferedIO::bytesAvailable();
01534
01535 return 0;
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();
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
01583 void KExtendedSocket::enableRead(bool enable)
01584 {
01585
01586
01587
01588
01589 if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
01590 d->qsnIn->setEnabled(false);
01591 else if (enable && d->qsnIn)
01592
01593 d->qsnIn->setEnabled(true);
01594 d->emitRead = enable;
01595 }
01596
01597
01598 void KExtendedSocket::enableWrite(bool enable)
01599 {
01600
01601 if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
01602 d->qsnOut->setEnabled(false);
01603 else if (enable && d->qsnOut)
01604
01605 d->qsnOut->setEnabled(true);
01606 d->emitWrite = enable;
01607 }
01608
01609
01610
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
01627 if (d->flags & inputBufferedSocket)
01628 {
01629
01630 QByteArray a;
01631 char buf[1024];
01632 int len, totalread = 0;
01633
01634
01635
01636 unsigned cursize = readBufferSize();
01637
01638 if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
01639 {
01640 do
01641 {
01642
01643 if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
01644
01645
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
01654 a.resize(a.size() + len);
01655 memcpy(a.data() + totalread, buf, len);
01656 totalread += len;
01657 }
01658 else if (len == 0)
01659 {
01660
01661 ::close(sockfd);
01662 sockfd = -1;
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
01675 setError(IO_ReadError, errno);
01676 return;
01677 }
01678
01679 }
01680 while (len == sizeof(buf));
01681
01682 feedReadBuffer(a.size(), a.data());
01683 }
01684
01685
01686 }
01687 else
01688 {
01689
01690
01691
01692
01693
01694
01695 char c;
01696 int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
01697 if (len == 0)
01698 {
01699
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
01734 d->qsnOut->setEnabled(!empty);
01735 }
01736 if (d->status == closing && empty)
01737 {
01738
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
01751
01752
01753 void KExtendedSocket::connectionEvent()
01754 {
01755 if (d->status != connecting)
01756 return;
01757
01758 KResolverResults remote = d->resRemote.results();
01759 if (remote.count() == 0)
01760 {
01761
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
01771
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
01779
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
01793
01794
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
01807
01808 KResolverResults local = d->resLocal.results();
01809 unsigned localidx = 0;
01810 for ( ; d->current < remote.count(); d->current++)
01811 {
01812
01813 if (local.count() != 0)
01814 {
01815
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
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;
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
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
01879
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
01886 return;
01887 }
01888
01889
01890
01891
01892
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
01904 d->status = lookupDone;
01905 emit connectionFailed(errcode);
01906 }
01907
01908 void KExtendedSocket::dnsResultsReady()
01909 {
01910
01911 if (d->status != lookupInProgress)
01912 return;
01913
01914
01915 if (d->resRemote.isRunning() || d->resLocal.isRunning())
01916
01917 return;
01918
01919
01920
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
01980 if (!process_flags(userflags, socktype, familyMask, flags))
01981 return l;
01982
01983
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
01997
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());
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;
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
02038
02039
02040
02041 if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02042 return NULL;
02043
02044
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
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;
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
02078
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
02086
02087
02088
02089 if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02090 return NULL;
02091
02092
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
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;
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
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"