kdecore Library API Documentation

ksockssocketdevice.cpp

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