00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include <config.h>
00026
00027
#include <qmap.h>
00028
00029
#ifdef USE_SOLARIS
00030
# include <sys/filio.h>
00031
#endif
00032
#include <sys/types.h>
00033
#include <sys/socket.h>
00034
#include <sys/time.h>
00035
#include <sys/ioctl.h>
00036
#include <errno.h>
00037
#include <fcntl.h>
00038
#include <netinet/in.h>
00039
#include <unistd.h>
00040
00041
#ifdef HAVE_POLL
00042
# include <sys/poll.h>
00043
#else
00044
# ifdef HAVE_SYS_SELECT
00045
# include <sys/select.h>
00046
# endif
00047
#endif
00048
00049
00050
#include "syssocket.h"
00051
00052
#include <qmutex.h>
00053
#include <qsocketnotifier.h>
00054
00055
#include "kresolver.h"
00056
#include "ksocketaddress.h"
00057
#include "ksocketbase.h"
00058
#include "ksocketdevice.h"
00059
#include "ksockssocketdevice.h"
00060
00061
using namespace KNetwork;
00062
00063
class KNetwork::KSocketDevicePrivate
00064 {
00065
public:
00066
mutable QSocketNotifier *input, *output, *exception;
00067
int af;
00068
00069
inline KSocketDevicePrivate()
00070 {
00071 input = output = exception = 0L;
00072 }
00073 };
00074
00075
00076 KSocketDevice::KSocketDevice(
const KSocketBase* parent)
00077 : m_sockfd(-1), d(new KSocketDevicePrivate)
00078 {
00079
setSocketDevice(
this);
00080
if (parent)
00081
setSocketOptions(parent->
socketOptions());
00082 }
00083
00084 KSocketDevice::KSocketDevice(
int fd)
00085 : m_sockfd(fd), d(new KSocketDevicePrivate)
00086 {
00087 setState(IO_Open);
00088 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00089
setSocketDevice(
this);
00090 }
00091
00092 KSocketDevice::KSocketDevice(
bool,
const KSocketBase* parent)
00093 : m_sockfd(-1), d(new KSocketDevicePrivate)
00094 {
00095
00096
if (parent)
00097
setSocketOptions(parent->
socketOptions());
00098 }
00099
00100 KSocketDevice::~KSocketDevice()
00101 {
00102
close();
00103 unsetSocketDevice();
00104
delete d;
00105 }
00106
00107 bool KSocketDevice::setSocketOptions(
int opts)
00108 {
00109
00110
QMutexLocker locker(
mutex());
00111
KSocketBase::setSocketOptions(opts);
00112
00113
if (
m_sockfd == -1)
00114
return true;
00115
00116 {
00117
int fdflags = fcntl(
m_sockfd, F_GETFL, 0);
00118
if (fdflags == -1)
00119 {
00120
setError(IO_UnspecifiedError, UnknownError);
00121
return false;
00122 }
00123
00124
if (opts & Blocking)
00125 fdflags &= ~O_NONBLOCK;
00126
else
00127 fdflags |= O_NONBLOCK;
00128
00129
if (fcntl(
m_sockfd, F_SETFL, fdflags) == -1)
00130 {
00131
setError(IO_UnspecifiedError, UnknownError);
00132
return false;
00133 }
00134 }
00135
00136 {
00137
int on = opts & AddressReuseable ? 1 : 0;
00138
if (setsockopt(
m_sockfd, SOL_SOCKET, SO_REUSEADDR, (
char*)&on,
sizeof(on)) == -1)
00139 {
00140
setError(IO_UnspecifiedError, UnknownError);
00141
return false;
00142 }
00143 }
00144
00145
#if defined(IPV6_V6ONLY) && defined(AF_INET6)
00146
if (d->af == AF_INET6)
00147 {
00148
00149
00150
int on = opts & IPv6Only ? 1 : 0;
00151
if (setsockopt(
m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (
char*)&on,
sizeof(on)) == -1)
00152 {
00153
setError(IO_UnspecifiedError, UnknownError);
00154
return false;
00155 }
00156 }
00157
#endif
00158
00159 {
00160
int on = opts & Broadcast ? 1 : 0;
00161
if (setsockopt(
m_sockfd, SOL_SOCKET, SO_BROADCAST, (
char*)&on,
sizeof(on)) == -1)
00162 {
00163
setError(IO_UnspecifiedError, UnknownError);
00164
return false;
00165 }
00166 }
00167
00168
return true;
00169 }
00170
00171 bool KSocketDevice::open(
int)
00172 {
00173
resetError();
00174
return false;
00175 }
00176
00177 void KSocketDevice::close()
00178 {
00179
resetError();
00180
if (
m_sockfd != -1)
00181 {
00182
delete d->input;
00183
delete d->output;
00184
delete d->exception;
00185
00186 d->input = d->output = d->exception = 0L;
00187
00188 ::close(
m_sockfd);
00189 }
00190 setState(0);
00191
00192
m_sockfd = -1;
00193 }
00194
00195 bool KSocketDevice::create(
int family,
int type,
int protocol)
00196 {
00197
resetError();
00198
00199
if (
m_sockfd != -1)
00200 {
00201
00202
setError(IO_SocketCreateError, AlreadyCreated);
00203
return false;
00204 }
00205
00206
00207
m_sockfd = kde_socket(family, type, protocol);
00208
00209
if (
m_sockfd == -1)
00210 {
00211
setError(IO_SocketCreateError, NotSupported);
00212
return false;
00213 }
00214
00215 d->af = family;
00216
setSocketOptions(
socketOptions());
00217
return true;
00218 }
00219
00220 bool KSocketDevice::create(
const KResolverEntry& address)
00221 {
00222
return create(address.
family(), address.
socketType(), address.
protocol());
00223 }
00224
00225 bool KSocketDevice::bind(
const KResolverEntry& address)
00226 {
00227
resetError();
00228
00229
if (
m_sockfd == -1 && !
create(address))
00230
return false;
00231
00232
00233
if (kde_bind(
m_sockfd, address.
address(), address.
length()) == -1)
00234 {
00235
if (errno == EADDRINUSE)
00236
setError(IO_BindError, AddressInUse);
00237
else if (errno == EINVAL)
00238
setError(IO_BindError, AlreadyBound);
00239
else
00240
00241
setError(IO_BindError, NotSupported);
00242
return false;
00243 }
00244
00245
return true;
00246 }
00247
00248 bool KSocketDevice::listen(
int backlog)
00249 {
00250
if (
m_sockfd != -1)
00251 {
00252
if (kde_listen(
m_sockfd, backlog) == -1)
00253 {
00254
setError(IO_ListenError, NotSupported);
00255
return false;
00256 }
00257
00258
resetError();
00259 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00260 setState(IO_Open);
00261
return true;
00262 }
00263
00264
00265
00266
setError(IO_ListenError, NotCreated);
00267
return false;
00268 }
00269
00270 bool KSocketDevice::connect(
const KResolverEntry& address)
00271 {
00272
resetError();
00273
00274
if (
m_sockfd == -1 && !
create(address))
00275
return false;
00276
00277
if (kde_connect(
m_sockfd, address.
address(), address.
length()) == -1)
00278 {
00279
if (errno == EISCONN)
00280
return true;
00281
else if (errno == EALREADY || errno == EINPROGRESS)
00282 {
00283
setError(IO_ConnectError, InProgress);
00284
return true;
00285 }
00286
else if (errno == ECONNREFUSED)
00287
setError(IO_ConnectError, ConnectionRefused);
00288
else if (errno == ENETDOWN || errno == ENETUNREACH ||
00289 errno == ENETRESET || errno == ECONNABORTED ||
00290 errno == ECONNRESET || errno == EHOSTDOWN ||
00291 errno == EHOSTUNREACH)
00292
setError(IO_ConnectError, NetFailure);
00293
else
00294
setError(IO_ConnectError, NotSupported);
00295
00296
return false;
00297 }
00298
00299 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00300 setState(IO_Open);
00301
return true;
00302 }
00303
00304 KSocketDevice*
KSocketDevice::accept()
00305 {
00306
if (
m_sockfd == -1)
00307 {
00308
00309
setError(IO_AcceptError, NotCreated);
00310
return 0L;
00311 }
00312
00313
struct sockaddr sa;
00314 socklen_t len =
sizeof(sa);
00315
int newfd = kde_accept(
m_sockfd, &sa, &len);
00316
if (newfd == -1)
00317 {
00318
if (errno == EAGAIN || errno == EWOULDBLOCK)
00319
setError(IO_AcceptError, WouldBlock);
00320
else
00321
setError(IO_AcceptError, UnknownError);
00322
return NULL;
00323 }
00324
00325
return new KSocketDevice(newfd);
00326 }
00327
00328 bool KSocketDevice::disconnect()
00329 {
00330
resetError();
00331
00332
if (
m_sockfd == -1)
00333
return false;
00334
00335
KSocketAddress address;
00336 address.
setFamily(AF_UNSPEC);
00337
if (kde_connect(
m_sockfd, address.
address(), address.
length()) == -1)
00338 {
00339
if (errno == EALREADY || errno == EINPROGRESS)
00340 {
00341
setError(IO_ConnectError, InProgress);
00342
return false;
00343 }
00344
else if (errno == ECONNREFUSED)
00345
setError(IO_ConnectError, ConnectionRefused);
00346
else if (errno == ENETDOWN || errno == ENETUNREACH ||
00347 errno == ENETRESET || errno == ECONNABORTED ||
00348 errno == ECONNRESET || errno == EHOSTDOWN ||
00349 errno == EHOSTUNREACH)
00350
setError(IO_ConnectError, NetFailure);
00351
else
00352
setError(IO_ConnectError, NotSupported);
00353
00354
return false;
00355 }
00356
00357 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00358 setState(IO_Open);
00359
return true;
00360 }
00361
00362 Q_LONG
KSocketDevice::bytesAvailable()
const
00363
{
00364
if (
m_sockfd == -1)
00365
return -1;
00366
00367
int nchars;
00368
if (ioctl(
m_sockfd, FIONREAD, &nchars) == -1)
00369
return -1;
00370
00371
return nchars;
00372 }
00373
00374 Q_LONG
KSocketDevice::waitForMore(
int msecs,
bool *timeout)
00375 {
00376
if (
m_sockfd == -1)
00377
return -1;
00378
00379
bool input;
00380
if (!
poll(&input, 0, 0, msecs, timeout))
00381
return -1;
00382
00383
return bytesAvailable();
00384 }
00385
00386
static int do_read_common(
int sockfd,
char *data, Q_ULONG maxlen,
KSocketAddress* from, ssize_t &retval,
bool peek =
false)
00387 {
00388 socklen_t len;
00389
if (from)
00390 {
00391 from->
setLength(len = 128);
00392 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->
address(), &len);
00393 }
00394
else
00395 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
00396
00397
if (retval == -1)
00398 {
00399
if (errno == EAGAIN || errno == EWOULDBLOCK)
00400
return KSocketDevice::WouldBlock;
00401
else
00402
return KSocketDevice::UnknownError;
00403 }
00404
00405
if (from)
00406 from->
setLength(len);
00407
return 0;
00408 }
00409
00410 Q_LONG
KSocketDevice::readBlock(
char *data, Q_ULONG maxlen)
00411 {
00412
resetError();
00413
if (
m_sockfd == -1)
00414
return -1;
00415
00416
if (maxlen == 0 || data == 0L)
00417
return 0;
00418
00419 ssize_t retval;
00420
int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval);
00421
00422
if (err)
00423 {
00424
setError(IO_ReadError, static_cast<SocketError>(err));
00425
return -1;
00426 }
00427
00428
return retval;
00429 }
00430
00431 Q_LONG
KSocketDevice::readBlock(
char *data, Q_ULONG maxlen,
KSocketAddress &from)
00432 {
00433
resetError();
00434
if (
m_sockfd == -1)
00435
return -1;
00436
00437
if (data == 0L || maxlen == 0)
00438
return 0;
00439
00440 ssize_t retval;
00441
int err = do_read_common(
m_sockfd, data, maxlen, &from, retval);
00442
00443
if (err)
00444 {
00445
setError(IO_ReadError, static_cast<SocketError>(err));
00446
return -1;
00447 }
00448
00449
return retval;
00450 }
00451
00452 Q_LONG
KSocketDevice::peekBlock(
char *data, Q_ULONG maxlen)
00453 {
00454
resetError();
00455
if (
m_sockfd == -1)
00456
return -1;
00457
00458
if (maxlen == 0 || data == 0L)
00459
return 0;
00460
00461 ssize_t retval;
00462
int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval,
true);
00463
00464
if (err)
00465 {
00466
setError(IO_ReadError, static_cast<SocketError>(err));
00467
return -1;
00468 }
00469
00470
return retval;
00471 }
00472
00473 Q_LONG
KSocketDevice::peekBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00474 {
00475
resetError();
00476
if (
m_sockfd == -1)
00477
return -1;
00478
00479
if (data == 0L || maxlen == 0)
00480
return 0;
00481
00482 ssize_t retval;
00483
int err = do_read_common(
m_sockfd, data, maxlen, &from, retval,
true);
00484
00485
if (err)
00486 {
00487
setError(IO_ReadError, static_cast<SocketError>(err));
00488
return -1;
00489 }
00490
00491
return retval;
00492 }
00493
00494 Q_LONG
KSocketDevice::writeBlock(
const char *data, Q_ULONG len)
00495 {
00496
return writeBlock(data, len,
KSocketAddress());
00497 }
00498
00499 Q_LONG
KSocketDevice::writeBlock(
const char *data, Q_ULONG len,
const KSocketAddress& to)
00500 {
00501
resetError();
00502
if (
m_sockfd == -1)
00503
return -1;
00504
00505
if (data == 0L || len == 0)
00506
return 0;
00507
00508 ssize_t retval = ::sendto(
m_sockfd, data, len, 0, to.
address(), to.
length());
00509
if (retval == -1)
00510 {
00511
if (errno == EAGAIN || errno == EWOULDBLOCK)
00512
setError(IO_WriteError, WouldBlock);
00513
else
00514
setError(IO_WriteError, UnknownError);
00515
return -1;
00516 }
00517
00518
return retval;
00519 }
00520
00521 KSocketAddress KSocketDevice::localAddress()
const
00522
{
00523
if (
m_sockfd == -1)
00524
return KSocketAddress();
00525
00526 socklen_t len;
00527
KSocketAddress localAddress;
00528 localAddress.
setLength(len = 32);
00529
if (kde_getsockname(
m_sockfd, localAddress.
address(), &len) == -1)
00530
00531
return KSocketAddress();
00532
00533
if (len <= localAddress.
length())
00534 {
00535
00536 localAddress.
setLength(len);
00537
return localAddress;
00538 }
00539
00540
00541
00542 localAddress.
setLength(len);
00543
if (kde_getsockname(
m_sockfd, localAddress.
address(), &len) == -1)
00544
00545
return KSocketAddress();
00546
00547
return localAddress;
00548 }
00549
00550 KSocketAddress KSocketDevice::peerAddress()
const
00551
{
00552
if (
m_sockfd == -1)
00553
return KSocketAddress();
00554
00555 socklen_t len;
00556
KSocketAddress peerAddress;
00557 peerAddress.
setLength(len = 32);
00558
if (kde_getpeername(
m_sockfd, peerAddress.
address(), &len) == -1)
00559
00560
return KSocketAddress();
00561
00562
if (len <= peerAddress.
length())
00563 {
00564
00565 peerAddress.
setLength(len);
00566
return peerAddress;
00567 }
00568
00569
00570
00571 peerAddress.
setLength(len);
00572
if (kde_getpeername(
m_sockfd, peerAddress.
address(), &len) == -1)
00573
00574
return KSocketAddress();
00575
00576
return peerAddress;
00577 }
00578
00579 KSocketAddress KSocketDevice::externalAddress()
const
00580
{
00581
00582
00583
return localAddress();
00584 }
00585
00586 QSocketNotifier*
KSocketDevice::readNotifier()
const
00587
{
00588
if (d->input)
00589
return d->input;
00590
00591
QMutexLocker locker(
mutex());
00592
if (d->input)
00593
return d->input;
00594
00595
if (
m_sockfd == -1)
00596 {
00597
00598
return 0L;
00599 }
00600
00601
return d->input =
createNotifier(QSocketNotifier::Read);
00602 }
00603
00604 QSocketNotifier*
KSocketDevice::writeNotifier()
const
00605
{
00606
if (d->output)
00607
return d->output;
00608
00609
QMutexLocker locker(
mutex());
00610
if (d->output)
00611
return d->output;
00612
00613
if (
m_sockfd == -1)
00614 {
00615
00616
return 0L;
00617 }
00618
00619
return d->output =
createNotifier(QSocketNotifier::Write);
00620 }
00621
00622 QSocketNotifier*
KSocketDevice::exceptionNotifier()
const
00623
{
00624
if (d->exception)
00625
return d->exception;
00626
00627
QMutexLocker locker(
mutex());
00628
if (d->exception)
00629
return d->exception;
00630
00631
if (
m_sockfd == -1)
00632 {
00633
00634
return 0L;
00635 }
00636
00637
return d->exception =
createNotifier(QSocketNotifier::Exception);
00638 }
00639
00640 bool KSocketDevice::poll(
bool *input,
bool *output,
bool *exception,
00641
int timeout,
bool* timedout)
00642 {
00643
if (
m_sockfd == -1)
00644 {
00645
setError(IO_UnspecifiedError, NotCreated);
00646
return false;
00647 }
00648
00649
resetError();
00650
#ifdef HAVE_POLL
00651
struct pollfd fds;
00652 fds.fd =
m_sockfd;
00653 fds.events = 0;
00654
00655
if (input)
00656 {
00657 fds.events |= POLLIN;
00658 *input =
false;
00659 }
00660
if (output)
00661 {
00662 fds.events |= POLLOUT;
00663 *output =
false;
00664 }
00665
if (exception)
00666 {
00667 fds.events |= POLLPRI;
00668 *exception =
false;
00669 }
00670
00671
int retval = ::poll(&fds, 1, timeout);
00672
if (retval == -1)
00673 {
00674
setError(IO_UnspecifiedError, UnknownError);
00675
return false;
00676 }
00677
if (retval == 0)
00678 {
00679
00680
if (timedout)
00681 *timedout =
true;
00682
return true;
00683 }
00684
00685
if (input && fds.revents & POLLIN)
00686 *input =
true;
00687
if (output && fds.revents & POLLOUT)
00688 *output =
true;
00689
if (exception && fds.revents & POLLPRI)
00690 *exception =
true;
00691
00692
return true;
00693
#else
00694
00695
00696
00697
00698 fd_set readfds, writefds, exceptfds;
00699 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
00700
00701
if (input)
00702 {
00703 preadfds = &readfds;
00704 FD_ZERO(preadfds);
00705 FD_SET(
m_sockfd, preadfds);
00706 *input =
false;
00707 }
00708
if (output)
00709 {
00710 pwritefds = &writefds;
00711 FD_ZERO(pwritefds);
00712 FD_SET(
m_sockfd, pwritefds);
00713 *output =
false;
00714 }
00715
if (exception)
00716 {
00717 pexceptfds = &exceptfds;
00718 FD_ZERO(pexceptfds);
00719 FD_SET(
m_sockfd, pexceptfds);
00720 *exception =
false;
00721 }
00722
00723
int retval;
00724
if (timeout < 0)
00725 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
00726
else
00727 {
00728
00729
struct timeval tv;
00730 tv.tv_sec = timeout / 1000;
00731 tv.tv_usec = timeout % 1000 * 1000;
00732
00733 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
00734 }
00735
00736
if (retval == -1)
00737 {
00738
setError(IO_UnspecifiedError, UnknownError);
00739
return false;
00740 }
00741
if (retval == 0)
00742 {
00743
00744
if (timedout)
00745 *timedout =
true;
00746
return true;
00747 }
00748
00749
if (input && FD_ISSET(
m_sockfd, preadfds))
00750 *input =
true;
00751
if (output && FD_ISSET(
m_sockfd, pwritefds))
00752 *output =
true;
00753
if (exception && FD_ISSET(
m_sockfd, pexceptfds))
00754 *exception =
true;
00755
00756
return true;
00757
#endif
00758
}
00759
00760 bool KSocketDevice::poll(
int timeout,
bool *timedout)
00761 {
00762
bool input, output, exception;
00763
return poll(&input, &output, &exception, timeout, timedout);
00764 }
00765
00766 QSocketNotifier*
KSocketDevice::createNotifier(QSocketNotifier::Type type)
const
00767
{
00768
if (
m_sockfd == -1)
00769
return 0L;
00770
00771
return new QSocketNotifier(
m_sockfd, type);
00772 }
00773
00774
namespace
00775
{
00776
00777
template<
class T>
class ptr
00778 {
00779
typedef T type;
00780 type* obj;
00781
public:
00782 ptr() : obj(0)
00783 { }
00784
00785 ptr(
const ptr<T>& other) : obj(other.obj)
00786 { }
00787
00788 ptr(type* _obj) : obj(_obj)
00789 { }
00790
00791 ~ptr()
00792 { }
00793
00794 ptr<T>& operator=(
const ptr<T>& other)
00795 { obj = other.obj;
return *
this; }
00796
00797 ptr<T>& operator=(T* _obj)
00798 { obj = _obj;
return *
this; }
00799
00800 type* operator->()
const {
return obj; }
00801
00802 operator T*()
const {
return obj; }
00803
00804
bool isNull()
const
00805
{
return obj == 0; }
00806 };
00807
00808
static KSocketDeviceFactoryBase* defaultImplFactory;
00809
static QMutex defaultImplFactoryMutex;
00810
typedef QMap<int, KSocketDeviceFactoryBase* > factoryMap;
00811
static factoryMap factories;
00812
00813 KSocketDevice*
KSocketDevice::createDefault(
KSocketBase* parent)
00814 {
00815
KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00816
if (device != 0L)
00817
return device;
00818
00819 KSocksSocketDevice::initSocks();
00820
00821
if (defaultImplFactory)
00822
return defaultImplFactory->create(parent);
00823
00824
00825
return new KSocketDevice(parent);
00826 }
00827
00828 KSocketDevice*
KSocketDevice::createDefault(
KSocketBase* parent,
int capabilities)
00829 {
00830
KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00831
if (device != 0L)
00832
return device;
00833
00834
QMutexLocker locker(&defaultImplFactoryMutex);
00835 factoryMap::ConstIterator it = factories.constBegin();
00836
for ( ; it != factories.constEnd(); ++it)
00837
if ((it.key() & capabilities) == capabilities)
00838
00839
return it.data()->create(parent);
00840
00841
return 0L;
00842 }
00843
00844 KSocketDeviceFactoryBase*
00845 KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory)
00846 {
00847
QMutexLocker locker(&defaultImplFactoryMutex);
00848 KSocketDeviceFactoryBase* old = defaultImplFactory;
00849 defaultImplFactory = factory;
00850
return old;
00851 }
00852
00853 void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory,
int capabilities)
00854 {
00855
QMutexLocker locker(&defaultImplFactoryMutex);
00856
if (factories.contains(capabilities))
00857
delete factories[capabilities];
00858 factories.insert(capabilities, factory);
00859 }
00860
00861 }