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
if (retval == 0)
00405
return KSocketDevice::RemotelyDisconnected;
00406
00407
if (from)
00408 from->
setLength(len);
00409
return 0;
00410 }
00411
00412 Q_LONG KSocketDevice::readBlock(
char *data, Q_ULONG maxlen)
00413 {
00414
resetError();
00415
if (
m_sockfd == -1)
00416
return -1;
00417
00418
if (maxlen == 0 || data == 0L)
00419
return 0;
00420
00421 ssize_t retval;
00422
int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval);
00423
00424
if (err)
00425 {
00426 setError(IO_ReadError, static_cast<SocketError>(err));
00427
return -1;
00428 }
00429
00430
return retval;
00431 }
00432
00433 Q_LONG KSocketDevice::readBlock(
char *data, Q_ULONG maxlen,
KSocketAddress &from)
00434 {
00435
resetError();
00436
if (
m_sockfd == -1)
00437
return -1;
00438
00439
if (data == 0L || maxlen == 0)
00440
return 0;
00441
00442 ssize_t retval;
00443
int err = do_read_common(
m_sockfd, data, maxlen, &from, retval);
00444
00445
if (err)
00446 {
00447 setError(IO_ReadError, static_cast<SocketError>(err));
00448
return -1;
00449 }
00450
00451
return retval;
00452 }
00453
00454 Q_LONG KSocketDevice::peekBlock(
char *data, Q_ULONG maxlen)
00455 {
00456
resetError();
00457
if (
m_sockfd == -1)
00458
return -1;
00459
00460
if (maxlen == 0 || data == 0L)
00461
return 0;
00462
00463 ssize_t retval;
00464
int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval,
true);
00465
00466
if (err)
00467 {
00468 setError(IO_ReadError, static_cast<SocketError>(err));
00469
return -1;
00470 }
00471
00472
return retval;
00473 }
00474
00475 Q_LONG KSocketDevice::peekBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00476 {
00477
resetError();
00478
if (
m_sockfd == -1)
00479
return -1;
00480
00481
if (data == 0L || maxlen == 0)
00482
return 0;
00483
00484 ssize_t retval;
00485
int err = do_read_common(
m_sockfd, data, maxlen, &from, retval,
true);
00486
00487
if (err)
00488 {
00489 setError(IO_ReadError, static_cast<SocketError>(err));
00490
return -1;
00491 }
00492
00493
return retval;
00494 }
00495
00496 Q_LONG KSocketDevice::writeBlock(
const char *data, Q_ULONG len)
00497 {
00498
return writeBlock(data, len,
KSocketAddress());
00499 }
00500
00501 Q_LONG KSocketDevice::writeBlock(
const char *data, Q_ULONG len,
const KSocketAddress& to)
00502 {
00503
resetError();
00504
if (
m_sockfd == -1)
00505
return -1;
00506
00507
if (data == 0L || len == 0)
00508
return 0;
00509
00510 ssize_t retval = ::sendto(
m_sockfd, data, len, 0, to.
address(), to.
length());
00511
if (retval == -1)
00512 {
00513
if (errno == EAGAIN || errno == EWOULDBLOCK)
00514 setError(IO_WriteError, WouldBlock);
00515
else
00516 setError(IO_WriteError, UnknownError);
00517
return -1;
00518 }
00519
else if (retval == 0)
00520 setError(IO_WriteError, RemotelyDisconnected);
00521
00522
return retval;
00523 }
00524
00525 KSocketAddress KSocketDevice::localAddress()
const
00526
{
00527
if (
m_sockfd == -1)
00528
return KSocketAddress();
00529
00530 socklen_t len;
00531
KSocketAddress localAddress;
00532 localAddress.
setLength(len = 32);
00533
if (kde_getsockname(
m_sockfd, localAddress.
address(), &len) == -1)
00534
00535
return KSocketAddress();
00536
00537
if (len <= localAddress.
length())
00538 {
00539
00540 localAddress.
setLength(len);
00541
return localAddress;
00542 }
00543
00544
00545
00546 localAddress.
setLength(len);
00547
if (kde_getsockname(
m_sockfd, localAddress.
address(), &len) == -1)
00548
00549
return KSocketAddress();
00550
00551
return localAddress;
00552 }
00553
00554 KSocketAddress KSocketDevice::peerAddress()
const
00555
{
00556
if (
m_sockfd == -1)
00557
return KSocketAddress();
00558
00559 socklen_t len;
00560
KSocketAddress peerAddress;
00561 peerAddress.
setLength(len = 32);
00562
if (kde_getpeername(
m_sockfd, peerAddress.
address(), &len) == -1)
00563
00564
return KSocketAddress();
00565
00566
if (len <= peerAddress.
length())
00567 {
00568
00569 peerAddress.
setLength(len);
00570
return peerAddress;
00571 }
00572
00573
00574
00575 peerAddress.
setLength(len);
00576
if (kde_getpeername(
m_sockfd, peerAddress.
address(), &len) == -1)
00577
00578
return KSocketAddress();
00579
00580
return peerAddress;
00581 }
00582
00583 KSocketAddress KSocketDevice::externalAddress()
const
00584
{
00585
00586
00587
return localAddress();
00588 }
00589
00590 QSocketNotifier*
KSocketDevice::readNotifier()
const
00591
{
00592
if (d->input)
00593
return d->input;
00594
00595
QMutexLocker locker(
mutex());
00596
if (d->input)
00597
return d->input;
00598
00599
if (
m_sockfd == -1)
00600 {
00601
00602
return 0L;
00603 }
00604
00605
return d->input =
createNotifier(QSocketNotifier::Read);
00606 }
00607
00608 QSocketNotifier*
KSocketDevice::writeNotifier()
const
00609
{
00610
if (d->output)
00611
return d->output;
00612
00613
QMutexLocker locker(
mutex());
00614
if (d->output)
00615
return d->output;
00616
00617
if (
m_sockfd == -1)
00618 {
00619
00620
return 0L;
00621 }
00622
00623
return d->output =
createNotifier(QSocketNotifier::Write);
00624 }
00625
00626 QSocketNotifier*
KSocketDevice::exceptionNotifier()
const
00627
{
00628
if (d->exception)
00629
return d->exception;
00630
00631
QMutexLocker locker(
mutex());
00632
if (d->exception)
00633
return d->exception;
00634
00635
if (
m_sockfd == -1)
00636 {
00637
00638
return 0L;
00639 }
00640
00641
return d->exception =
createNotifier(QSocketNotifier::Exception);
00642 }
00643
00644 bool KSocketDevice::poll(
bool *input,
bool *output,
bool *exception,
00645
int timeout,
bool* timedout)
00646 {
00647
if (
m_sockfd == -1)
00648 {
00649 setError(IO_UnspecifiedError, NotCreated);
00650
return false;
00651 }
00652
00653
resetError();
00654
#ifdef HAVE_POLL
00655
struct pollfd fds;
00656 fds.fd =
m_sockfd;
00657 fds.events = 0;
00658
00659
if (input)
00660 {
00661 fds.events |= POLLIN;
00662 *input =
false;
00663 }
00664
if (output)
00665 {
00666 fds.events |= POLLOUT;
00667 *output =
false;
00668 }
00669
if (exception)
00670 {
00671 fds.events |= POLLPRI;
00672 *exception =
false;
00673 }
00674
00675
int retval = ::poll(&fds, 1, timeout);
00676
if (retval == -1)
00677 {
00678 setError(IO_UnspecifiedError, UnknownError);
00679
return false;
00680 }
00681
if (retval == 0)
00682 {
00683
00684
if (timedout)
00685 *timedout =
true;
00686
return true;
00687 }
00688
00689
if (input && fds.revents & POLLIN)
00690 *input =
true;
00691
if (output && fds.revents & POLLOUT)
00692 *output =
true;
00693
if (exception && fds.revents & POLLPRI)
00694 *exception =
true;
00695
00696
return true;
00697
#else
00698
00699
00700
00701
00702 fd_set readfds, writefds, exceptfds;
00703 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
00704
00705
if (input)
00706 {
00707 preadfds = &readfds;
00708 FD_ZERO(preadfds);
00709 FD_SET(
m_sockfd, preadfds);
00710 *input =
false;
00711 }
00712
if (output)
00713 {
00714 pwritefds = &writefds;
00715 FD_ZERO(pwritefds);
00716 FD_SET(
m_sockfd, pwritefds);
00717 *output =
false;
00718 }
00719
if (exception)
00720 {
00721 pexceptfds = &exceptfds;
00722 FD_ZERO(pexceptfds);
00723 FD_SET(
m_sockfd, pexceptfds);
00724 *exception =
false;
00725 }
00726
00727
int retval;
00728
if (timeout < 0)
00729 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
00730
else
00731 {
00732
00733
struct timeval tv;
00734 tv.tv_sec = timeout / 1000;
00735 tv.tv_usec = timeout % 1000 * 1000;
00736
00737 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
00738 }
00739
00740
if (retval == -1)
00741 {
00742 setError(IO_UnspecifiedError, UnknownError);
00743
return false;
00744 }
00745
if (retval == 0)
00746 {
00747
00748
if (timedout)
00749 *timedout =
true;
00750
return true;
00751 }
00752
00753
if (input && FD_ISSET(
m_sockfd, preadfds))
00754 *input =
true;
00755
if (output && FD_ISSET(
m_sockfd, pwritefds))
00756 *output =
true;
00757
if (exception && FD_ISSET(
m_sockfd, pexceptfds))
00758 *exception =
true;
00759
00760
return true;
00761
#endif
00762
}
00763
00764 bool KSocketDevice::poll(
int timeout,
bool *timedout)
00765 {
00766
bool input, output, exception;
00767
return poll(&input, &output, &exception, timeout, timedout);
00768 }
00769
00770 QSocketNotifier* KSocketDevice::createNotifier(QSocketNotifier::Type type)
const
00771
{
00772
if (
m_sockfd == -1)
00773
return 0L;
00774
00775
return new QSocketNotifier(
m_sockfd, type);
00776 }
00777
00778
namespace
00779
{
00780
00781
template<
class T>
class ptr
00782 {
00783
typedef T type;
00784 type* obj;
00785
public:
00786 ptr() : obj(0)
00787 { }
00788
00789 ptr(
const ptr<T>& other) : obj(other.obj)
00790 { }
00791
00792 ptr(type* _obj) : obj(_obj)
00793 { }
00794
00795 ~ptr()
00796 { }
00797
00798 ptr<T>& operator=(
const ptr<T>& other)
00799 { obj = other.obj;
return *
this; }
00800
00801 ptr<T>& operator=(T* _obj)
00802 { obj = _obj;
return *
this; }
00803
00804 type* operator->()
const {
return obj; }
00805
00806 operator T*()
const {
return obj; }
00807
00808
bool isNull()
const
00809
{
return obj == 0; }
00810 };
00811 }
00812
00813
static KSocketDeviceFactoryBase* defaultImplFactory;
00814
static QMutex defaultImplFactoryMutex;
00815
typedef QMap<int, KSocketDeviceFactoryBase* > factoryMap;
00816
static factoryMap factories;
00817
00818 KSocketDevice* KSocketDevice::createDefault(
KSocketBase* parent)
00819 {
00820
KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00821
if (device != 0L)
00822
return device;
00823
00824 KSocksSocketDevice::initSocks();
00825
00826
if (defaultImplFactory)
00827
return defaultImplFactory->create(parent);
00828
00829
00830
return new KSocketDevice(parent);
00831 }
00832
00833 KSocketDevice* KSocketDevice::createDefault(
KSocketBase* parent,
int capabilities)
00834 {
00835
KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00836
if (device != 0L)
00837
return device;
00838
00839
QMutexLocker locker(&defaultImplFactoryMutex);
00840 factoryMap::ConstIterator it = factories.constBegin();
00841
for ( ; it != factories.constEnd(); ++it)
00842
if ((it.key() & capabilities) == capabilities)
00843
00844
return it.data()->create(parent);
00845
00846
return 0L;
00847 }
00848
00849 KSocketDeviceFactoryBase*
00850 KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory)
00851 {
00852
QMutexLocker locker(&defaultImplFactoryMutex);
00853 KSocketDeviceFactoryBase* old = defaultImplFactory;
00854 defaultImplFactory = factory;
00855
return old;
00856 }
00857
00858 void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory,
int capabilities)
00859 {
00860
QMutexLocker locker(&defaultImplFactoryMutex);
00861
if (factories.contains(capabilities))
00862
delete factories[capabilities];
00863 factories.insert(capabilities, factory);
00864 }
00865