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