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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • network
k3sockssocketdevice.cpp
Go to the documentation of this file.
1 /* -*- C++ -*-
2  * Copyright (C) 2004 Thiago Macieira <thiago@kde.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include "k3sockssocketdevice.h"
21 
22 #include <config.h>
23 #include <config-network.h>
24 
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 
29 #if defined(HAVE_UNISTD_H)
30 #include <unistd.h>
31 #endif
32 
33 
34 #include <QCoreApplication>
35 #ifndef KDE_USE_FINAL
36 #define I_KNOW_KSOCKS_ISNT_PUBLIC
37 #include "k3socks.h"
38 #undef I_KNOW_KSOCKS_ISNT_PUBLIC
39 #endif
40 #include "k3socketaddress.h"
41 #include "k3resolver.h"
42 
43 using namespace KNetwork;
44 
45 // constructor
46 // nothing to do
47 KSocksSocketDevice::KSocksSocketDevice(const KSocketBase* obj)
48  : KSocketDevice(obj), d(0)
49 {
50 }
51 
52 // constructor with argument
53 // nothing to do
54 KSocksSocketDevice::KSocksSocketDevice(int fd)
55  : KSocketDevice(fd), d(0)
56 {
57 }
58 
59 // destructor
60 // also nothing to do
61 KSocksSocketDevice::~KSocksSocketDevice()
62 {
63 }
64 
65 // returns the capabilities
66 int KSocksSocketDevice::capabilities() const
67 {
68  return 0; // can do everything!
69 }
70 
71 // From here on, the code is almost exactly a copy of KSocketDevice
72 // the differences are the use of KSocks where appropriate
73 
74 bool KSocksSocketDevice::bind(const KResolverEntry& address)
75 {
76  resetError();
77 
78  if (m_sockfd == -1 && !create(address))
79  return false; // failed creating
80 
81  // we have a socket, so try and bind
82  if (KSocks::self()->bind(m_sockfd, address.address(), address.length()) == -1)
83  {
84  if (errno == EADDRINUSE)
85  setError(AddressInUse);
86  else if (errno == EINVAL)
87  setError(AlreadyBound);
88  else
89  // assume the address is the cause
90  setError(NotSupported);
91  return false;
92  }
93 
94  return true;
95 }
96 
97 
98 bool KSocksSocketDevice::listen(int backlog)
99 {
100  if (m_sockfd != -1)
101  {
102  if (KSocks::self()->listen(m_sockfd, backlog) == -1)
103  {
104  setError(NotSupported);
105  return false;
106  }
107 
108  resetError();
109  setOpenMode(ReadWrite | Unbuffered);
110  return true;
111  }
112 
113  // we don't have a socket
114  // can't listen
115  setError(NotCreated);
116  return false;
117 }
118 
119 bool KSocksSocketDevice::connect(const KResolverEntry& address)
120 {
121  resetError();
122 
123  if (m_sockfd == -1 && !create(address))
124  return false; // failed creating!
125 
126  int retval;
127  if (KSocks::self()->hasWorkingAsyncConnect())
128  retval = KSocks::self()->connect(m_sockfd, address.address(),
129  address.length());
130  else
131  {
132  // work around some SOCKS implementation bugs
133  // we will do a *synchronous* connection here!
134  // FIXME: KDE4, write a proper SOCKS implementation
135  bool isBlocking = blocking();
136  setBlocking(true);
137  retval = KSocks::self()->connect(m_sockfd, address.address(),
138  address.length());
139  setBlocking(isBlocking);
140  }
141 
142  if (retval == -1)
143  {
144  if (errno == EISCONN)
145  return true; // we're already connected
146  else if (errno == EALREADY || errno == EINPROGRESS)
147  {
148  setError(InProgress);
149  return true;
150  }
151  else if (errno == ECONNREFUSED)
152  setError(ConnectionRefused);
153  else if (errno == ENETDOWN || errno == ENETUNREACH ||
154  errno == ENETRESET || errno == ECONNABORTED ||
155  errno == ECONNRESET || errno == EHOSTDOWN ||
156  errno == EHOSTUNREACH)
157  setError(NetFailure);
158  else
159  setError(NotSupported);
160 
161  return false;
162  }
163 
164  setOpenMode(ReadWrite | Unbuffered);
165  return true; // all is well
166 }
167 
168 KSocksSocketDevice* KSocksSocketDevice::accept()
169 {
170  if (m_sockfd == -1)
171  {
172  // can't accept without a socket
173  setError(NotCreated);
174  return 0L;
175  }
176 
177  struct sockaddr sa;
178  kde_socklen_t len = sizeof(sa);
179  int newfd = KSocks::self()->accept(m_sockfd, &sa, &len);
180  if (newfd == -1)
181  {
182  if (errno == EAGAIN || errno == EWOULDBLOCK)
183  setError(WouldBlock);
184  else
185  setError(UnknownError);
186  return NULL;
187  }
188 
189  return new KSocksSocketDevice(newfd);
190 }
191 
192 static int socks_read_common(int sockfd, char *data, quint64 maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false)
193 {
194  kde_socklen_t len;
195  if (from)
196  {
197  from->setLength(len = 128); // arbitrary length
198  retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
199  }
200  else
201  retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
202 
203  if (retval == -1)
204  {
205  if (errno == EAGAIN || errno == EWOULDBLOCK)
206  return KSocketDevice::WouldBlock;
207  else
208  return KSocketDevice::UnknownError;
209  }
210 
211  if (from)
212  from->setLength(len);
213  return 0;
214 }
215 
216 qint64 KSocksSocketDevice::readBlock(char *data, quint64 maxlen)
217 {
218  resetError();
219  if (m_sockfd == -1)
220  return -1;
221 
222  if (maxlen == 0 || data == 0L)
223  return 0; // can't read
224 
225  ssize_t retval;
226  int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval);
227 
228  if (err)
229  {
230  setError(static_cast<SocketError>(err));
231  return -1;
232  }
233 
234  return retval;
235 }
236 
237 qint64 KSocksSocketDevice::readBlock(char *data, quint64 maxlen, KSocketAddress &from)
238 {
239  resetError();
240  if (m_sockfd == -1)
241  return -1; // nothing to do here
242 
243  if (data == 0L || maxlen == 0)
244  return 0; // user doesn't want to read
245 
246  ssize_t retval;
247  int err = socks_read_common(m_sockfd, data, maxlen, &from, retval);
248 
249  if (err)
250  {
251  setError(static_cast<SocketError>(err));
252  return -1;
253  }
254 
255  return retval;
256 }
257 
258 qint64 KSocksSocketDevice::peekBlock(char *data, quint64 maxlen)
259 {
260  resetError();
261  if (m_sockfd == -1)
262  return -1;
263 
264  if (maxlen == 0 || data == 0L)
265  return 0; // can't read
266 
267  ssize_t retval;
268  int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true);
269 
270  if (err)
271  {
272  setError(static_cast<SocketError>(err));
273  return -1;
274  }
275 
276  return retval;
277 }
278 
279 qint64 KSocksSocketDevice::peekBlock(char *data, quint64 maxlen, KSocketAddress& from)
280 {
281  resetError();
282  if (m_sockfd == -1)
283  return -1; // nothing to do here
284 
285  if (data == 0L || maxlen == 0)
286  return 0; // user doesn't want to read
287 
288  ssize_t retval;
289  int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true);
290 
291  if (err)
292  {
293  setError(static_cast<SocketError>(err));
294  return -1;
295  }
296 
297  return retval;
298 }
299 
300 qint64 KSocksSocketDevice::writeBlock(const char *data, quint64 len)
301 {
302  return writeBlock(data, len, KSocketAddress());
303 }
304 
305 qint64 KSocksSocketDevice::writeBlock(const char *data, quint64 len, const KSocketAddress& to)
306 {
307  resetError();
308  if (m_sockfd == -1)
309  return -1; // can't write to unopen socket
310 
311  if (data == 0L || len == 0)
312  return 0; // nothing to be written
313 
314  ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length());
315  if (retval == -1)
316  {
317  if (errno == EAGAIN || errno == EWOULDBLOCK)
318  setError(WouldBlock);
319  else
320  setError(UnknownError);
321  return -1; // nothing written
322  }
323 
324  return retval;
325 }
326 
327 KSocketAddress KSocksSocketDevice::localAddress() const
328 {
329  if (m_sockfd == -1)
330  return KSocketAddress(); // not open, empty value
331 
332  kde_socklen_t len;
333  KSocketAddress localAddress;
334  localAddress.setLength(len = 32); // arbitrary value
335  if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
336  // error!
337  return KSocketAddress();
338 
339  if (len <= localAddress.length())
340  {
341  // it has fit already
342  localAddress.setLength(len);
343  return localAddress;
344  }
345 
346  // no, the socket address is actually larger than we had anticipated
347  // call again
348  localAddress.setLength(len);
349  if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
350  // error!
351  return KSocketAddress();
352 
353  return localAddress;
354 }
355 
356 KSocketAddress KSocksSocketDevice::peerAddress() const
357 {
358  if (m_sockfd == -1)
359  return KSocketAddress(); // not open, empty value
360 
361  kde_socklen_t len;
362  KSocketAddress peerAddress;
363  peerAddress.setLength(len = 32); // arbitrary value
364  if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
365  // error!
366  return KSocketAddress();
367 
368  if (len <= peerAddress.length())
369  {
370  // it has fit already
371  peerAddress.setLength(len);
372  return peerAddress;
373  }
374 
375  // no, the socket address is actually larger than we had anticipated
376  // call again
377  peerAddress.setLength(len);
378  if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
379  // error!
380  return KSocketAddress();
381 
382  return peerAddress;
383 }
384 
385 KSocketAddress KSocksSocketDevice::externalAddress() const
386 {
387  // return empty, indicating unknown external address
388  return KSocketAddress();
389 }
390 
391 bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception,
392  int timeout, bool *timedout)
393 {
394  if (m_sockfd == -1)
395  {
396  setError(NotCreated);
397  return false;
398  }
399 
400  resetError();
401  fd_set readfds, writefds, exceptfds;
402  fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
403 
404  if (input)
405  {
406  preadfds = &readfds;
407  FD_ZERO(preadfds);
408  FD_SET(m_sockfd, preadfds);
409  *input = false;
410  }
411  if (output)
412  {
413  pwritefds = &writefds;
414  FD_ZERO(pwritefds);
415  FD_SET(m_sockfd, pwritefds);
416  *output = false;
417  }
418  if (exception)
419  {
420  pexceptfds = &exceptfds;
421  FD_ZERO(pexceptfds);
422  FD_SET(m_sockfd, pexceptfds);
423  *exception = false;
424  }
425 
426  int retval;
427  if (timeout < 0)
428  retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
429  else
430  {
431  // convert the milliseconds to timeval
432  struct timeval tv;
433  tv.tv_sec = timeout / 1000;
434  tv.tv_usec = timeout % 1000 * 1000;
435 
436  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
437  }
438 
439  if (retval == -1)
440  {
441  setError(UnknownError);
442  return false;
443  }
444  if (retval == 0)
445  {
446  // timeout
447  if (timedout)
448  *timedout = true;
449  return true;
450  }
451 
452  if (input && FD_ISSET(m_sockfd, preadfds))
453  *input = true;
454  if (output && FD_ISSET(m_sockfd, pwritefds))
455  *output = true;
456  if (exception && FD_ISSET(m_sockfd, pexceptfds))
457  *exception = true;
458 
459  return true;
460 }
461 
462 void KSocksSocketDevice::initSocks()
463 {
464  static bool init = false;
465 
466  if (init)
467  return;
468 
469  if (QCoreApplication::instance() == 0L)
470  return; // no KApplication, so don't initialize
471  // this should, however, test for KComponentData
472 
473  init = true;
474 
475  if (KSocks::self()->hasSocks())
476  delete KSocketDevice::setDefaultImpl(new KSocketDeviceFactory<KSocksSocketDevice>);
477 }
478 
479 #if 0
480 static bool register()
481 {
482  KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0);
483 }
484 
485 static bool register = registered();
486 #endif
k3socketaddress.h
KNetwork::KSocketBase::AddressInUse
Definition: k3socketbase.h:147
k3sockssocketdevice.h
qint64
KNetwork::KSocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: k3socketbase.cpp:102
KNetwork::KSocksSocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: k3sockssocketdevice.cpp:66
KNetwork::KSocksSocketDevice::listen
virtual bool listen(int backlog)
Overrides listening.
Definition: k3sockssocketdevice.cpp:98
KNetwork::KSocketBase::NotCreated
Definition: k3socketbase.h:153
timeout
int timeout
Definition: kkernel_mac.cpp:46
KNetwork::KResolverEntry
One resolution entry.
Definition: k3resolver.h:68
KNetwork::KSocketAddress::setLength
KSocketAddress & setLength(quint16 len)
Sets the length of this socket structure.
Definition: k3socketaddress.cpp:480
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: k3socketbase.cpp:441
KNetwork::KSocksSocketDevice::accept
virtual KSocksSocketDevice * accept()
Overrides accepting.
Definition: k3sockssocketdevice.cpp:168
KNetwork::KSocksSocketDevice::localAddress
virtual KSocketAddress localAddress() const
Overrides getting socket address.
Definition: k3sockssocketdevice.cpp:327
KNetwork::KSocketBase::UnknownError
Definition: k3socketbase.h:161
KNetwork::KSocketBase::InProgress
Definition: k3socketbase.h:157
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:414
KNetwork::KSocketAddress::address
const sockaddr * address() const
Returns the socket address structure, to be passed down to low level functions.
Definition: k3socketaddress.cpp:449
KNetwork::KSocksSocketDevice::peerAddress
virtual KSocketAddress peerAddress() const
Overrides getting peer address.
Definition: k3sockssocketdevice.cpp:356
KNetwork::KSocksSocketDevice::bind
virtual bool bind(const KResolverEntry &address)
Overrides binding.
Definition: k3sockssocketdevice.cpp:74
k3socks.h
KNetwork::KSocketBase::WouldBlock
Definition: k3socketbase.h:154
KNetwork::KSocksSocketDevice
The low-level class for SOCKS proxying.
Definition: k3sockssocketdevice.h:42
KNetwork::KSocketDevice::addNewImpl
static void addNewImpl(KSocketDeviceFactoryBase *factory, int capabilities)
Adds a factory of KSocketDevice objects to the list, along with its capabilities flag.
Definition: k3socketdevice.cpp:915
KNetwork::KSocketDevice::create
virtual bool create(int family, int type, int protocol)
Creates a socket but don't connect or bind anywhere.
Definition: k3socketdevice.cpp:261
KNetwork::KSocksSocketDevice::writeBlock
virtual qint64 writeBlock(const char *data, quint64 len)
Overrides writing.
Definition: k3sockssocketdevice.cpp:300
KNetwork::KSocksSocketDevice::peekBlock
virtual qint64 peekBlock(char *data, quint64 maxlen)
Overrides peeking.
Definition: k3sockssocketdevice.cpp:258
KNetwork::KSocksSocketDevice::poll
virtual bool poll(bool *input, bool *output, bool *exception=0L, int timeout=-1, bool *timedout=0L)
Overrides polling.
Definition: k3sockssocketdevice.cpp:391
QCoreApplication::instance
QCoreApplication * instance()
socks_read_common
static int socks_read_common(int sockfd, char *data, quint64 maxlen, KSocketAddress *from, ssize_t &retval, bool peek=false)
Definition: k3sockssocketdevice.cpp:192
KNetwork::KActiveSocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: k3socketbase.cpp:435
KNetwork::KSocketBase::NotSupported
Definition: k3socketbase.h:159
k3resolver.h
KNetwork::KResolverEntry::address
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:135
KNetwork::KSocketDevice::setDefaultImpl
static KSocketDeviceFactoryBase * setDefaultImpl(KSocketDeviceFactoryBase *factory)
Sets the default KSocketDevice implementation to use and return the old factory.
Definition: k3socketdevice.cpp:907
KNetwork::KSocketDeviceFactory
This class provides functionality for creating and registering socket implementations.
Definition: k3socketdevice.h:401
KNetwork::KSocksSocketDevice::externalAddress
virtual KSocketAddress externalAddress() const
Overrides getting external address.
Definition: k3sockssocketdevice.cpp:385
KNetwork::KResolverEntry::length
quint16 length() const
Retrieves the length of the socket address structure.
Definition: k3resolver.cpp:141
KNetwork::KSocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: k3socketdevice.h:96
output
void output(QList< Action > actions, QHash< QString, QString > domain)
Definition: fake/kauth-policy-gen-polkit.cpp:41
quint64
KNetwork::KSocketAddress::length
quint16 length() const
Returns the length of this socket address structure.
Definition: k3socketaddress.cpp:473
KNetwork::KSocketBase::AlreadyBound
Definition: k3socketbase.h:149
KNetwork::KSocksSocketDevice::readBlock
virtual qint64 readBlock(char *data, quint64 maxlen)
Overrides reading.
Definition: k3sockssocketdevice.cpp:216
KNetwork::KSocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: k3socketbase.cpp:97
KNetwork::KSocketDevice
Low-level socket functionality.
Definition: k3socketdevice.h:51
KNetwork::KSocksSocketDevice::KSocksSocketDevice
KSocksSocketDevice(const KSocketBase *=0L)
Constructor.
Definition: k3sockssocketdevice.cpp:47
KNetwork::KSocketBase::ConnectionRefused
Definition: k3socketbase.h:155
KNetwork::KSocketBase::NetFailure
Definition: k3socketbase.h:158
KNetwork::KSocketBase
Basic socket functionality.
Definition: k3socketbase.h:85
QIODevice::setOpenMode
void setOpenMode(QFlags< QIODevice::OpenModeFlag > openMode)
KNetwork::KSocksSocketDevice::~KSocksSocketDevice
virtual ~KSocksSocketDevice()
Destructor.
Definition: k3sockssocketdevice.cpp:61
KNetwork::KSocksSocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: k3sockssocketdevice.cpp:119
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal