• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • network
ksockssocketdevice.cpp
1 /*
2  * Copyright (C) 2004 Thiago Macieira <thiago.macieira@kdemail.net>
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 <config.h>
21 
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 
26 #if defined(HAVE_UNISTD_H)
27 #include <unistd.h>
28 #endif
29 
30 #ifdef __CYGWIN__
31 #undef kde_socklen_t
32 #define kde_socklen_t ksocklen_t
33 #endif
34 
35 #include "tdeapplication.h"
36 
37 #include "ksocks.h"
38 #include "tdesocketaddress.h"
39 #include "kresolver.h"
40 #include "ksockssocketdevice.h"
41 
42 using namespace KNetwork;
43 
44 // constructor
45 // nothing to do
46 KSocksSocketDevice::KSocksSocketDevice(const TDESocketBase* obj)
47  : TDESocketDevice(obj)
48 {
49 }
50 
51 // constructor with argument
52 // nothing to do
53 KSocksSocketDevice::KSocksSocketDevice(int fd)
54  : TDESocketDevice(fd)
55 {
56 }
57 
58 // destructor
59 // also nothing to do
60 KSocksSocketDevice::~KSocksSocketDevice()
61 {
62 }
63 
64 // returns the capabilities
65 int KSocksSocketDevice::capabilities() const
66 {
67  return 0; // can do everything!
68 }
69 
70 // From here on, the code is almost exactly a copy of TDESocketDevice
71 // the differences are the use of KSocks where appropriate
72 
73 bool KSocksSocketDevice::bind(const KResolverEntry& address)
74 {
75  resetError();
76 
77  if (m_sockfd == -1 && !create(address))
78  return false; // failed creating
79 
80  // we have a socket, so try and bind
81  if (KSocks::self()->bind(m_sockfd, address.address(), address.length()) == -1)
82  {
83  if (errno == EADDRINUSE)
84  setError(IO_BindError, AddressInUse);
85  else if (errno == EINVAL)
86  setError(IO_BindError, AlreadyBound);
87  else
88  // assume the address is the cause
89  setError(IO_BindError, NotSupported);
90  return false;
91  }
92 
93  return true;
94 }
95 
96 
97 bool KSocksSocketDevice::listen(int backlog)
98 {
99  if (m_sockfd != -1)
100  {
101  if (KSocks::self()->listen(m_sockfd, backlog) == -1)
102  {
103  setError(IO_ListenError, NotSupported);
104  return false;
105  }
106 
107  resetError();
108  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
109  setState(IO_Open);
110  return true;
111  }
112 
113  // we don't have a socket
114  // can't listen
115  setError(IO_ListenError, 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(IO_ConnectError, InProgress);
149  return true;
150  }
151  else if (errno == ECONNREFUSED)
152  setError(IO_ConnectError, ConnectionRefused);
153  else if (errno == ENETDOWN || errno == ENETUNREACH ||
154  errno == ENETRESET || errno == ECONNABORTED ||
155  errno == ECONNRESET || errno == EHOSTDOWN ||
156  errno == EHOSTUNREACH)
157  setError(IO_ConnectError, NetFailure);
158  else
159  setError(IO_ConnectError, NotSupported);
160 
161  return false;
162  }
163 
164  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
165  setState(IO_Open);
166  return true; // all is well
167 }
168 
169 KSocksSocketDevice* KSocksSocketDevice::accept()
170 {
171  if (m_sockfd == -1)
172  {
173  // can't accept without a socket
174  setError(IO_AcceptError, NotCreated);
175  return 0L;
176  }
177 
178  struct sockaddr sa;
179  kde_socklen_t len = sizeof(sa);
180  int newfd = KSocks::self()->accept(m_sockfd, &sa, &len);
181  if (newfd == -1)
182  {
183  if (errno == EAGAIN || errno == EWOULDBLOCK)
184  setError(IO_AcceptError, WouldBlock);
185  else
186  setError(IO_AcceptError, UnknownError);
187  return NULL;
188  }
189 
190  return new KSocksSocketDevice(newfd);
191 }
192 
193 static int socks_read_common(int sockfd, char *data, TQ_ULONG maxlen, TDESocketAddress* from, ssize_t &retval, bool peek = false)
194 {
195  kde_socklen_t len;
196  if (from)
197  {
198  from->setLength(len = 128); // arbitrary length
199  retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
200  }
201  else
202  retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
203 
204  if (retval == -1)
205  {
206  if (errno == EAGAIN || errno == EWOULDBLOCK)
207  return TDESocketDevice::WouldBlock;
208  else
209  return TDESocketDevice::UnknownError;
210  }
211 
212  if (from)
213  from->setLength(len);
214  return 0;
215 }
216 
217 TQ_LONG KSocksSocketDevice::tqreadBlock(char *data, TQ_ULONG maxlen)
218 {
219  resetError();
220  if (m_sockfd == -1)
221  return -1;
222 
223  if (maxlen == 0 || data == 0L)
224  return 0; // can't read
225 
226  ssize_t retval;
227  int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval);
228 
229  if (err)
230  {
231  setError(IO_ReadError, static_cast<SocketError>(err));
232  return -1;
233  }
234 
235  return retval;
236 }
237 
238 TQ_LONG KSocksSocketDevice::tqreadBlock(char *data, TQ_ULONG maxlen, TDESocketAddress &from)
239 {
240  resetError();
241  if (m_sockfd == -1)
242  return -1; // nothing to do here
243 
244  if (data == 0L || maxlen == 0)
245  return 0; // user doesn't want to read
246 
247  ssize_t retval;
248  int err = socks_read_common(m_sockfd, data, maxlen, &from, retval);
249 
250  if (err)
251  {
252  setError(IO_ReadError, static_cast<SocketError>(err));
253  return -1;
254  }
255 
256  return retval;
257 }
258 
259 TQ_LONG KSocksSocketDevice::peekBlock(char *data, TQ_ULONG maxlen)
260 {
261  resetError();
262  if (m_sockfd == -1)
263  return -1;
264 
265  if (maxlen == 0 || data == 0L)
266  return 0; // can't read
267 
268  ssize_t retval;
269  int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true);
270 
271  if (err)
272  {
273  setError(IO_ReadError, static_cast<SocketError>(err));
274  return -1;
275  }
276 
277  return retval;
278 }
279 
280 TQ_LONG KSocksSocketDevice::peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from)
281 {
282  resetError();
283  if (m_sockfd == -1)
284  return -1; // nothing to do here
285 
286  if (data == 0L || maxlen == 0)
287  return 0; // user doesn't want to read
288 
289  ssize_t retval;
290  int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true);
291 
292  if (err)
293  {
294  setError(IO_ReadError, static_cast<SocketError>(err));
295  return -1;
296  }
297 
298  return retval;
299 }
300 
301 TQ_LONG KSocksSocketDevice::tqwriteBlock(const char *data, TQ_ULONG len)
302 {
303  return tqwriteBlock(data, len, TDESocketAddress());
304 }
305 
306 TQ_LONG KSocksSocketDevice::tqwriteBlock(const char *data, TQ_ULONG len, const TDESocketAddress& to)
307 {
308  resetError();
309  if (m_sockfd == -1)
310  return -1; // can't write to unopen socket
311 
312  if (data == 0L || len == 0)
313  return 0; // nothing to be written
314 
315  ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length());
316  if (retval == -1)
317  {
318  if (errno == EAGAIN || errno == EWOULDBLOCK)
319  setError(IO_WriteError, WouldBlock);
320  else
321  setError(IO_WriteError, UnknownError);
322  return -1; // nothing written
323  }
324 
325  return retval;
326 }
327 
328 TDESocketAddress KSocksSocketDevice::localAddress() const
329 {
330  if (m_sockfd == -1)
331  return TDESocketAddress(); // not open, empty value
332 
333  kde_socklen_t len;
334  TDESocketAddress localAddress;
335  localAddress.setLength(len = 32); // arbitrary value
336  if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
337  // error!
338  return TDESocketAddress();
339 
340  if (len <= localAddress.length())
341  {
342  // it has fit already
343  localAddress.setLength(len);
344  return localAddress;
345  }
346 
347  // no, the socket address is actually larger than we had anticipated
348  // call again
349  localAddress.setLength(len);
350  if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1)
351  // error!
352  return TDESocketAddress();
353 
354  return localAddress;
355 }
356 
357 TDESocketAddress KSocksSocketDevice::peerAddress() const
358 {
359  if (m_sockfd == -1)
360  return TDESocketAddress(); // not open, empty value
361 
362  kde_socklen_t len;
363  TDESocketAddress peerAddress;
364  peerAddress.setLength(len = 32); // arbitrary value
365  if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
366  // error!
367  return TDESocketAddress();
368 
369  if (len <= peerAddress.length())
370  {
371  // it has fit already
372  peerAddress.setLength(len);
373  return peerAddress;
374  }
375 
376  // no, the socket address is actually larger than we had anticipated
377  // call again
378  peerAddress.setLength(len);
379  if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1)
380  // error!
381  return TDESocketAddress();
382 
383  return peerAddress;
384 }
385 
386 TDESocketAddress KSocksSocketDevice::externalAddress() const
387 {
388  // return empty, indicating unknown external address
389  return TDESocketAddress();
390 }
391 
392 bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception,
393  int timeout, bool *timedout)
394 {
395  if (m_sockfd == -1)
396  {
397  setError(IO_UnspecifiedError, NotCreated);
398  return false;
399  }
400 
401  resetError();
402  fd_set readfds, writefds, exceptfds;
403  fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
404 
405  if (input)
406  {
407  preadfds = &readfds;
408  FD_ZERO(preadfds);
409  FD_SET(m_sockfd, preadfds);
410  *input = false;
411  }
412  if (output)
413  {
414  pwritefds = &writefds;
415  FD_ZERO(pwritefds);
416  FD_SET(m_sockfd, pwritefds);
417  *output = false;
418  }
419  if (exception)
420  {
421  pexceptfds = &exceptfds;
422  FD_ZERO(pexceptfds);
423  FD_SET(m_sockfd, pexceptfds);
424  *exception = false;
425  }
426 
427  int retval;
428  if (timeout < 0)
429  retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
430  else
431  {
432  // convert the milliseconds to timeval
433  struct timeval tv;
434  tv.tv_sec = timeout / 1000;
435  tv.tv_usec = timeout % 1000 * 1000;
436 
437  retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
438  }
439 
440  if (retval == -1)
441  {
442  setError(IO_UnspecifiedError, UnknownError);
443  return false;
444  }
445  if (retval == 0)
446  {
447  // timeout
448  if (timedout)
449  *timedout = true;
450  return true;
451  }
452 
453  if (input && FD_ISSET(m_sockfd, preadfds))
454  *input = true;
455  if (output && FD_ISSET(m_sockfd, pwritefds))
456  *output = true;
457  if (exception && FD_ISSET(m_sockfd, pexceptfds))
458  *exception = true;
459 
460  return true;
461 }
462 
463 void KSocksSocketDevice::initSocks()
464 {
465  static bool init = false;
466 
467  if (init)
468  return;
469 
470  if (kapp == 0L)
471  return; // no TDEApplication, so don't initialise
472  // this should, however, test for TDEInstance
473 
474  init = true;
475 
476  if (KSocks::self()->hasSocks())
477  delete TDESocketDevice::setDefaultImpl(new TDESocketDeviceFactory<KSocksSocketDevice>);
478 }
479 
480 #if 0
481 static bool register()
482 {
483  TDESocketDevice::addNewImpl(new TDESocketDeviceFactory<KSocksSocketDevice>, 0);
484 }
485 
486 static bool register = registered();
487 #endif
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:423
KNetwork::KSocksSocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: ksockssocketdevice.cpp:65
KNetwork::KSocksSocketDevice::listen
virtual bool listen(int backlog)
Overrides listening.
Definition: ksockssocketdevice.cpp:97
KNetwork::TDESocketDevice::addNewImpl
static void addNewImpl(TDESocketDeviceFactoryBase *factory, int capabilities)
Adds a factory of TDESocketDevice objects to the list, along with its capabilities flag...
Definition: tdesocketdevice.cpp:884
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:66
KNetwork::TDESocketDeviceFactory
This class provides functionality for creating and registering socket implementations.
Definition: tdesocketdevice.h:421
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::KSocksSocketDevice::accept
virtual KSocksSocketDevice * accept()
Overrides accepting.
Definition: ksockssocketdevice.cpp:169
KNetwork::TDESocketDevice::create
virtual bool create(int family, int type, int protocol)
Creates a socket but don't connect or bind anywhere.
Definition: tdesocketdevice.cpp:201
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:50
KSocks::sendto
int sendto(int s, const void *msg, unsigned long int len, int flags, const sockaddr *to, ksocklen_t tolen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:514
KNetwork::KSocksSocketDevice::localAddress
virtual TDESocketAddress localAddress() const
Overrides getting socket address.
Definition: ksockssocketdevice.cpp:328
KNetwork::KResolverEntry::address
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: kresolver.cpp:142
KNetwork::KSocksSocketDevice::bind
virtual bool bind(const KResolverEntry &address)
Overrides binding.
Definition: ksockssocketdevice.cpp:73
KSocks::self
static KSocks * self()
Return an instance of class KSocks *.
Definition: ksocks.cpp:212
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36
KNetwork::KSocksSocketDevice
The low-level class for SOCKS proxying.
Definition: ksockssocketdevice.h:40
KNetwork::TDESocketAddress::setLength
TDESocketAddress & setLength(TQ_UINT16 len)
Sets the length of this socket structure.
Definition: tdesocketaddress.cpp:492
KNetwork::KActiveSocketBase::setError
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
Definition: tdesocketbase.cpp:309
KNetwork::TDESocketDevice::setDefaultImpl
static TDESocketDeviceFactoryBase * setDefaultImpl(TDESocketDeviceFactoryBase *factory)
Sets the default TDESocketDevice implementation to use and return the old factory.
Definition: tdesocketdevice.cpp:876
KNetwork::KSocksSocketDevice::poll
virtual bool poll(bool *input, bool *output, bool *exception=0L, int timeout=-1, bool *timedout=0L)
Overrides polling.
Definition: ksockssocketdevice.cpp:392
KNetwork::KResolverEntry::length
TQ_UINT16 length() const
Retrieves the length of the socket address structure.
Definition: kresolver.cpp:148
KSocks::accept
int accept(int s, sockaddr *addr, ksocklen_t *addrlen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:560
KNetwork::KSocksSocketDevice::tqwriteBlock
virtual TQ_LONG tqwriteBlock(const char *data, TQ_ULONG len)
Overrides writing.
Definition: ksockssocketdevice.cpp:301
KNetwork::TDESocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: tdesocketdevice.h:95
KNetwork::TDESocketAddress::address
const sockaddr * address() const
Returns the socket address structure, to be passed down to low level functions.
Definition: tdesocketaddress.cpp:461
KNetwork::KSocksSocketDevice::tqreadBlock
virtual TQ_LONG tqreadBlock(char *data, TQ_ULONG maxlen)
Overrides reading.
Definition: ksockssocketdevice.cpp:217
KSocks::select
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:572
KNetwork::KSocksSocketDevice::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Overrides peeking.
Definition: ksockssocketdevice.cpp:259
KSocks::recvfrom
int recvfrom(int s, void *buf, unsigned long int len, int flags, sockaddr *from, ksocklen_t *fromlen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:501
KNetwork::TDESocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: tdesocketbase.cpp:76
KSocks::connect
int connect(int sockfd, const sockaddr *serv_addr, ksocklen_t addrlen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:479
KNetwork::KSocksSocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Overrides getting external address.
Definition: ksockssocketdevice.cpp:386
KNetwork::TDESocketBase
Basic socket functionality.
Definition: tdesocketbase.h:97
KNetwork::KSocksSocketDevice::KSocksSocketDevice
KSocksSocketDevice(const TDESocketBase *=0L)
Constructor.
Definition: ksockssocketdevice.cpp:46
KNetwork::KSocksSocketDevice::~KSocksSocketDevice
virtual ~KSocksSocketDevice()
Destructor.
Definition: ksockssocketdevice.cpp:60
KNetwork::KSocksSocketDevice::peerAddress
virtual TDESocketAddress peerAddress() const
Overrides getting peer address.
Definition: ksockssocketdevice.cpp:357
KNetwork::TDESocketAddress::length
TQ_UINT16 length() const
Returns the length of this socket address structure.
Definition: tdesocketaddress.cpp:485
KNetwork::KSocksSocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: ksockssocketdevice.cpp:119

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.