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