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