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