• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

k3sockssocketdevice.cpp

Go to the documentation of this file.
00001 /*  -*- C++ -*-
00002  *  Copyright (C) 2004 Thiago Macieira <thiago@kde.org>
00003  *
00004  *  This library is free software; you can redistribute it and/or
00005  *  modify it under the terms of the GNU Library General Public
00006  *  License as published by the Free Software Foundation; either
00007  *  version 2 of the License, or (at your option) any later version.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "k3sockssocketdevice.h"
00021 
00022 #include <config.h>
00023 #include <config-network.h>
00024 
00025 #include <errno.h>
00026 #include <sys/types.h>
00027 #include <sys/socket.h>
00028 
00029 #if defined(HAVE_UNISTD_H)
00030 #include <unistd.h>
00031 #endif
00032 
00033 #ifdef __CYGWIN__
00034 #undef kde_socklen_t
00035 #define kde_socklen_t ksocklen_t
00036 #endif
00037 
00038 #include <QCoreApplication>
00039 #ifndef KDE_USE_FINAL
00040 #define I_KNOW_KSOCKS_ISNT_PUBLIC
00041 #include "k3socks.h"
00042 #undef I_KNOW_KSOCKS_ISNT_PUBLIC
00043 #endif
00044 #include "k3socketaddress.h"
00045 #include "k3resolver.h"
00046 
00047 using namespace KNetwork;
00048 
00049 // constructor
00050 // nothing to do
00051 KSocksSocketDevice::KSocksSocketDevice(const KSocketBase* obj)
00052   : KSocketDevice(obj), d(0)
00053 {
00054 }
00055 
00056 // constructor with argument
00057 // nothing to do
00058 KSocksSocketDevice::KSocksSocketDevice(int fd)
00059   : KSocketDevice(fd), d(0)
00060 {
00061 }
00062 
00063 // destructor
00064 // also nothing to do
00065 KSocksSocketDevice::~KSocksSocketDevice()
00066 {
00067 }
00068 
00069 // returns the capabilities
00070 int KSocksSocketDevice::capabilities() const
00071 {
00072   return 0;         // can do everything!
00073 }
00074 
00075 // From here on, the code is almost exactly a copy of KSocketDevice
00076 // the differences are the use of KSocks where appropriate
00077 
00078 bool KSocksSocketDevice::bind(const KResolverEntry& address)
00079 {
00080   resetError();
00081 
00082   if (m_sockfd == -1 && !create(address))
00083     return false;       // failed creating
00084 
00085   // we have a socket, so try and bind
00086   if (KSocks::self()->bind(m_sockfd, address.address(), address.length()) == -1)
00087     {
00088       if (errno == EADDRINUSE)
00089     setError(AddressInUse);
00090       else if (errno == EINVAL)
00091     setError(AlreadyBound);
00092       else
00093     // assume the address is the cause
00094     setError(NotSupported);
00095       return false;
00096     }
00097 
00098   return true;
00099 }
00100 
00101 
00102 bool KSocksSocketDevice::listen(int backlog)
00103 {
00104   if (m_sockfd != -1)
00105     {
00106       if (KSocks::self()->listen(m_sockfd, backlog) == -1)
00107     {
00108       setError(NotSupported);
00109       return false;
00110     }
00111 
00112       resetError();
00113       setOpenMode(ReadWrite | Unbuffered);
00114       return true;
00115     }
00116 
00117   // we don't have a socket
00118   // can't listen
00119   setError(NotCreated);
00120   return false;
00121 }
00122 
00123 bool KSocksSocketDevice::connect(const KResolverEntry& address)
00124 {
00125   resetError();
00126 
00127   if (m_sockfd == -1 && !create(address))
00128     return false;       // failed creating!
00129 
00130   int retval;
00131   if (KSocks::self()->hasWorkingAsyncConnect())
00132     retval = KSocks::self()->connect(m_sockfd, address.address(),
00133                      address.length());
00134   else
00135     {
00136       // work around some SOCKS implementation bugs
00137       // we will do a *synchronous* connection here!
00138       // FIXME: KDE4, write a proper SOCKS implementation
00139       bool isBlocking = blocking();
00140       setBlocking(true);
00141       retval = KSocks::self()->connect(m_sockfd, address.address(),
00142                        address.length());
00143       setBlocking(isBlocking);
00144     }
00145 
00146   if (retval == -1)
00147     {
00148       if (errno == EISCONN)
00149     return true;        // we're already connected
00150       else if (errno == EALREADY || errno == EINPROGRESS)
00151     {
00152       setError(InProgress);
00153       return true;
00154     }
00155       else if (errno == ECONNREFUSED)
00156     setError(ConnectionRefused);
00157       else if (errno == ENETDOWN || errno == ENETUNREACH ||
00158            errno == ENETRESET || errno == ECONNABORTED ||
00159            errno == ECONNRESET || errno == EHOSTDOWN ||
00160            errno == EHOSTUNREACH)
00161     setError(NetFailure);
00162       else
00163     setError(NotSupported);
00164 
00165       return false;
00166     }
00167 
00168   setOpenMode(ReadWrite | Unbuffered);
00169   return true;          // all is well
00170 }
00171 
00172 KSocksSocketDevice* KSocksSocketDevice::accept()
00173 {
00174   if (m_sockfd == -1)
00175     {
00176       // can't accept without a socket
00177       setError(NotCreated);
00178       return 0L;
00179     }
00180 
00181   struct sockaddr sa;
00182   kde_socklen_t len = sizeof(sa);
00183   int newfd = KSocks::self()->accept(m_sockfd, &sa, &len);
00184   if (newfd == -1)
00185     {
00186       if (errno == EAGAIN || errno == EWOULDBLOCK)
00187     setError(WouldBlock);
00188       else
00189     setError(UnknownError);
00190       return NULL;
00191     }
00192 
00193   return new KSocksSocketDevice(newfd);
00194 }
00195 
00196 static int socks_read_common(int sockfd, char *data, quint64 maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false)
00197 {
00198   kde_socklen_t len;
00199   if (from)
00200     {
00201       from->setLength(len = 128); // arbitrary length
00202       retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
00203     }
00204   else
00205     retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
00206 
00207   if (retval == -1)
00208     {
00209       if (errno == EAGAIN || errno == EWOULDBLOCK)
00210     return KSocketDevice::WouldBlock;
00211       else
00212     return KSocketDevice::UnknownError;
00213     }
00214 
00215   if (from)
00216     from->setLength(len);
00217   return 0;
00218 }
00219 
00220 qint64 KSocksSocketDevice::readBlock(char *data, quint64 maxlen)
00221 {
00222   resetError();
00223   if (m_sockfd == -1)
00224     return -1;
00225 
00226   if (maxlen == 0 || data == 0L)
00227     return 0;           // can't read
00228 
00229   ssize_t retval;
00230   int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval);
00231 
00232   if (err)
00233     {
00234       setError(static_cast<SocketError>(err));
00235       return -1;
00236     }
00237 
00238   return retval;
00239 }
00240 
00241 qint64 KSocksSocketDevice::readBlock(char *data, quint64 maxlen, KSocketAddress &from)
00242 {
00243   resetError();
00244   if (m_sockfd == -1)
00245     return -1;          // nothing to do here
00246 
00247   if (data == 0L || maxlen == 0)
00248     return 0;           // user doesn't want to read
00249 
00250   ssize_t retval;
00251   int err = socks_read_common(m_sockfd, data, maxlen, &from, retval);
00252 
00253   if (err)
00254     {
00255       setError(static_cast<SocketError>(err));
00256       return -1;
00257     }
00258 
00259   return retval;
00260 }
00261 
00262 qint64 KSocksSocketDevice::peekBlock(char *data, quint64 maxlen)
00263 {
00264   resetError();
00265   if (m_sockfd == -1)
00266     return -1;
00267 
00268   if (maxlen == 0 || data == 0L)
00269     return 0;           // can't read
00270 
00271   ssize_t retval;
00272   int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true);
00273 
00274   if (err)
00275     {
00276       setError(static_cast<SocketError>(err));
00277       return -1;
00278     }
00279 
00280   return retval;
00281 }
00282 
00283 qint64 KSocksSocketDevice::peekBlock(char *data, quint64 maxlen, KSocketAddress& from)
00284 {
00285   resetError();
00286   if (m_sockfd == -1)
00287     return -1;          // nothing to do here
00288 
00289   if (data == 0L || maxlen == 0)
00290     return 0;           // user doesn't want to read
00291 
00292   ssize_t retval;
00293   int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true);
00294 
00295   if (err)
00296     {
00297       setError(static_cast<SocketError>(err));
00298       return -1;
00299     }
00300 
00301   return retval;
00302 }
00303 
00304 qint64 KSocksSocketDevice::writeBlock(const char *data, quint64 len)
00305 {
00306   return writeBlock(data, len, KSocketAddress());
00307 }
00308 
00309 qint64 KSocksSocketDevice::writeBlock(const char *data, quint64 len, const KSocketAddress& to)
00310 {
00311   resetError();
00312   if (m_sockfd == -1)
00313     return -1;          // can't write to unopen socket
00314 
00315   if (data == 0L || len == 0)
00316     return 0;           // nothing to be written
00317 
00318   ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length());
00319   if (retval == -1)
00320     {
00321       if (errno == EAGAIN || errno == EWOULDBLOCK)
00322     setError(WouldBlock);
00323       else
00324     setError(UnknownError);
00325       return -1;        // nothing written
00326     }
00327 
00328   return retval;
00329 }
00330 
00331 KSocketAddress KSocksSocketDevice::localAddress() const
00332 {
00333   if (m_sockfd == -1)
00334     return KSocketAddress();    // not open, empty value
00335 
00336   kde_socklen_t len;
00337   KSocketAddress localAddress;
00338   localAddress.setLength(len = 32); // arbitrary value
00339   if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
00340     // error!
00341     return KSocketAddress();
00342 
00343   if (len <= localAddress.length())
00344     {
00345       // it has fit already
00346       localAddress.setLength(len);
00347       return localAddress;
00348     }
00349 
00350   // no, the socket address is actually larger than we had anticipated
00351   // call again
00352   localAddress.setLength(len);
00353   if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
00354     // error!
00355     return KSocketAddress();
00356 
00357   return localAddress;
00358 }
00359 
00360 KSocketAddress KSocksSocketDevice::peerAddress() const
00361 {
00362   if (m_sockfd == -1)
00363     return KSocketAddress();    // not open, empty value
00364 
00365   kde_socklen_t len;
00366   KSocketAddress peerAddress;
00367   peerAddress.setLength(len = 32);  // arbitrary value
00368   if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00369     // error!
00370     return KSocketAddress();
00371 
00372   if (len <= peerAddress.length())
00373     {
00374       // it has fit already
00375       peerAddress.setLength(len);
00376       return peerAddress;
00377     }
00378 
00379   // no, the socket address is actually larger than we had anticipated
00380   // call again
00381   peerAddress.setLength(len);
00382   if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00383     // error!
00384     return KSocketAddress();
00385 
00386   return peerAddress;
00387 }
00388 
00389 KSocketAddress KSocksSocketDevice::externalAddress() const
00390 {
00391   // return empty, indicating unknown external address
00392   return KSocketAddress();
00393 }
00394 
00395 bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception,
00396                   int timeout, bool *timedout)
00397 {
00398   if (m_sockfd == -1)
00399     {
00400       setError(NotCreated);
00401       return false;
00402     }
00403 
00404   resetError();
00405   fd_set readfds, writefds, exceptfds;
00406   fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
00407 
00408   if (input)
00409     {
00410       preadfds = &readfds;
00411       FD_ZERO(preadfds);
00412       FD_SET(m_sockfd, preadfds);
00413       *input = false;
00414     }
00415   if (output)
00416     {
00417       pwritefds = &writefds;
00418       FD_ZERO(pwritefds);
00419       FD_SET(m_sockfd, pwritefds);
00420       *output = false;
00421     }
00422   if (exception)
00423     {
00424       pexceptfds = &exceptfds;
00425       FD_ZERO(pexceptfds);
00426       FD_SET(m_sockfd, pexceptfds);
00427       *exception = false;
00428     }
00429 
00430   int retval;
00431   if (timeout < 0)
00432     retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
00433   else
00434     {
00435       // convert the milliseconds to timeval
00436       struct timeval tv;
00437       tv.tv_sec = timeout / 1000;
00438       tv.tv_usec = timeout % 1000 * 1000;
00439 
00440       retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
00441     }
00442 
00443   if (retval == -1)
00444     {
00445       setError(UnknownError);
00446       return false;
00447     }
00448   if (retval == 0)
00449     {
00450       // timeout
00451       if (timedout)
00452     *timedout = true;
00453       return true;
00454     }
00455 
00456   if (input && FD_ISSET(m_sockfd, preadfds))
00457     *input = true;
00458   if (output && FD_ISSET(m_sockfd, pwritefds))
00459     *output = true;
00460   if (exception && FD_ISSET(m_sockfd, pexceptfds))
00461     *exception = true;
00462 
00463   return true;
00464 }
00465 
00466 void KSocksSocketDevice::initSocks()
00467 {
00468   static bool init = false;
00469 
00470   if (init)
00471     return;
00472 
00473   if (QCoreApplication::instance() == 0L)
00474     return;         // no KApplication, so don't initialize
00475                                 // this should, however, test for KComponentData
00476 
00477   init = true;
00478 
00479   if (KSocks::self()->hasSocks())
00480     delete KSocketDevice::setDefaultImpl(new KSocketDeviceFactory<KSocksSocketDevice>);
00481 }
00482 
00483 #if 0
00484 static bool register()
00485 {
00486   KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0);
00487 }
00488 
00489 static bool register = registered();
00490 #endif

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal