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

KDECore

  • 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
43using namespace KNetwork;
44
45// constructor
46// nothing to do
47KSocksSocketDevice::KSocksSocketDevice(const KSocketBase* obj)
48 : KSocketDevice(obj), d(0)
49{
50}
51
52// constructor with argument
53// nothing to do
54KSocksSocketDevice::KSocksSocketDevice(int fd)
55 : KSocketDevice(fd), d(0)
56{
57}
58
59// destructor
60// also nothing to do
61KSocksSocketDevice::~KSocksSocketDevice()
62{
63}
64
65// returns the capabilities
66int 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
74bool 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
98bool 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
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(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
168KSocksSocketDevice* 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
192static 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
216qint64 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
237qint64 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
258qint64 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
279qint64 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
300qint64 KSocksSocketDevice::writeBlock(const char *data, quint64 len)
301{
302 return writeBlock(data, len, KSocketAddress());
303}
304
305qint64 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
327KSocketAddress 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
356KSocketAddress 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
385KSocketAddress KSocksSocketDevice::externalAddress() const
386{
387 // return empty, indicating unknown external address
388 return KSocketAddress();
389}
390
391bool 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
462void 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
480static bool register()
481{
482 KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0);
483}
484
485static bool register = registered();
486#endif
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: k3socketbase.cpp:441
KNetwork::KActiveSocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: k3socketbase.cpp:435
KNetwork::KResolverEntry
One resolution entry.
Definition: k3resolver.h:69
KNetwork::KResolverEntry::address
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:135
KNetwork::KResolverEntry::length
quint16 length() const
Retrieves the length of the socket address structure.
Definition: k3resolver.cpp:141
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:415
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::KSocketAddress::length
quint16 length() const
Returns the length of this socket address structure.
Definition: k3socketaddress.cpp:473
KNetwork::KSocketAddress::setLength
KSocketAddress & setLength(quint16 len)
Sets the length of this socket structure.
Definition: k3socketaddress.cpp:480
KNetwork::KSocketBase
Basic socket functionality.
Definition: k3socketbase.h:86
KNetwork::KSocketBase::SocketError
SocketError
Possible socket error codes.
Definition: k3socketbase.h:144
KNetwork::KSocketBase::NotSupported
@ NotSupported
Definition: k3socketbase.h:159
KNetwork::KSocketBase::InProgress
@ InProgress
Definition: k3socketbase.h:157
KNetwork::KSocketBase::NotCreated
@ NotCreated
Definition: k3socketbase.h:153
KNetwork::KSocketBase::UnknownError
@ UnknownError
Definition: k3socketbase.h:161
KNetwork::KSocketBase::ConnectionRefused
@ ConnectionRefused
Definition: k3socketbase.h:155
KNetwork::KSocketBase::AddressInUse
@ AddressInUse
Definition: k3socketbase.h:147
KNetwork::KSocketBase::NetFailure
@ NetFailure
Definition: k3socketbase.h:158
KNetwork::KSocketBase::WouldBlock
@ WouldBlock
Definition: k3socketbase.h:154
KNetwork::KSocketBase::AlreadyBound
@ AlreadyBound
Definition: k3socketbase.h:149
KNetwork::KSocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: k3socketbase.cpp:102
KNetwork::KSocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: k3socketbase.cpp:97
KNetwork::KSocketDeviceFactory
This class provides functionality for creating and registering socket implementations.
Definition: k3socketdevice.h:402
KNetwork::KSocketDevice
Low-level socket functionality.
Definition: k3socketdevice.h:52
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::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::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::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: k3socketdevice.h:96
KNetwork::KSocksSocketDevice
The low-level class for SOCKS proxying.
Definition: k3sockssocketdevice.h:43
KNetwork::KSocksSocketDevice::peekBlock
virtual qint64 peekBlock(char *data, quint64 maxlen)
Overrides peeking.
Definition: k3sockssocketdevice.cpp:258
KNetwork::KSocksSocketDevice::readBlock
virtual qint64 readBlock(char *data, quint64 maxlen)
Overrides reading.
Definition: k3sockssocketdevice.cpp:216
KNetwork::KSocksSocketDevice::accept
virtual KSocksSocketDevice * accept()
Overrides accepting.
Definition: k3sockssocketdevice.cpp:168
KNetwork::KSocksSocketDevice::writeBlock
virtual qint64 writeBlock(const char *data, quint64 len)
Overrides writing.
Definition: k3sockssocketdevice.cpp:300
KNetwork::KSocksSocketDevice::localAddress
virtual KSocketAddress localAddress() const
Overrides getting socket address.
Definition: k3sockssocketdevice.cpp:327
KNetwork::KSocksSocketDevice::listen
virtual bool listen(int backlog)
Overrides listening.
Definition: k3sockssocketdevice.cpp:98
KNetwork::KSocksSocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: k3sockssocketdevice.cpp:119
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
KNetwork::KSocksSocketDevice::peerAddress
virtual KSocketAddress peerAddress() const
Overrides getting peer address.
Definition: k3sockssocketdevice.cpp:356
KNetwork::KSocksSocketDevice::KSocksSocketDevice
KSocksSocketDevice(const KSocketBase *=0L)
Constructor.
Definition: k3sockssocketdevice.cpp:47
KNetwork::KSocksSocketDevice::externalAddress
virtual KSocketAddress externalAddress() const
Overrides getting external address.
Definition: k3sockssocketdevice.cpp:385
KNetwork::KSocksSocketDevice::~KSocksSocketDevice
virtual ~KSocksSocketDevice()
Destructor.
Definition: k3sockssocketdevice.cpp:61
KNetwork::KSocksSocketDevice::bind
virtual bool bind(const KResolverEntry &address)
Overrides binding.
Definition: k3sockssocketdevice.cpp:74
KNetwork::KSocksSocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: k3sockssocketdevice.cpp:66
qint64
quint64
output
void output(QList< Action > actions, QHash< QString, QString > domain)
Definition: fake/kauth-policy-gen-polkit.cpp:41
k3resolver.h
k3socketaddress.h
k3socks.h
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
k3sockssocketdevice.h
timeout
int timeout
Definition: kkernel_mac.cpp:46
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: k3bufferedsocket.h:35
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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