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