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

KDECore

ksockssocketdevice.cpp

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

KDECore

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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