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