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
00989
00990
00991
00992
00993
00994 bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
00995 if (doingtimeout)
00996 {
00997 gettimeofday(&end, NULL);
00998 end.tv_usec += d->timeout.tv_usec;
00999 end.tv_sec += d->timeout.tv_sec;
01000 if (end.tv_usec > 1000*1000)
01001 {
01002 end.tv_usec -= 1000*1000;
01003 end.tv_sec++;
01004 }
01005
01006
01007 }
01008
01009 KResolverResults remote = d->resRemote.results(),
01010 local = d->resLocal.results();
01011 KResolverResults::const_iterator it, it2;
01012
01013
01014
01015 for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
01016 {
01017
01018 if (it2 != local.end())
01019 {
01020
01021 if ((*it).family() != (*it2).family())
01022
01023 for (it2 = local.begin(); it2 != local.end(); ++it2)
01024 if ((*it).family() == (*it2).family())
01025 break;
01026
01027 if ((*it).family() != (*it2).family())
01028 {
01029
01030
01031 it2 = local.begin();
01032 continue;
01033 }
01034
01035
01036 errno = 0;
01037 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01038 setError(IO_ConnectError, errno);
01039 if (sockfd == -1)
01040 continue;
01041 fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01042 if (d->addressReusable)
01043 setAddressReusable(sockfd, true);
01044 setIPv6Only(d->ipv6only);
01045 cleanError();
01046 if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
01047 {
01048
01049 ::close(sockfd);
01050 sockfd = -1;
01051 continue;
01052 }
01053 }
01054 else
01055 {
01056
01057 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
01058 if (sockfd == -1)
01059 {
01060 setError(IO_ConnectError, errno);
01061 continue;
01062 }
01063 fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01064 if (d->addressReusable)
01065 setAddressReusable(sockfd, true);
01066 setIPv6Only(d->ipv6only);
01067 cleanError();
01068 }
01069
01070
01071 d->status = created;
01072
01073
01074 if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
01075 {
01076 fd_set rd, wr;
01077
01078 setBlockingMode(false);
01079
01080
01081 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01082 {
01083
01084 if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01085 {
01086
01087 setError(IO_ConnectError, errno);
01088 ::close(sockfd);
01089 sockfd = -1;
01090 continue;
01091 }
01092
01093 FD_ZERO(&rd);
01094 FD_ZERO(&wr);
01095 FD_SET(sockfd, &rd);
01096 FD_SET(sockfd, &wr);
01097
01098 int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
01099 if (retval == -1)
01100 {
01101 setError(IO_FatalError, errno);
01102 continue;
01103 }
01104 else if (retval == 0)
01105 {
01106 ::close(sockfd);
01107 sockfd = -1;
01108
01109
01110 d->status = lookupDone;
01111 setError(IO_TimeOutError, 0);
01112 return -3;
01113 }
01114
01115
01116 gettimeofday(&now, NULL);
01117 d->timeout.tv_sec = end.tv_sec - now.tv_sec;
01118 d->timeout.tv_usec = end.tv_usec - now.tv_usec;
01119 if (d->timeout.tv_usec < 0)
01120 {
01121 d->timeout.tv_usec += 1000*1000;
01122 d->timeout.tv_sec--;
01123 }
01124
01125
01126
01127
01128 int errcode;
01129 socklen_t len = sizeof(errcode);
01130 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
01131 &len);
01132 if (retval == -1 || errcode != 0)
01133 {
01134
01135
01136
01137 ::close(sockfd);
01138 sockfd = -1;
01139
01140
01141 if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
01142 {
01143 d->status = lookupDone;
01144 setError(IO_TimeOutError, 0);
01145 return -3;
01146 }
01147
01148 setError(IO_ConnectError, errcode);
01149 continue;
01150 }
01151 }
01152
01153
01154
01155 setBlockingMode(true);
01156 d->status = connected;
01157 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01158 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01159 d->flags & outputBufferedSocket ? -1 : 0);
01160 emit connectionSuccess();
01161
01162 return 0;
01163 }
01164 else
01165 {
01166
01167 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
01168 {
01169
01170
01171 setError(IO_ConnectError, errno);
01172 ::close(sockfd);
01173 sockfd = -1;
01174 continue;
01175 }
01176
01177 d->status = connected;
01178 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01179 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01180 d->flags & outputBufferedSocket ? -1 : 0);
01181 emit connectionSuccess();
01182
01183 return 0;
01184 }
01185 }
01186
01187
01188 emit connectionFailed(d->syserror);
01189
01190 return -1;
01191 }
01192
01193 int KExtendedSocket::startAsyncConnect()
01194 {
01195 cleanError();
01196
01197 if (d->status >= connected || d->flags & passiveSocket)
01198 return -2;
01199
01200 if (d->status == connecting)
01201
01202 return 0;
01203
01204
01205
01206
01207 if (d->status < lookupDone)
01208 {
01209 QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01210 if (d->status < lookupInProgress)
01211 return startAsyncLookup();
01212 else
01213 return 0;
01214 }
01215
01216
01217
01218 d->status = connecting;
01219 QGuardedPtr<QObject> p = this;
01220 connectionEvent();
01221 if (!p)
01222 return -1;
01223 if (d->status < connecting)
01224 return -1;
01225 return 0;
01226 }
01227
01228 void KExtendedSocket::cancelAsyncConnect()
01229 {
01230 if (d->status != connecting)
01231 return;
01232
01233 if (sockfd != -1)
01234 {
01235
01236 if (d->qsnIn)
01237 delete d->qsnIn;
01238 if (d->qsnOut)
01239 delete d->qsnOut;
01240 d->qsnIn = d->qsnOut = NULL;
01241
01242 ::close(sockfd);
01243 sockfd = -1;
01244 }
01245 d->status = lookupDone;
01246 }
01247
01248 bool KExtendedSocket::open(int mode)
01249 {
01250 if (mode != IO_Raw | IO_ReadWrite)
01251 return false;
01252
01253 if (d->flags & passiveSocket)
01254 return listen() == 0;
01255 else if (d->status < connecting)
01256 return connect() == 0;
01257 else
01258 return false;
01259 }
01260
01261 void KExtendedSocket::close()
01262 {
01263 if (sockfd == -1 || d->status >= closing)
01264 return;
01265
01266
01267 if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
01268 {
01269
01270 d->status = closing;
01271 if (d->qsnIn)
01272 delete d->qsnIn;
01273 d->qsnIn = NULL;
01274
01275
01276 }
01277 else
01278 {
01279
01280
01281 if (d->qsnIn)
01282 delete d->qsnIn;
01283 if (d->qsnOut)
01284 delete d->qsnOut;
01285 d->qsnIn = d->qsnOut = NULL;
01286
01287 ::close(sockfd);
01288 d->status = done;
01289 emit closed(readBufferSize() != 0 ? availRead : 0);
01290 }
01291
01292 }
01293
01294
01295 void KExtendedSocket::closeNow()
01296 {
01297 if (d->status >= done)
01298 return;
01299
01300
01301 delete d->qsnIn;
01302 delete d->qsnOut;
01303 d->qsnIn = d->qsnOut = NULL;
01304
01305 if (d->status > connecting && sockfd != -1)
01306 {
01307 ::close(sockfd);
01308 sockfd = -1;
01309 }
01310 else if (d->status == connecting)
01311 cancelAsyncConnect();
01312 else if (d->status == lookupInProgress)
01313 cancelAsyncLookup();
01314
01315 d->status = done;
01316
01317 emit closed(closedNow |
01318 (readBufferSize() != 0 ? availRead : 0) |
01319 (writeBufferSize() != 0 ? dirtyWrite : 0));
01320 }
01321
01322 void KExtendedSocket::release()
01323 {
01324
01325 sockfd = -1;
01326 d->status = done;
01327
01328 d->resRemote.cancel(false);
01329 d->resLocal.cancel(false);
01330
01331 if (d->local != NULL)
01332 delete d->local;
01333 if (d->peer != NULL)
01334 delete d->peer;
01335
01336 d->peer = d->local = NULL;
01337
01338 if (d->qsnIn != NULL)
01339 delete d->qsnIn;
01340 if (d->qsnOut != NULL)
01341 delete d->qsnOut;
01342
01343 d->qsnIn = d->qsnOut = NULL;
01344
01345
01346 consumeReadBuffer(readBufferSize(), NULL, true);
01347 consumeWriteBuffer(writeBufferSize());
01348
01349
01350
01351 }
01352
01353 void KExtendedSocket::flush()
01354 {
01355 cleanError();
01356 if (d->status < connected || d->status >= done || d->flags & passiveSocket)
01357 return;
01358
01359 if (sockfd == -1)
01360 return;
01361
01362 if ((d->flags & outputBufferedSocket) == 0)
01363 return;
01364
01365
01366
01367 unsigned written = 0;
01368 unsigned offset = outBufIndex;
01369 while (writeBufferSize() - written > 0)
01370 {
01371
01372
01373
01374
01375
01376 QByteArray buf(16384);
01377 QByteArray *a = outBuf.first();
01378 unsigned count = 0;
01379
01380 while (a && count + (a->size() - offset) <= buf.size())
01381 {
01382 memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
01383 count += a->size() - offset;
01384 offset = 0;
01385 a = outBuf.next();
01386 }
01387
01388
01389 if (a && count < buf.size())
01390 {
01391
01392
01393 memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
01394 offset += buf.size() - count;
01395 count = buf.size();
01396 }
01397
01398
01399 int wrote = KSocks::self()->write(sockfd, buf, count);
01400
01401 if (wrote == -1)
01402 {
01403
01404 setError(IO_WriteError, errno);
01405 break;
01406 }
01407 written += wrote;
01408
01409 if ((unsigned)wrote != count)
01410 break;
01411 }
01412 if (written)
01413 {
01414 consumeWriteBuffer(written);
01415 emit bytesWritten(written);
01416 }
01417
01418
01419 }
01420
01421
01422 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen)
01423 {
01424 cleanError();
01425 if (d->status < connected || d->flags & passiveSocket)
01426 return -2;
01427
01428 int retval;
01429
01430 if ((d->flags & inputBufferedSocket) == 0)
01431 {
01432
01433
01434
01435 if (sockfd == -1)
01436 return -2;
01437 if (data)
01438 retval = KSocks::self()->read(sockfd, data, maxlen);
01439 else
01440 retval = skipData(sockfd, maxlen);
01441 if (retval == -1)
01442 setError(IO_ReadError, errno);
01443 }
01444 else
01445 {
01446
01447
01448
01449
01450 retval = consumeReadBuffer(maxlen, data);
01451 if (retval == 0)
01452 {
01453
01454
01455 if (sockfd == -1)
01456 return 0;
01457 setError(IO_ReadError, EWOULDBLOCK);
01458 retval = -1;
01459 }
01460
01461
01462
01463 }
01464 return retval;
01465 }
01466
01467 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len)
01468 {
01469 cleanError();
01470 if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
01471 return -2;
01472 if (sockfd == -1)
01473 return -2;
01474
01475 if (len == 0)
01476 return 0;
01477
01478 int retval;
01479
01480 if ((d->flags & outputBufferedSocket) == 0)
01481 {
01482
01483 retval = KSocks::self()->write(sockfd, data, len);
01484 if (retval == -1)
01485 setError(IO_WriteError, errno);
01486 else
01487 emit bytesWritten(retval);
01488 }
01489 else
01490 {
01491
01492
01493
01494
01495 register unsigned wsize = writeBufferSize();
01496 if (d->outMaxSize == (int)wsize)
01497 {
01498
01499 setError(IO_WriteError, EWOULDBLOCK);
01500 retval = -1;
01501 }
01502 else
01503 {
01504 if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
01505
01506 len = d->outMaxSize - wsize;
01507
01508
01509 retval = feedWriteBuffer(len, data);
01510 if (wsize == 0 || d->emitWrite)
01511
01512 d->qsnOut->setEnabled(true);
01513 }
01514
01515
01516 }
01517
01518 return retval;
01519 }
01520
01521 int KExtendedSocket::peekBlock(char *data, uint maxlen)
01522 {
01523 if (d->status < connected || d->flags & passiveSocket)
01524 return -2;
01525 if (sockfd == -1)
01526 return -2;
01527
01528
01529
01530 if (d->flags & inputBufferedSocket)
01531 return consumeReadBuffer(maxlen, data, false);
01532
01533 return 0;
01534 }
01535
01536 int KExtendedSocket::unreadBlock(const char *, uint)
01537 {
01538
01539 setError(IO_ReadError, ENOSYS);
01540 return -1;
01541 }
01542
01543 int KExtendedSocket::bytesAvailable() const
01544 {
01545 if (d->status < connected || d->flags & passiveSocket)
01546 return -2;
01547
01548
01549
01550 if (d->flags & inputBufferedSocket)
01551 return KBufferedIO::bytesAvailable();
01552
01553 return 0;
01554 }
01555
01556 int KExtendedSocket::waitForMore(int msecs)
01557 {
01558 cleanError();
01559 if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
01560 return -2;
01561 if (sockfd == -1)
01562 return -2;
01563
01564 fd_set rd;
01565 FD_ZERO(&rd);
01566 FD_SET(sockfd, &rd);
01567 timeval tv;
01568 tv.tv_sec = msecs / 1000;
01569 tv.tv_usec = (msecs % 1000) * 1000;
01570
01571 int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
01572 if (retval == -1)
01573 {
01574 setError(IO_FatalError, errno);
01575 return -1;
01576 }
01577 else if (retval != 0)
01578 socketActivityRead();
01579
01580 return bytesAvailable();
01581 }
01582
01583 int KExtendedSocket::getch()
01584 {
01585 unsigned char c;
01586 int retval;
01587 retval = readBlock((char*)&c, sizeof(c));
01588
01589 if (retval < 0)
01590 return retval;
01591 return c;
01592 }
01593
01594 int KExtendedSocket::putch(int ch)
01595 {
01596 unsigned char c = (char)ch;
01597 return writeBlock((char*)&c, sizeof(c));
01598 }
01599
01600
01601 void KExtendedSocket::enableRead(bool enable)
01602 {
01603
01604
01605
01606
01607 if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
01608 d->qsnIn->setEnabled(false);
01609 else if (enable && d->qsnIn)
01610
01611 d->qsnIn->setEnabled(true);
01612 d->emitRead = enable;
01613 }
01614
01615
01616 void KExtendedSocket::enableWrite(bool enable)
01617 {
01618
01619 if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
01620 d->qsnOut->setEnabled(false);
01621 else if (enable && d->qsnOut)
01622
01623 d->qsnOut->setEnabled(true);
01624 d->emitWrite = enable;
01625 }
01626
01627
01628
01629 void KExtendedSocket::socketActivityRead()
01630 {
01631 if (d->flags & passiveSocket)
01632 {
01633 emit readyAccept();
01634 return;
01635 }
01636 if (d->status == connecting)
01637 {
01638 connectionEvent();
01639 return;
01640 }
01641 if (d->status != connected)
01642 return;
01643
01644
01645 if (d->flags & inputBufferedSocket)
01646 {
01647
01648 QByteArray a;
01649 char buf[1024];
01650 int len, totalread = 0;
01651
01652
01653
01654 unsigned cursize = readBufferSize();
01655
01656 if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
01657 {
01658 do
01659 {
01660
01661 if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
01662
01663
01664 len = d->inMaxSize - (cursize + totalread);
01665 else
01666 len = sizeof(buf);
01667
01668 len = KSocks::self()->read(sockfd, buf, len);
01669 if (len > 0)
01670 {
01671
01672 a.resize(a.size() + len);
01673 memcpy(a.data() + totalread, buf, len);
01674 totalread += len;
01675 }
01676 else if (len == 0)
01677 {
01678
01679 ::close(sockfd);
01680 sockfd = -1;
01681 d->qsnIn->deleteLater();
01682 delete d->qsnOut;
01683 d->qsnIn = d->qsnOut = NULL;
01684 d->status = done;
01685 emit closed(involuntary |
01686 (readBufferSize() ? availRead : 0) |
01687 (writeBufferSize() ? dirtyWrite : 0));
01688 return;
01689 }
01690 else
01691 {
01692
01693 setError(IO_ReadError, errno);
01694 return;
01695 }
01696
01697 }
01698 while (len == sizeof(buf));
01699
01700 feedReadBuffer(a.size(), a.data());
01701 }
01702
01703
01704 }
01705 else
01706 {
01707
01708
01709
01710
01711
01712
01713 char c;
01714 int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
01715 if (len == 0)
01716 {
01717
01718 d->qsnIn->setEnabled(false);
01719 ::close(sockfd);
01720 sockfd = -1;
01721 d->status = done;
01722 emit closed(involuntary);
01723 return;
01724 }
01725 }
01726
01727 if (d->emitRead)
01728 emit readyRead();
01729 }
01730
01731 void KExtendedSocket::socketActivityWrite()
01732 {
01733 if (d->flags & passiveSocket)
01734 return;
01735 if (d->status == connecting)
01736 {
01737 connectionEvent();
01738 return;
01739 }
01740 if (d->status != connected && d->status != closing)
01741 return;
01742
01743 flush();
01744
01745 bool empty = writeBufferSize() == 0;
01746
01747 if (d->emitWrite && empty)
01748 emit readyWrite();
01749 else if (!d->emitWrite)
01750 {
01751
01752 d->qsnOut->setEnabled(!empty);
01753 }
01754 if (d->status == closing && empty)
01755 {
01756
01757 d->status = done;
01758
01759 delete d->qsnOut;
01760 ::close(sockfd);
01761
01762 d->qsnOut = NULL;
01763 sockfd = -1;
01764 emit closed(delayed | (readBufferSize() ? availRead : 0));
01765 }
01766 }
01767
01768
01769
01770
01771 void KExtendedSocket::connectionEvent()
01772 {
01773 if (d->status != connecting)
01774 return;
01775
01776 KResolverResults remote = d->resRemote.results();
01777 if (remote.count() == 0)
01778 {
01779
01780 kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
01781 return;
01782 }
01783
01784 int errcode = 0;
01785
01786 if (sockfd != -1)
01787 {
01788
01789
01790 int retval;
01791 socklen_t len = sizeof(errcode);
01792 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
01793
01794 if (retval == -1 || errcode != 0)
01795 {
01796
01797
01798 if (d->qsnIn)
01799 delete d->qsnIn;
01800 if (d->qsnOut)
01801 delete d->qsnOut;
01802 ::close(sockfd);
01803
01804 sockfd = -1;
01805 d->qsnIn = d->qsnOut = NULL;
01806 d->current++;
01807 setError(IO_ConnectError, errcode);
01808 }
01809 else
01810 {
01811
01812
01813
01814 cleanError();
01815 d->status = connected;
01816 setBlockingMode(true);
01817 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01818 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01819 d->flags & outputBufferedSocket ? -1 : 0);
01820 emit connectionSuccess();
01821 return;
01822 }
01823 }
01824
01825
01826
01827 KResolverResults local = d->resLocal.results();
01828 unsigned localidx = 0;
01829 for ( ; d->current < remote.count(); d->current++)
01830 {
01831
01832 if (local.count() != 0)
01833 {
01834
01835 for (localidx = 0; localidx < local.count(); localidx++)
01836 if (remote[d->current].family() == local[localidx].family())
01837 break;
01838
01839 if (remote[d->current].family() != local[localidx].family())
01840 {
01841
01842 continue;
01843 }
01844
01845 errno = 0;
01846 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01847 remote[d->current].protocol());
01848 setError(IO_ConnectError, errno);
01849 errcode = errno;
01850 if (sockfd == -1)
01851 continue;
01852 fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01853 if (d->addressReusable)
01854 setAddressReusable(sockfd, true);
01855 setIPv6Only(d->ipv6only);
01856 cleanError();
01857 if (KSocks::self()->bind(sockfd, local[localidx].address(),
01858 local[localidx].length()) == -1)
01859 {
01860 ::close(sockfd);
01861 sockfd = -1;
01862 continue;
01863 }
01864 }
01865 else
01866 {
01867
01868 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
01869 remote[d->current].protocol());
01870 if (sockfd == -1)
01871 {
01872 setError(IO_ConnectError, errno);
01873 errcode = errno;
01874 continue;
01875 }
01876 fcntl(sockfd, F_SETFD, FD_CLOEXEC);
01877 if (d->addressReusable)
01878 setAddressReusable(sockfd, true);
01879 setIPv6Only(d->ipv6only);
01880 cleanError();
01881 }
01882
01883 if (KSocks::self()->hasWorkingAsyncConnect())
01884 setBlockingMode(false);
01885 if (KSocks::self()->connect(sockfd, remote[d->current].address(),
01886 remote[d->current].length()) == -1)
01887 {
01888 if (errno != EWOULDBLOCK && errno != EINPROGRESS)
01889 {
01890 setError(IO_ConnectError, errno);
01891 ::close(sockfd);
01892 sockfd = -1;
01893 errcode = errno;
01894 continue;
01895 }
01896
01897
01898
01899 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read);
01900 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead()));
01901 d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write);
01902 QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite()));
01903
01904
01905 return;
01906 }
01907
01908
01909
01910
01911
01912 cleanError();
01913 d->status = connected;
01914 setBlockingMode(true);
01915 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
01916 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
01917 d->flags & outputBufferedSocket ? -1 : 0);
01918 emit connectionSuccess();
01919 return;
01920 }
01921
01922
01923 d->status = lookupDone;
01924 emit connectionFailed(errcode);
01925 }
01926
01927 void KExtendedSocket::dnsResultsReady()
01928 {
01929
01930 if (d->status != lookupInProgress)
01931 return;
01932
01933
01934 if (d->resRemote.isRunning() || d->resLocal.isRunning())
01935
01936 return;
01937
01938
01939
01940 int n = d->resRemote.results().count() + d->resLocal.results().count();
01941
01942 if (n)
01943 {
01944 d->status = lookupDone;
01945 cleanError();
01946 }
01947 else
01948 {
01949 d->status = nothing;
01950 setError(IO_LookupError, KResolver::NoName);
01951 }
01952
01953 emit lookupFinished(n);
01954
01955 return;
01956 }
01957
01958 void KExtendedSocket::startAsyncConnectSlot()
01959 {
01960 QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot()));
01961
01962 if (d->status == lookupDone)
01963 startAsyncConnect();
01964 }
01965
01966 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host,
01967 QString &port, int flags)
01968 {
01969 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01970
01971 int err;
01972 char h[NI_MAXHOST], s[NI_MAXSERV];
01973
01974 h[0] = s[0] = '\0';
01975
01976 err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
01977 host = QString::fromUtf8(h);
01978 port = QString::fromUtf8(s);
01979
01980 return err;
01981 }
01982
01983 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port,
01984 int flags)
01985 {
01986 return resolve(sock->data, sock->datasize, host, port, flags);
01987 }
01988
01989 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port,
01990 int userflags, int *error)
01991 {
01992 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
01993
01994 int socktype, familyMask, flags;
01995 unsigned i;
01996 QPtrList<KAddressInfo> l;
01997
01998
01999 if (!process_flags(userflags, socktype, familyMask, flags))
02000 return l;
02001
02002
02003 KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
02004 if (res.error())
02005 {
02006 if (error)
02007 *error = res.error();
02008 return l;
02009 }
02010
02011 for (i = 0; i < res.count(); i++)
02012 {
02013 KAddressInfo *ai = new KAddressInfo();
02014
02015
02016
02017 ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
02018 memset(ai->ai, 0, sizeof(addrinfo));
02019
02020 ai->ai->ai_family = res[i].family();
02021 ai->ai->ai_socktype = res[i].socketType();
02022 ai->ai->ai_protocol = res[i].protocol();
02023 QString canon = res[i].canonicalName();
02024 if (!canon.isEmpty())
02025 {
02026 ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
02027 strcpy(ai->ai->ai_canonname, canon.ascii());
02028 }
02029 if ((ai->ai->ai_addrlen = res[i].length()))
02030 {
02031 ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
02032 memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
02033 }
02034 else
02035 {
02036 ai->ai->ai_addr = 0;
02037 }
02038
02039 ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
02040
02041 l.append(ai);
02042 }
02043
02044 if ( error )
02045 *error = 0;
02046
02047 return l;
02048 }
02049
02050 ::KSocketAddress *KExtendedSocket::localAddress(int fd)
02051 {
02052 ::KSocketAddress *local;
02053 struct sockaddr static_sa, *sa = &static_sa;
02054 ksocklen_t len = sizeof(static_sa);
02055
02056
02057
02058
02059
02060 if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02061 return NULL;
02062
02063
02064 if (len > sizeof(static_sa)
02065 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02066 || sa->sa_len > sizeof(static_sa)
02067 #endif
02068 )
02069 {
02070
02071
02072 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02073 if (sa->sa_len != len)
02074 len = sa->sa_len;
02075 #endif
02076
02077 sa = (sockaddr*)malloc(len);
02078 if (sa == NULL)
02079 return NULL;
02080
02081 if (KSocks::self()->getsockname(fd, sa, &len) == -1)
02082 {
02083 free(sa);
02084 return NULL;
02085 }
02086
02087 local = ::KSocketAddress::newAddress(sa, len);
02088 free(sa);
02089 }
02090 else
02091 local = ::KSocketAddress::newAddress(sa, len);
02092
02093 return local;
02094 }
02095
02096
02097
02098 ::KSocketAddress *KExtendedSocket::peerAddress(int fd)
02099 {
02100 ::KSocketAddress *peer;
02101 struct sockaddr static_sa, *sa = &static_sa;
02102 ksocklen_t len = sizeof(static_sa);
02103
02104
02105
02106
02107
02108 if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02109 return NULL;
02110
02111
02112 if (len > sizeof(static_sa)
02113 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02114 || sa->sa_len > sizeof(static_sa)
02115 #endif
02116 )
02117 {
02118
02119
02120 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
02121 if (sa->sa_len != len)
02122 len = sa->sa_len;
02123 #endif
02124
02125 sa = (sockaddr*)malloc(len);
02126 if (sa == NULL)
02127 return NULL;
02128
02129 if (KSocks::self()->getpeername(fd, sa, &len) == -1)
02130 {
02131 free(sa);
02132 return NULL;
02133 }
02134
02135 peer = ::KSocketAddress::newAddress(sa, len);
02136 free(sa);
02137 }
02138 else
02139 peer = ::KSocketAddress::newAddress(sa, len);
02140
02141 return peer;
02142 }
02143
02144 QString KExtendedSocket::strError(int code, int syserr)
02145 {
02146 const char * msg;
02147 if (code == IO_LookupError)
02148 msg = gai_strerror(syserr);
02149 else
02150 msg = strerror(syserr);
02151
02152 return QString::fromLocal8Bit(msg);
02153 }
02154
02155
02156 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
02157 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
02158
02159
02160
02161
02162
02163 #if 0
02164 KAddressInfo::KAddressInfo(addrinfo *p)
02165 {
02166 ai = (addrinfo *) malloc(sizeof(addrinfo));
02167 memcpy(ai, p, sizeof(addrinfo));
02168 ai->ai_next = NULL;
02169 if (p->ai_canonname)
02170 {
02171 ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
02172 strcpy(ai->ai_canonname, p->ai_canonname);
02173 }
02174 if (p->ai_addr && p->ai_addrlen)
02175 {
02176 ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
02177 memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
02178 }
02179 else
02180 {
02181 ai->ai_addr = 0;
02182 ai->ai_addrlen = 0;
02183 }
02184
02185 addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
02186 }
02187 #endif
02188 KAddressInfo::~KAddressInfo()
02189 {
02190 if (ai && ai->ai_canonname)
02191 free(ai->ai_canonname);
02192
02193 if (ai && ai->ai_addr)
02194 free(ai->ai_addr);
02195
02196 if (ai)
02197 free(ai);
02198 delete addr;
02199 }
02200
02201 int KAddressInfo::flags() const
02202 {
02203 return ai->ai_flags;
02204 }
02205
02206 int KAddressInfo::family() const
02207 {
02208 return ai->ai_family;
02209 }
02210
02211 int KAddressInfo::socktype() const
02212 {
02213 return ai->ai_socktype;
02214 }
02215
02216 int KAddressInfo::protocol() const
02217 {
02218 return ai->ai_protocol;
02219 }
02220
02221 const char* KAddressInfo::canonname() const
02222 {
02223 return ai->ai_canonname;
02224 }
02225
02226 void KExtendedSocket::virtual_hook( int id, void* data )
02227 { KBufferedIO::virtual_hook( id, data ); }
02228
02229 #include "kextsock.moc"