• 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
42using namespace KNetwork;
43
44// constructor
45// nothing to do
46KSocksSocketDevice::KSocksSocketDevice(const TDESocketBase* obj)
47 : TDESocketDevice(obj)
48{
49}
50
51// constructor with argument
52// nothing to do
53KSocksSocketDevice::KSocksSocketDevice(int fd)
54 : TDESocketDevice(fd)
55{
56}
57
58// destructor
59// also nothing to do
60KSocksSocketDevice::~KSocksSocketDevice()
61{
62}
63
64// returns the capabilities
65int 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
73bool 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
97bool 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
119bool 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
169KSocksSocketDevice* 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
193static 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
217TQ_LONG KSocksSocketDevice::readBlock(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
238TQ_LONG KSocksSocketDevice::readBlock(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
259TQ_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
280TQ_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
301TQ_LONG KSocksSocketDevice::writeBlock(const char *data, TQ_ULONG len)
302{
303 return writeBlock(data, len, TDESocketAddress());
304}
305
306TQ_LONG KSocksSocketDevice::writeBlock(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
328TDESocketAddress 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
357TDESocketAddress 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
386TDESocketAddress KSocksSocketDevice::externalAddress() const
387{
388 // return empty, indicating unknown external address
389 return TDESocketAddress();
390}
391
392bool 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
463void KSocksSocketDevice::initSocks()
464{
465 static bool init = false;
466
467 if (init)
468 return;
469
470 if (tdeApp == 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
481static bool register()
482{
483 TDESocketDevice::addNewImpl(new TDESocketDeviceFactory<KSocksSocketDevice>, 0);
484}
485
486static bool register = registered();
487#endif
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::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:67
KNetwork::KResolverEntry::length
TQ_UINT16 length() const
Retrieves the length of the socket address structure.
Definition: kresolver.cpp:148
KNetwork::KResolverEntry::address
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: kresolver.cpp:142
KNetwork::KSocksSocketDevice
The low-level class for SOCKS proxying.
Definition: ksockssocketdevice.h:41
KNetwork::KSocksSocketDevice::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Overrides peeking.
Definition: ksockssocketdevice.cpp:259
KNetwork::KSocksSocketDevice::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Overrides writing.
Definition: ksockssocketdevice.cpp:301
KNetwork::KSocksSocketDevice::localAddress
virtual TDESocketAddress localAddress() const
Overrides getting socket address.
Definition: ksockssocketdevice.cpp:328
KNetwork::KSocksSocketDevice::accept
virtual KSocksSocketDevice * accept()
Overrides accepting.
Definition: ksockssocketdevice.cpp:169
KNetwork::KSocksSocketDevice::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Overrides reading.
Definition: ksockssocketdevice.cpp:217
KNetwork::KSocksSocketDevice::listen
virtual bool listen(int backlog)
Overrides listening.
Definition: ksockssocketdevice.cpp:97
KNetwork::KSocksSocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: ksockssocketdevice.cpp:119
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::KSocksSocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Overrides getting external address.
Definition: ksockssocketdevice.cpp:386
KNetwork::KSocksSocketDevice::KSocksSocketDevice
KSocksSocketDevice(const TDESocketBase *=0L)
Constructor.
Definition: ksockssocketdevice.cpp:46
KNetwork::KSocksSocketDevice::~KSocksSocketDevice
virtual ~KSocksSocketDevice()
Destructor.
Definition: ksockssocketdevice.cpp:60
KNetwork::KSocksSocketDevice::bind
virtual bool bind(const KResolverEntry &address)
Overrides binding.
Definition: ksockssocketdevice.cpp:73
KNetwork::KSocksSocketDevice::peerAddress
virtual TDESocketAddress peerAddress() const
Overrides getting peer address.
Definition: ksockssocketdevice.cpp:357
KNetwork::KSocksSocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: ksockssocketdevice.cpp:65
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:424
KNetwork::TDESocketAddress::setLength
TDESocketAddress & setLength(TQ_UINT16 len)
Sets the length of this socket structure.
Definition: tdesocketaddress.cpp:492
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::TDESocketAddress::length
TQ_UINT16 length() const
Returns the length of this socket address structure.
Definition: tdesocketaddress.cpp:485
KNetwork::TDESocketBase
Basic socket functionality.
Definition: tdesocketbase.h:98
KNetwork::TDESocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: tdesocketbase.cpp:76
KNetwork::TDESocketBase::SocketError
SocketError
Possible socket error codes.
Definition: tdesocketbase.h:153
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::TDESocketDeviceFactory
This class provides functionality for creating and registering socket implementations.
Definition: tdesocketdevice.h:417
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:51
KNetwork::TDESocketDevice::setDefaultImpl
static TDESocketDeviceFactoryBase * setDefaultImpl(TDESocketDeviceFactoryBase *factory)
Sets the default TDESocketDevice implementation to use and return the old factory.
Definition: tdesocketdevice.cpp:871
KNetwork::TDESocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: tdesocketdevice.h:95
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:879
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
KSocks::self
static KSocks * self()
Return an instance of class KSocks *.
Definition: ksocks.cpp:212
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
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
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
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
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
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36

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
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.