# kdecore Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:11 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003