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

tdecore

  • tdecore
kextsock.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  **/
20 
21 #include <config.h>
22 
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/times.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <sys/un.h>
29 
30 #include <stdio.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 
34 #include <netdb.h>
35 
36 #include <stdlib.h>
37 #include <unistd.h>
38 
39 #include <tqglobal.h>
40 #include <tqstring.h>
41 #include <tqiodevice.h>
42 #include <tqsocketnotifier.h>
43 #include <tqguardedptr.h>
44 
45 #include "kresolver.h"
46 
47 #include "kdebug.h"
48 #include "kextsock.h"
49 #include "ksockaddr.h"
50 #include "ksocks.h"
51 
52 #ifdef __CYGWIN__
53 #include "netsupp.h"
54 #endif
55 
56 using namespace KNetwork;
57 
58 //
59 // Internal class definitions
60 //
61 
62 class KExtendedSocketPrivate
63 {
64 public:
65  int flags; // socket flags
66  int status; // status
67  int syserror; // the system error value
68 
69  timeval timeout; // connection/acception timeout
70 
71  KResolver resRemote; // the resolved addresses
72  KResolver resLocal; // binding resolution
73  unsigned current; // used by the asynchronous connection
74 
75  ::TDESocketAddress *local; // local socket address
76  ::TDESocketAddress *peer; // peer socket address
77 
78  TQSocketNotifier *qsnIn, *qsnOut;
79  int inMaxSize, outMaxSize;
80  bool emitRead : 1, emitWrite : 1;
81  mutable bool addressReusable : 1, ipv6only : 1;
82 
83  KExtendedSocketPrivate() :
84  flags(0), status(0), syserror(0),
85  current(0), local(0), peer(0),
86  qsnIn(0), qsnOut(0), inMaxSize(-1), outMaxSize(-1), emitRead(false), emitWrite(false),
87  addressReusable(false), ipv6only(false)
88  {
89  timeout.tv_sec = timeout.tv_usec = 0;
90  }
91 };
92 
93 // translate KExtendedSocket flags into KResolver ones
94 static bool process_flags(int flags, int& socktype, int& familyMask, int& outflags)
95 {
96  switch (flags & (KExtendedSocket::streamSocket | KExtendedSocket::datagramSocket | KExtendedSocket::rawSocket))
97  {
98  case 0:
99  /* No flags given, use default */
100 
101  case KExtendedSocket::streamSocket:
102  /* streaming socket requested */
103  socktype = SOCK_STREAM;
104  break;
105 
106  case KExtendedSocket::datagramSocket:
107  /* datagram packet socket requested */
108  socktype = SOCK_DGRAM;
109  break;
110 
111  case KExtendedSocket::rawSocket:
112  /* raw socket requested. I wouldn't do this if I were you... */
113  socktype = SOCK_RAW;
114  break;
115 
116  default:
117  /* the flags were used in an invalid manner */
118  return false;
119  }
120 
121  if (flags & KExtendedSocket::knownSocket)
122  {
123  familyMask = 0;
124  if ((flags & KExtendedSocket::unixSocket) == KExtendedSocket::unixSocket)
125  familyMask |= KResolver::UnixFamily;
126 
127  switch ((flags & (KExtendedSocket::ipv6Socket|KExtendedSocket::ipv4Socket)))
128  {
129  case KExtendedSocket::ipv4Socket:
130  familyMask |= KResolver::IPv4Family;
131  break;
132  case KExtendedSocket::ipv6Socket:
133  familyMask |= KResolver::IPv6Family;
134  break;
135  case KExtendedSocket::inetSocket:
136  familyMask |= KResolver::InternetFamily;
137  break;
138  }
139 
140  // those are all the families we know about
141  }
142  else
143  familyMask = KResolver::KnownFamily;
144 
145  /* check other flags */
146  outflags = (flags & KExtendedSocket::passiveSocket ? KResolver::Passive : 0) |
147  (flags & KExtendedSocket::canonName ? KResolver::CanonName : 0) |
148  (flags & KExtendedSocket::noResolve ? KResolver::NoResolve : 0);
149 
150  if (getenv("TDE_NO_IPV6"))
151  familyMask &= ~KResolver::IPv6Family;
152 
153  return true;
154 }
155 
156 // "skips" at most len bytes from file descriptor fd
157 // that is, we will try and read that much data and discard
158 // it. We will stop when we have read those or when the read
159 // function returns error
160 static int skipData(int fd, unsigned len)
161 {
162  char buf[1024];
163  unsigned skipped = 0;
164  while (len)
165  {
166  int count = sizeof(buf);
167  if ((unsigned)count > len)
168  count = len;
169  count = KSocks::self()->read(fd, buf, count);
170  if (count == -1)
171  return -1;
172  else
173  {
174  len -= count;
175  skipped += count;
176  }
177  }
178  return skipped;
179 }
180 
181 /*
182  * class KExtendedSocket
183  */
184 
185 // default constructor
186 KExtendedSocket::KExtendedSocket() :
187  sockfd(-1), d(new KExtendedSocketPrivate)
188 {
189 }
190 
191 // constructor with hostname
192 KExtendedSocket::KExtendedSocket(const TQString& host, int port, int flags) :
193  sockfd(-1), d(new KExtendedSocketPrivate)
194 {
195  setAddress(host, port);
196  setSocketFlags(flags);
197 }
198 
199 // same
200 KExtendedSocket::KExtendedSocket(const TQString& host, const TQString& service, int flags) :
201  sockfd(-1), d(new KExtendedSocketPrivate)
202 {
203  setAddress(host, service);
204  setSocketFlags(flags);
205 }
206 
207 // destroy the class
208 KExtendedSocket::~KExtendedSocket()
209 {
210  closeNow();
211 
212  if (d->local != NULL)
213  delete d->local;
214  if (d->peer != NULL)
215  delete d->peer;
216 
217  if (d->qsnIn != NULL)
218  delete d->qsnIn;
219  if (d->qsnOut != NULL)
220  delete d->qsnOut;
221 
222  delete d;
223 }
224 
225 void KExtendedSocket::reset()
226 {
227  closeNow();
228  release();
229  d->current = 0;
230  d->status = nothing;
231  d->syserror = 0;
232 }
233 
234 int KExtendedSocket::socketStatus() const
235 {
236  return d->status;
237 }
238 
239 void KExtendedSocket::setSocketStatus(int newstatus)
240 {
241  d->status = newstatus;
242 }
243 
244 void KExtendedSocket::setError(int errorcode, int syserror)
245 {
246  setStatus(errorcode);
247  d->syserror = syserror;
248 }
249 
250 int KExtendedSocket::systemError() const
251 {
252  return d->syserror;
253 }
254 
255 /*
256  * Sets socket flags
257  * This is only allowed if we are in nothing state
258  */
259 int KExtendedSocket::setSocketFlags(int flags)
260 {
261  if (d->status > nothing)
262  return -1; // error!
263 
264  return d->flags = flags;
265 }
266 
267 int KExtendedSocket::socketFlags() const
268 {
269  return d->flags;
270 }
271 
272 /*
273  * Sets socket target hostname
274  * This is only allowed if we are in nothing state
275  */
276 bool KExtendedSocket::setHost(const TQString& host)
277 {
278  if (d->status > nothing)
279  return false; // error!
280 
281  d->resRemote.setNodeName(host);
282  return true;
283 }
284 
285 /*
286  * returns the hostname
287  */
288 TQString KExtendedSocket::host() const
289 {
290  return d->resRemote.nodeName();
291 }
292 
293 /*
294  * Sets the socket target port/service
295  * Same thing: only state 'nothing'
296  */
297 bool KExtendedSocket::setPort(int port)
298 {
299  return setPort(TQString::number(port));
300 }
301 
302 bool KExtendedSocket::setPort(const TQString& service)
303 {
304  if (d->status > nothing)
305  return false; // error
306 
307  d->resRemote.setServiceName(service);
308  return true;
309 }
310 
311 /*
312  * returns the service port number
313  */
314 TQString KExtendedSocket::port() const
315 {
316  return d->resRemote.serviceName();
317 }
318 
319 /*
320  * sets the address
321  */
322 bool KExtendedSocket::setAddress(const TQString& host, int port)
323 {
324  return setHost(host) && setPort(port);
325 }
326 
327 /*
328  * the same
329  */
330 bool KExtendedSocket::setAddress(const TQString& host, const TQString& serv)
331 {
332  return setHost(host) && setPort(serv);
333 }
334 
335 /*
336  * Sets the bind hostname
337  * This is only valid in the 'nothing' state and if this is not a
338  * passiveSocket socket
339  */
340 bool KExtendedSocket::setBindHost(const TQString& host)
341 {
342  if (d->status > nothing || d->flags & passiveSocket)
343  return false; // error
344 
345  d->resLocal.setServiceName(host);
346  return true;
347 }
348 
349 /*
350  * Unsets the bind hostname
351  * same thing
352  */
353 bool KExtendedSocket::unsetBindHost()
354 {
355  return setBindHost(TQString::null);
356 }
357 
358 /*
359  * returns the binding host
360  */
361 TQString KExtendedSocket::bindHost() const
362 {
363  return d->resLocal.serviceName();
364 }
365 
366 /*
367  * Sets the bind port
368  * Same condition as setBindHost
369  */
370 bool KExtendedSocket::setBindPort(int port)
371 {
372  return setBindPort(TQString::number(port));
373 }
374 
375 bool KExtendedSocket::setBindPort(const TQString& service)
376 {
377  if (d->status > nothing || d->flags & passiveSocket)
378  return false; // error
379 
380  d->resLocal.setServiceName(service);
381  return true;
382 }
383 
384 /*
385  * unsets the bind port
386  */
387 bool KExtendedSocket::unsetBindPort()
388 {
389  return setBindPort(TQString::null);
390 }
391 
392 /*
393  * returns the binding port
394  */
395 TQString KExtendedSocket::bindPort() const
396 {
397  return d->resLocal.serviceName();
398 }
399 
400 /*
401  * sets the binding address
402  */
403 bool KExtendedSocket::setBindAddress(const TQString& host, int port)
404 {
405  return setBindHost(host) && setBindPort(port);
406 }
407 
408 /*
409  * same
410  */
411 bool KExtendedSocket::setBindAddress(const TQString& host, const TQString& service)
412 {
413  return setBindHost(host) && setBindPort(service);
414 }
415 
416 /*
417  * unsets binding address
418  */
419 bool KExtendedSocket::unsetBindAddress()
420 {
421  return unsetBindHost() && unsetBindPort();
422 }
423 
424 /*
425  * sets the timeout for the connection
426  */
427 bool KExtendedSocket::setTimeout(int secs, int usecs)
428 {
429  if (d->status >= connected) // closed?
430  return false;
431 
432  d->timeout.tv_sec = secs;
433  d->timeout.tv_usec = usecs;
434  return true;
435 }
436 
437 /*
438  * returns the timeout
439  */
440 timeval KExtendedSocket::timeout() const
441 {
442  return d->timeout;
443 }
444 
445 /*
446  * Sets the blocking mode on this socket
447  */
448 bool KExtendedSocket::setBlockingMode(bool enable)
449 {
450  cleanError();
451  if (d->status < created)
452  return false;
453 
454  if (sockfd == -1)
455  return false; // error!
456 
457  int fdflags = fcntl(sockfd, F_GETFL, 0);
458  if (fdflags == -1)
459  return false; // error!
460 
461  if (!enable)
462  fdflags |= O_NONBLOCK;
463  else
464  fdflags &= ~O_NONBLOCK;
465 
466  if (fcntl(sockfd, F_SETFL, fdflags) == -1)
467  {
468  setError(IO_UnspecifiedError, errno);
469  return false;
470  }
471  return true;
472 }
473 
474 /*
475  * Returns the blocking mode on the socket
476  */
477 bool KExtendedSocket::blockingMode()
478 {
479  cleanError();
480  if (d->status < created)
481  return false; // sockets not created are in blocking mode
482 
483  if (sockfd == -1)
484  return false; // error
485 
486  int fdflags = fcntl(sockfd, F_GETFL, 0);
487  if (fdflags == -1)
488  {
489  setError(IO_UnspecifiedError, errno);
490  return false;
491  }
492  return (fdflags & O_NONBLOCK) == 0; // non-blocking == false
493 }
494 
495 /*
496  * Sets the reusability flag for this socket in the OS
497  */
498 bool KExtendedSocket::setAddressReusable(bool enable)
499 {
500  cleanError();
501  d->addressReusable = enable;
502  if (d->status < created)
503  return true;
504 
505  if (sockfd == -1)
506  return true;
507 
508  if (!setAddressReusable(sockfd, enable))
509  {
510  setError(IO_UnspecifiedError, errno);
511  return false;
512  }
513  return true;
514 }
515 
516 bool KExtendedSocket::setAddressReusable(int fd, bool enable)
517 {
518  if (fd == -1)
519  return false;
520 
521  int on = enable; // just to be on the safe side
522 
523  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
524  return false;
525  return true;
526 }
527 
528 /*
529  * Retrieves the reusability flag for this socket
530  */
531 bool KExtendedSocket::addressReusable()
532 {
533  cleanError();
534  if (d->status < created)
535  return d->addressReusable;
536 
537  if (sockfd == -1)
538  return d->addressReusable;
539 
540  int on;
541  socklen_t onsiz = sizeof(on);
542  if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, &onsiz) == -1)
543  {
544  setError(IO_UnspecifiedError, errno);
545  return false;
546  }
547 
548  return on != 0;
549 }
550 
551 /*
552  * Set the IPV6_V6ONLY flag
553  */
554 bool KExtendedSocket::setIPv6Only(bool enable)
555 {
556 #ifdef IPV6_V6ONLY
557  cleanError();
558 
559  d->ipv6only = enable;
560  if (sockfd == -1)
561  return true; // can't set on a non-existing socket
562 
563  int on = enable;
564 
565  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
566  (char *)&on, sizeof(on)) == -1)
567  {
568  setError(IO_UnspecifiedError, errno);
569  return false;
570  }
571  else
572  return true;
573 
574 #else
575  // we don't have the IPV6_V6ONLY constant in this system
576  d->ipv6only = enable;
577 
578  setError(IO_UnspecifiedError, ENOSYS);
579  return false; // can't set if we don't know about this flag
580 #endif
581 }
582 
583 /*
584  * retrieve the IPV6_V6ONLY flag
585  */
586 bool KExtendedSocket::isIPv6Only()
587 {
588 #ifdef IPV6_V6ONLY
589  cleanError();
590 
591  if (d->status < created || sockfd == -1)
592  return d->ipv6only;
593 
594  int on;
595  socklen_t onsiz = sizeof(on);
596  if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
597  (char *)&on, &onsiz) == -1)
598  {
599  setError(IO_UnspecifiedError, errno);
600  return false;
601  }
602 
603  return d->ipv6only = on;
604 
605 #else
606  // we don't have the constant
607  setError(IO_UnspecifiedError, ENOSYS);
608  return false;
609 #endif
610 }
611 
612 /*
613  * Sets the buffer sizes in this socket
614  * Also, we create or delete the socket notifiers
615  */
616 bool KExtendedSocket::setBufferSize(int rsize, int wsize)
617 {
618  cleanError();
619  if (d->status < created)
620  return false;
621 
622  if (sockfd == -1)
623  return false;
624 
625  if (d->flags & passiveSocket)
626  return false; // no I/O on passive sockets
627 
628  if (rsize < -2)
629  return false;
630 
631  if (wsize < -2)
632  return false;
633 
634  // LOCK BUFFER MUTEX
635 
636  // The input socket notifier is always enabled
637  // That happens because we want to be notified of when the socket gets
638  // closed
639  if (d->qsnIn == NULL)
640  {
641  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
642  TQObject::connect(d->qsnIn, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityRead()));
643  d->qsnIn->setEnabled(true);
644  }
645 
646  if (rsize == 0 && d->flags & inputBufferedSocket)
647  {
648  // user wants to disable input buffering
649  d->flags &= ~inputBufferedSocket;
650 
651  consumeReadBuffer(readBufferSize(), NULL, true);
652  d->inMaxSize = 0;
653  }
654  else if (rsize != -2)
655  {
656  // enabling input buffering
657  if (rsize)
658  d->flags |= inputBufferedSocket;
659  d->inMaxSize = rsize;
660 
661  if (rsize > 0 && (unsigned)rsize < readBufferSize())
662  // input buffer has more data than the new size; discard
663  consumeReadBuffer(readBufferSize() - rsize, NULL, true);
664 
665  }
666 
667  if (wsize == 0 && d->flags & outputBufferedSocket)
668  {
669  // disabling output buffering
670  d->flags &= ~outputBufferedSocket;
671  if (d->qsnOut && !d->emitWrite)
672  d->qsnOut->setEnabled(false);
673  consumeWriteBuffer(writeBufferSize());
674  d->outMaxSize = 0;
675  }
676  else if (wsize != -2)
677  {
678  // enabling input buffering
679  if (wsize)
680  d->flags |= outputBufferedSocket;
681  d->outMaxSize = wsize;
682 
683  if (wsize > 0 && (unsigned)wsize < writeBufferSize())
684  // output buffer is bigger than it is to become; shrink
685  consumeWriteBuffer(writeBufferSize() - wsize);
686 
687  if (d->qsnOut == NULL)
688  {
689  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
690  TQObject::connect(d->qsnOut, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityWrite()));
691  // if the class is being created now, there's nothing to write yet
692  // so socketActivityWrite() will get called once and disable
693  // the notifier
694  }
695  }
696 
697  // UNLOCK BUFFER MUTEX
698 
699  setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw));
700 
701  // check we didn't turn something off we shouldn't
702  if (d->emitWrite && d->qsnOut == NULL)
703  {
704  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
705  TQObject::connect(d->qsnOut, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityWrite()));
706  }
707 
708  return true;
709 }
710 
711 /*
712  * Finds the local address for this socket
713  * if we have done this already, we return it. Otherwise, we'll have
714  * to find the socket name
715  */
716 const ::TDESocketAddress *KExtendedSocket::localAddress()
717 {
718  if (d->local != NULL)
719  return d->local;
720  if (d->status < bound)
721  return NULL;
722 
723  return d->local = localAddress(sockfd);
724 }
725 
726 /*
727  * Same thing, but for peer address. Which means this does not work on
728  * passiveSocket and that we require to be connected already. Also note that
729  * the behavior on connectionless sockets is not defined here.
730  */
731 const ::TDESocketAddress* KExtendedSocket::peerAddress()
732 {
733  if (d->peer != NULL)
734  return d->peer;
735  if (d->flags & passiveSocket || d->status < connected)
736  return NULL;
737 
738  return d->peer = peerAddress(sockfd);
739 }
740 
741 /*
742  * Perform the lookup on the addresses given
743  */
744 int KExtendedSocket::lookup()
745 {
746  if (startAsyncLookup() != 0)
747  return -1;
748 
749  if (!d->resRemote.wait() || !d->resLocal.wait())
750  {
751  d->status = nothing;
752  return -1;
753  }
754 
755  d->status = lookupDone;
756  if (d->resRemote.error() != KResolver::NoError)
757  return d->resRemote.error();
758  if (d->resLocal.error() != KResolver::NoError)
759  return d->resLocal.error();
760  return 0;
761 }
762 
763 /*
764  * Performs an asynchronous lookup on the given address(es)
765  */
766 int KExtendedSocket::startAsyncLookup()
767 {
768  cleanError();
769  if (d->status > lookupInProgress)
770  return -1;
771  if (d->status == lookupInProgress)
772  // already in progress
773  return 0;
774 
775  /* check socket type flags */
776  int socktype, familyMask, flags;
777  if (!process_flags(d->flags, socktype, familyMask, flags))
778  return -2;
779 
780  // perform the global lookup before
781  if (!d->resRemote.isRunning())
782  {
783  d->resRemote.setFlags(flags);
784  d->resRemote.setFamily(familyMask);
785  d->resRemote.setSocketType(socktype);
786  TQObject::connect(&d->resRemote, TQ_SIGNAL(finished(KResolverResults)),
787  this, TQ_SLOT(dnsResultsReady()));
788 
789  if (!d->resRemote.start())
790  {
791  setError(IO_LookupError, d->resRemote.error());
792  return d->resRemote.error();
793  }
794  }
795 
796  if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning())
797  {
798  /* keep flags, but make this passive */
799  flags |= KResolver::Passive;
800  d->resLocal.setFlags(flags);
801  d->resLocal.setFamily(familyMask);
802  d->resLocal.setSocketType(socktype);
803  TQObject::connect(&d->resLocal, TQ_SIGNAL(finished(KResolverResults)),
804  this, TQ_SLOT(dnsResultsReady()));
805 
806  if (!d->resLocal.start())
807  {
808  setError(IO_LookupError, d->resLocal.error());
809  return d->resLocal.error();
810  }
811  }
812 
813  // if we are here, there were no errors
814  if (d->resRemote.isRunning() || d->resLocal.isRunning())
815  d->status = lookupInProgress; // only if there actually is a running lookup
816  else
817  {
818  d->status = lookupDone;
819  emit lookupFinished(d->resRemote.results().count() +
820  d->resLocal.results().count());
821  }
822  return 0;
823 }
824 
825 void KExtendedSocket::cancelAsyncLookup()
826 {
827  cleanError();
828  if (d->status != lookupInProgress)
829  return; // what's to cancel?
830 
831  d->status = nothing;
832  d->resLocal.cancel(false);
833  d->resRemote.cancel(false);
834 }
835 
836 int KExtendedSocket::listen(int N)
837 {
838  cleanError();
839  if ((d->flags & passiveSocket) == 0 || d->status >= listening)
840  return -2;
841  if (d->status < lookupDone)
842  if (lookup() != 0)
843  return -2; // error!
844  if (d->resRemote.error())
845  return -2;
846 
847  // doing the loop:
848  KResolverResults::const_iterator it;
849  KResolverResults res = d->resRemote.results();
850  for (it = res.begin(); it != res.end(); ++it)
851  {
852  //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl;
853  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
854  if (sockfd == -1)
855  {
856  // socket failed creating
857  //kdDebug(170) << "Failed to create: " << perror << endl;
858  continue;
859  }
860 
861  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
862 
863  if (d->addressReusable)
864  setAddressReusable(sockfd, true);
865  setIPv6Only(d->ipv6only);
866  cleanError();
867  if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1)
868  {
869  //kdDebug(170) << "Failed to bind: " << perror << endl;
870  ::close(sockfd);
871  sockfd = -1;
872  continue;
873  }
874 
875  // ok, socket has bound
876  // kdDebug(170) << "Socket bound: " << sockfd << endl;
877 
878  d->status = bound;
879  break;
880  }
881 
882  if (sockfd == -1)
883  {
884  setError(IO_ListenError, errno);
885  //kdDebug(170) << "Listen error - sockfd is -1 " << endl;
886  return -1;
887  }
888 
889  d->status = bound;
890  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
891 
892  int retval = KSocks::self()->listen(sockfd, N);
893  if (retval == -1)
894  setError(IO_ListenError, errno);
895  else
896  {
897  d->status = listening;
898  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
899  TQObject::connect(d->qsnIn, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityRead()));
900  }
901  return retval == -1 ? -1 : 0;
902 }
903 
904 int KExtendedSocket::accept(KExtendedSocket *&sock)
905 {
906  cleanError();
907  sock = NULL;
908  if ((d->flags & passiveSocket) == 0 || d->status >= accepting)
909  return -2;
910  if (d->status < listening)
911  if (listen() < 0)
912  return -2; // error!
913 
914  // let's see
915  // if we have a timeout in place, we have to place this socket in non-blocking
916  // mode
917  bool block = blockingMode();
918  struct sockaddr sa;
919  ksocklen_t len = sizeof(sa);
920  sock = NULL;
921 
922  if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0)
923  {
924  fd_set set;
925 
926  setBlockingMode(false); // turn on non-blocking
927  FD_ZERO(&set);
928  FD_SET(sockfd, &set);
929 
930  //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n",
931  // sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
932  // check if there is anything to accept now
933  int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout);
934  if (retval == -1)
935  {
936  setError(IO_UnspecifiedError, errno);
937  return -1; // system error
938  }
939  else if (retval == 0 || !FD_ISSET(sockfd, &set))
940  {
941  setError(IO_TimeOutError, 0);
942  return -3; // timeout
943  }
944  }
945 
946  // it's common stuff here
947  int newfd = KSocks::self()->accept(sockfd, &sa, &len);
948 
949  if (newfd == -1)
950  {
951  setError(IO_AcceptError, errno);
952  kdWarning(170) << "Error accepting on socket " << sockfd << ":"
953  << perror << endl;
954  return -1;
955  }
956 
957  fcntl(newfd, F_SETFD, FD_CLOEXEC);
958 
959  //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd);
960 
961  setBlockingMode(block); // restore blocking mode
962 
963  sock = new KExtendedSocket;
964  sock->d->status = connected;
965  sock->sockfd = newfd;
966  sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
967  sock->setBufferSize(0, 0); // always unbuffered here. User can change that later
968 
969  return 0;
970 }
971 
972 /*
973  * tries to connect
974  *
975  * FIXME!
976  * This function is critical path. It has to be cleaned up and made faster
977  */
978 int KExtendedSocket::connect()
979 {
980  cleanError();
981  if (d->flags & passiveSocket || d->status >= connected)
982  return -2;
983  if (d->status < lookupDone)
984  if (lookup() != 0)
985  return -2;
986 
987  timeval end, now;
988  timeval timeout_copy = d->timeout;
989  // Ok, things are a little tricky here
990  // Let me explain
991  // getaddrinfo() will return several different families of sockets
992  // When we have to bind before we connect, we have to make sure we're binding
993  // and connecting to the same family, or things won't work
994 
995  KResolverResults remote = d->resRemote.results(),
996  local = d->resLocal.results();
997  KResolverResults::const_iterator it, it2;
998  //kdDebug(170) << "Starting connect to " << host() << '|' << port()
999  // << ": have " << local.count() << " local entries and "
1000  // << remote.count() << " remote" << endl;
1001 
1002  int ret = -1;
1003  for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
1004  {
1005  bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
1006  if (doingtimeout)
1007  {
1008  gettimeofday(&end, NULL);
1009  end.tv_usec += d->timeout.tv_usec;
1010  end.tv_sec += d->timeout.tv_sec;
1011  if (end.tv_usec > 1000*1000)
1012  {
1013  end.tv_usec -= 1000*1000;
1014  end.tv_sec++;
1015  }
1016  //kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n",
1017  // d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec);
1018  }
1019 
1020  //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl;
1021  if (it2 != local.end())
1022  {
1023 // //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl;
1024  if ((*it).family() != (*it2).family())
1025  // differing families, scan local for a matching family
1026  for (it2 = local.begin(); it2 != local.end(); ++it2)
1027  if ((*it).family() == (*it2).family())
1028  break;
1029 
1030  if ((*it).family() != (*it2).family())
1031  {
1032  // no matching families for this
1033  //kdDebug(170) << "No matching family for bind socket\n";
1034  it2 = local.begin();
1035  continue;
1036  }
1037 
1038  //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl;
1039  errno = 0;
1040  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
1041  setError(IO_ConnectError, errno);
1042  if (sockfd == -1)
1043  continue; // cannot create this socket
1044  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1045  if (d->addressReusable)
1046  setAddressReusable(sockfd, true);
1047  setIPv6Only(d->ipv6only);
1048  cleanError();
1049  if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
1050  {
1051  //kdDebug(170) << "Bind failed: " << perror << endl;
1052  ::close(sockfd);
1053  sockfd = -1;
1054  continue;
1055  }
1056  }
1057  else
1058  {
1059  // no need to bind, just create
1060  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
1061  if (sockfd == -1)
1062  {
1063  setError(IO_ConnectError, errno);
1064  continue;
1065  }
1066  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1067  if (d->addressReusable)
1068  setAddressReusable(sockfd, true);
1069  setIPv6Only(d->ipv6only);
1070  cleanError();
1071  }
1072 
1073 // kdDebug(170) << "Socket " << sockfd << " created" << endl;
1074  d->status = created;
1075 
1076  // check if we have to do timeout
1077  if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
1078  {
1079  fd_set rd, wr;
1080 
1081  setBlockingMode(false);
1082 
1083  // now try and connect
1084  if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
1085  {
1086  // this could be EWOULDBLOCK
1087  if (errno != EWOULDBLOCK && errno != EINPROGRESS)
1088  {
1089  //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl;
1090  setError(IO_ConnectError, errno);
1091  ::close(sockfd);
1092  sockfd = -1;
1093  continue; // nope, another error
1094  }
1095 
1096  FD_ZERO(&rd);
1097  FD_ZERO(&wr);
1098  FD_SET(sockfd, &rd);
1099  FD_SET(sockfd, &wr);
1100 
1101  int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
1102  if (retval == -1)
1103  {
1104  setError(IO_FatalError, errno);
1105  continue; // system error
1106  }
1107  else if (retval == 0)
1108  {
1109  ::close(sockfd);
1110  sockfd = -1;
1111 // kdDebug(170) << "Time out while trying to connect to " <<
1112 // (*it).address().toString() << endl;
1113  setError(IO_TimeOutError, 0);
1114  ret = -3; // time out
1115 
1116  d->timeout.tv_usec += timeout_copy.tv_usec;
1117  d->timeout.tv_sec += timeout_copy.tv_sec;
1118  if (d->timeout.tv_usec < 0)
1119  {
1120  d->timeout.tv_usec += 1000*1000;
1121  d->timeout.tv_sec--;
1122  }
1123 
1124  continue;
1125  }
1126 
1127  // adjust remaining time
1128  gettimeofday(&now, NULL);
1129  d->timeout.tv_sec = end.tv_sec - now.tv_sec;
1130  d->timeout.tv_usec = end.tv_usec - now.tv_usec;
1131  if (d->timeout.tv_usec < 0)
1132  {
1133  d->timeout.tv_usec += 1000*1000;
1134  d->timeout.tv_sec--;
1135  }
1136 // kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n",
1137 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
1138 
1139  // this means that an event occurred in the socket
1140  int errcode;
1141  socklen_t len = sizeof(errcode);
1142  retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
1143  &len);
1144  if (retval == -1 || errcode != 0)
1145  {
1146  // socket did not connect
1147  //kdDebug(170) << "Socket " << sockfd << " did not connect: "
1148  // << strerror(errcode) << endl;
1149  ::close(sockfd);
1150  sockfd = -1;
1151 
1152  // this is HIGHLY UNLIKELY
1153  if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
1154  {
1155  d->status = lookupDone;
1156  setError(IO_TimeOutError, 0);
1157  return -3; // time out
1158  }
1159 
1160  setError(IO_ConnectError, errcode);
1161  continue;
1162  }
1163  }
1164 
1165  // getting here means it connected
1166  // setBufferSize() takes care of creating the socket notifiers
1167  setBlockingMode(true);
1168  d->status = connected;
1169  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1170  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1171  d->flags & outputBufferedSocket ? -1 : 0);
1172  emit connectionSuccess();
1173 // kdDebug(170) << "Socket " << sockfd << " connected\n";
1174  return 0;
1175  }
1176  else
1177  {
1178  // without timeouts
1179  if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
1180  {
1181  //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString()
1182  // << " did not connect: " << perror << endl;
1183  setError(IO_ConnectError, errno);
1184  ::close(sockfd);
1185  sockfd = -1;
1186  continue;
1187  }
1188 
1189  d->status = connected;
1190  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1191  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1192  d->flags & outputBufferedSocket ? -1 : 0);
1193  emit connectionSuccess();
1194 // kdDebug(170) << "Socket " << sockfd << " connected\n";
1195  return 0; // it connected
1196  }
1197  }
1198 
1199  // getting here means no socket connected or stuff like that
1200  emit connectionFailed(d->syserror);
1201  //kdDebug(170) << "Failed to connect\n";
1202  return ret;
1203 }
1204 
1205 int KExtendedSocket::startAsyncConnect()
1206 {
1207  cleanError();
1208  // check status
1209  if (d->status >= connected || d->flags & passiveSocket)
1210  return -2;
1211 
1212  if (d->status == connecting)
1213  // already on async connect
1214  return 0;
1215 
1216  // check if we have to do lookup
1217  // if we do, then we'll use asynchronous lookup and use
1218  // signal lookupFinished to do connection
1219  if (d->status < lookupDone)
1220  {
1221  TQObject::connect(this, TQ_SIGNAL(lookupFinished(int)), this, TQ_SLOT(startAsyncConnectSlot()));
1222  if (d->status < lookupInProgress)
1223  return startAsyncLookup();
1224  else
1225  return 0; // we still have to wait
1226  }
1227 
1228  // here we have d->status >= lookupDone and <= connecting
1229  // we can do our connection
1230  d->status = connecting;
1231  TQGuardedPtr<TQObject> p = this;
1232  connectionEvent();
1233  if (!p)
1234  return -1; // We have been deleted.
1235  if (d->status < connecting)
1236  return -1;
1237  return 0;
1238 }
1239 
1240 void KExtendedSocket::cancelAsyncConnect()
1241 {
1242  if (d->status != connecting)
1243  return;
1244 
1245  if (sockfd != -1)
1246  {
1247  // we have a waiting connection
1248  if (d->qsnIn)
1249  delete d->qsnIn;
1250  if (d->qsnOut)
1251  delete d->qsnOut;
1252  d->qsnIn = d->qsnOut = NULL;
1253 
1254  ::close(sockfd);
1255  sockfd = -1;
1256  }
1257  d->status = lookupDone;
1258 }
1259 
1260 bool KExtendedSocket::open(int mode)
1261 {
1262  if (mode != IO_Raw | IO_ReadWrite)
1263  return false; // invalid open mode
1264 
1265  if (d->flags & passiveSocket)
1266  return listen() == 0;
1267  else if (d->status < connecting)
1268  return connect() == 0;
1269  else
1270  return false;
1271 }
1272 
1273 void KExtendedSocket::close()
1274 {
1275  if (sockfd == -1 || d->status >= closing)
1276  return; // nothing to close
1277 
1278  // LOCK BUFFER MUTEX
1279  if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
1280  {
1281  // write buffer not empty, go into closing state
1282  d->status = closing;
1283  if (d->qsnIn)
1284  delete d->qsnIn;
1285  d->qsnIn = NULL;
1286  // we keep the outgoing socket notifier because we want
1287  // to send data, but not receive
1288  }
1289  else
1290  {
1291  // nope, write buffer is empty
1292  // we can close now
1293  if (d->qsnIn)
1294  delete d->qsnIn;
1295  if (d->qsnOut)
1296  delete d->qsnOut;
1297  d->qsnIn = d->qsnOut = NULL;
1298 
1299  ::close(sockfd);
1300  d->status = done;
1301  emit closed(readBufferSize() != 0 ? availRead : 0);
1302  }
1303  // UNLOCK BUFFER MUTEX
1304 }
1305 
1306 
1307 void KExtendedSocket::closeNow()
1308 {
1309  if (d->status >= done)
1310  return; // nothing to close
1311 
1312  // close the socket
1313  delete d->qsnIn;
1314  delete d->qsnOut;
1315  d->qsnIn = d->qsnOut = NULL;
1316 
1317  if (d->status > connecting && sockfd != -1)
1318  {
1319  ::close(sockfd);
1320  sockfd = -1;
1321  }
1322  else if (d->status == connecting)
1323  cancelAsyncConnect();
1324  else if (d->status == lookupInProgress)
1325  cancelAsyncLookup();
1326 
1327  d->status = done;
1328 
1329  emit closed(closedNow |
1330  (readBufferSize() != 0 ? availRead : 0) |
1331  (writeBufferSize() != 0 ? dirtyWrite : 0));
1332 }
1333 
1334 void KExtendedSocket::release()
1335 {
1336  // release our hold on the socket
1337  sockfd = -1;
1338  d->status = done;
1339 
1340  d->resRemote.cancel(false);
1341  d->resLocal.cancel(false);
1342 
1343  if (d->local != NULL)
1344  delete d->local;
1345  if (d->peer != NULL)
1346  delete d->peer;
1347 
1348  d->peer = d->local = NULL;
1349 
1350  if (d->qsnIn != NULL)
1351  delete d->qsnIn;
1352  if (d->qsnOut != NULL)
1353  delete d->qsnOut;
1354 
1355  d->qsnIn = d->qsnOut = NULL;
1356 
1357  // now that the socket notificators are done with, we can flush out the buffers
1358  consumeReadBuffer(readBufferSize(), NULL, true);
1359  consumeWriteBuffer(writeBufferSize());
1360 
1361  // don't delete d
1362  // leave that for the destructor
1363 }
1364 
1365 void KExtendedSocket::flush()
1366 {
1367  cleanError();
1368  if (d->status < connected || d->status >= done || d->flags & passiveSocket)
1369  return;
1370 
1371  if (sockfd == -1)
1372  return;
1373 
1374  if ((d->flags & outputBufferedSocket) == 0)
1375  return; // nothing to do
1376 
1377  // LOCK MUTEX
1378 
1379  unsigned written = 0;
1380  unsigned offset = outBufIndex; // this happens only for the first
1381  while (writeBufferSize() - written > 0)
1382  {
1383  // we have to write each output buffer in outBuf
1384  // but since we can have several very small buffers, we can make things
1385  // better by concatenating a few of them into a big buffer
1386  // question is: how big should that buffer be? 16 kB should be enough
1387 
1388  TQByteArray buf(16384);
1389  TQByteArray *a = outBuf.first();
1390  unsigned count = 0;
1391 
1392  while (a && count + (a->size() - offset) <= buf.size())
1393  {
1394  memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
1395  count += a->size() - offset;
1396  offset = 0;
1397  a = outBuf.next();
1398  }
1399 
1400  // see if we can still fit more
1401  if (a && count < buf.size())
1402  {
1403  // getting here means this buffer (a) is larger than
1404  // (buf.size() - count) (even for count == 0).
1405  memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
1406  offset += buf.size() - count;
1407  count = buf.size();
1408  }
1409 
1410  // now try to write those bytes
1411  int wrote = KSocks::self()->write(sockfd, buf, count);
1412 
1413  if (wrote == -1)
1414  {
1415  // could be EAGAIN (EWOULDBLOCK)
1416  setError(IO_WriteError, errno);
1417  break;
1418  }
1419  written += wrote;
1420 
1421  if ((unsigned)wrote != count)
1422  break;
1423  }
1424  if (written)
1425  {
1426  consumeWriteBuffer(written);
1427  emit bytesWritten(written);
1428  }
1429 
1430  // UNLOCK MUTEX
1431 }
1432 
1433 
1434 TQ_LONG KExtendedSocket::readBlock(char *data, TQ_ULONG maxlen)
1435 {
1436  cleanError();
1437  if (d->status < connected || d->flags & passiveSocket)
1438  return -2;
1439 
1440  int retval;
1441 
1442  if ((d->flags & inputBufferedSocket) == 0)
1443  {
1444  // we aren't buffering this socket, so just pass along
1445  // the call to the real read method
1446 
1447  if (sockfd == -1)
1448  return -2;
1449  if (data)
1450  retval = KSocks::self()->read(sockfd, data, maxlen);
1451  else
1452  retval = skipData(sockfd, maxlen);
1453  if (retval == -1)
1454  setError(IO_ReadError, errno);
1455  }
1456  else
1457  {
1458  // this socket is being buffered. So read from the buffer
1459 
1460  // LOCK BUFFER MUTEX
1461 
1462  retval = consumeReadBuffer(maxlen, data);
1463  if (retval == 0)
1464  {
1465  // consumeReadBuffer returns 0 only if the buffer is
1466  // empty
1467  if (sockfd == -1)
1468  return 0; // buffer is clear now, indicate EOF
1469  setError(IO_ReadError, EWOULDBLOCK);
1470  retval = -1;
1471  }
1472 
1473  // UNLOCK BUFFER MUTEX
1474 
1475  }
1476  return retval;
1477 }
1478 
1479 TQ_LONG KExtendedSocket::writeBlock(const char *data, TQ_ULONG len)
1480 {
1481  cleanError();
1482  if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
1483  return -2;
1484  if (sockfd == -1)
1485  return -2;
1486 
1487  if (len == 0)
1488  return 0; // what's to write?
1489 
1490  int retval;
1491 
1492  if ((d->flags & outputBufferedSocket) == 0)
1493  {
1494  // socket not buffered. Just call write
1495  retval = KSocks::self()->write(sockfd, data, len);
1496  if (retval == -1)
1497  setError(IO_WriteError, errno);
1498  else
1499  emit bytesWritten(retval);
1500  }
1501  else
1502  {
1503  // socket is buffered. Feed the write buffer
1504 
1505  // LOCK BUFFER MUTEX
1506 
1507  unsigned wsize = writeBufferSize();
1508  if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning
1509  {
1510  // buffer is full!
1511  setError(IO_WriteError, EWOULDBLOCK);
1512  retval = -1;
1513  }
1514  else
1515  {
1516  if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
1517  // we cannot write all data. Write just as much as to fill the buffer
1518  len = d->outMaxSize - wsize;
1519 
1520  // len > 0 here
1521  retval = feedWriteBuffer(len, data);
1522  if (wsize == 0 || d->emitWrite)
1523  // buffer was empty, which means that the notifier is probably disabled
1524  d->qsnOut->setEnabled(true);
1525  }
1526 
1527  // UNLOCK BUFFER MUTEX
1528  }
1529 
1530  return retval;
1531 }
1532 
1533 int KExtendedSocket::peekBlock(char *data, uint maxlen)
1534 {
1535  if (d->status < connected || d->flags & passiveSocket)
1536  return -2;
1537  if (sockfd == -1)
1538  return -2;
1539 
1540  // need to LOCK MUTEX around this call...
1541 
1542  if (d->flags & inputBufferedSocket)
1543  return consumeReadBuffer(maxlen, data, false);
1544 
1545  return 0;
1546 }
1547 
1548 int KExtendedSocket::unreadBlock(const char *, uint)
1549 {
1550  // Always return -1, indicating this is not supported
1551  setError(IO_ReadError, ENOSYS);
1552  return -1;
1553 }
1554 
1555 int KExtendedSocket::bytesAvailable() const
1556 {
1557  if (d->status < connected || d->flags & passiveSocket)
1558  return -2;
1559 
1560  // as of now, we don't do any extra processing
1561  // we only work in input-buffered sockets
1562  if (d->flags & inputBufferedSocket)
1563  return TDEBufferedIO::bytesAvailable();
1564 
1565  return 0; // TODO: FIONREAD ioctl
1566 }
1567 
1568 int KExtendedSocket::waitForMore(int msecs)
1569 {
1570  cleanError();
1571  if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
1572  return -2;
1573  if (sockfd == -1)
1574  return -2;
1575 
1576  fd_set rd;
1577  FD_ZERO(&rd);
1578  FD_SET(sockfd, &rd);
1579  timeval tv;
1580  tv.tv_sec = msecs / 1000;
1581  tv.tv_usec = (msecs % 1000) * 1000;
1582 
1583  int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
1584  if (retval == -1)
1585  {
1586  setError(IO_FatalError, errno);
1587  return -1;
1588  }
1589  else if (retval != 0)
1590  socketActivityRead(); // do read processing
1591 
1592  return bytesAvailable();
1593 }
1594 
1595 int KExtendedSocket::getch()
1596 {
1597  unsigned char c;
1598  int retval;
1599  retval = readBlock((char*)&c, sizeof(c));
1600 
1601  if (retval < 0)
1602  return retval;
1603  return c;
1604 }
1605 
1606 int KExtendedSocket::putch(int ch)
1607 {
1608  unsigned char c = (char)ch;
1609  return writeBlock((char*)&c, sizeof(c));
1610 }
1611 
1612 // sets the emission of the readyRead signal
1613 void KExtendedSocket::enableRead(bool enable)
1614 {
1615  // check if we can disable the socket notifier
1616  // saves us a few cycles
1617  // this is so because in buffering mode, we rely on these signals
1618  // being emitted to do our I/O. We couldn't disable them here
1619  if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
1620  d->qsnIn->setEnabled(false);
1621  else if (enable && d->qsnIn)
1622  // we can enable it always
1623  d->qsnIn->setEnabled(true);
1624  d->emitRead = enable;
1625 }
1626 
1627 // sets the emission of the readyWrite signal
1628 void KExtendedSocket::enableWrite(bool enable)
1629 {
1630  // same thing as above
1631  if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
1632  d->qsnOut->setEnabled(false);
1633  else if (enable && d->qsnOut)
1634  // we can enable it always
1635  d->qsnOut->setEnabled(true);
1636  d->emitWrite = enable;
1637 }
1638 
1639 // protected slot
1640 // this is connected to d->qsnIn::activated(int)
1641 void KExtendedSocket::socketActivityRead()
1642 {
1643  if (d->flags & passiveSocket)
1644  {
1645  emit readyAccept();
1646  return;
1647  }
1648  if (d->status == connecting)
1649  {
1650  connectionEvent();
1651  return;
1652  }
1653  if (d->status != connected)
1654  return;
1655 
1656  // do we need to do I/O here?
1657  if (d->flags & inputBufferedSocket)
1658  {
1659  // aye. Do read from the socket and feed our buffer
1660  TQByteArray a;
1661  char buf[1024];
1662  int len, totalread = 0;
1663 
1664  // LOCK MUTEX
1665 
1666  unsigned cursize = readBufferSize();
1667 
1668  if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
1669  {
1670  do
1671  {
1672  // check that we can read that many bytes
1673  if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
1674  // no, that would overrun the buffer
1675  // note that this will also make us exit the loop
1676  len = d->inMaxSize - (cursize + totalread);
1677  else
1678  len = sizeof(buf);
1679 
1680  len = KSocks::self()->read(sockfd, buf, len);
1681  if (len > 0)
1682  {
1683  // normal read operation
1684  a.resize(a.size() + len);
1685  memcpy(a.data() + totalread, buf, len);
1686  totalread += len; // totalread == a.size() now
1687  }
1688  else if (len == 0)
1689  {
1690  // EOF condition here
1691  ::close(sockfd);
1692  sockfd = -1; // we're closed
1693  d->qsnIn->deleteLater();
1694  delete d->qsnOut;
1695  d->qsnIn = d->qsnOut = NULL;
1696  d->status = done;
1697  emit closed(involuntary |
1698  (readBufferSize() ? availRead : 0) |
1699  (writeBufferSize() ? dirtyWrite : 0));
1700  return;
1701  }
1702  else
1703  {
1704  // error!
1705  setError(IO_ReadError, errno);
1706  return;
1707  }
1708  // will loop only for normal read operations
1709  }
1710  while (len == sizeof(buf));
1711 
1712  feedReadBuffer(a.size(), a.data());
1713  }
1714 
1715  // UNLOCK MUTEX
1716  }
1717  else
1718  {
1719  // No input buffering, but the notifier fired
1720  // That means that either there is data to be read or that the
1721  // socket closed.
1722 
1723  // try to read one byte. If we can't, then the socket got closed
1724 
1725  char c;
1726  int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
1727  if (len == 0)
1728  {
1729  // yes, it's an EOF condition
1730  d->qsnIn->setEnabled(false);
1731  ::close(sockfd);
1732  sockfd = -1;
1733  d->status = done;
1734  emit closed(involuntary);
1735  return;
1736  }
1737  }
1738 
1739  if (d->emitRead)
1740  emit readyRead();
1741 }
1742 
1743 void KExtendedSocket::socketActivityWrite()
1744 {
1745  if (d->flags & passiveSocket)
1746  return;
1747  if (d->status == connecting)
1748  {
1749  connectionEvent();
1750  return;
1751  }
1752  if (d->status != connected && d->status != closing)
1753  return;
1754 
1755  flush();
1756 
1757  bool empty = writeBufferSize() == 0;
1758 
1759  if (d->emitWrite && empty)
1760  emit readyWrite();
1761  else if (!d->emitWrite)
1762  {
1763  // check if we can disable the notifier
1764  d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send
1765  }
1766  if (d->status == closing && empty)
1767  {
1768  // done sending the missing data!
1769  d->status = done;
1770 
1771  delete d->qsnOut;
1772  ::close(sockfd);
1773 
1774  d->qsnOut = NULL;
1775  sockfd = -1;
1776  emit closed(delayed | (readBufferSize() ? availRead : 0));
1777  }
1778 }
1779 
1780 // this function is called whenever we have a "connection event"
1781 // that is, whenever our asynchronously connecting socket throws
1782 // an event
1783 void KExtendedSocket::connectionEvent()
1784 {
1785  if (d->status != connecting)
1786  return; // move along. There's nothing to see here
1787 
1788  KResolverResults remote = d->resRemote.results();
1789  if (remote.count() == 0)
1790  {
1791  // We have a problem! Abort?
1792  kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
1793  return;
1794  }
1795 
1796  int errcode = 0;
1797 
1798  if (sockfd != -1)
1799  {
1800  // our socket has activity
1801  // find out what it was
1802  int retval;
1803  socklen_t len = sizeof(errcode);
1804  retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
1805 
1806  if (retval == -1 || errcode != 0)
1807  {
1808  // socket activity and there was error?
1809  // that means the socket probably did not connect
1810  if (d->qsnIn)
1811  delete d->qsnIn;
1812  if (d->qsnOut)
1813  delete d->qsnOut;
1814  ::close(sockfd);
1815 
1816  sockfd = -1;
1817  d->qsnIn = d->qsnOut = NULL;
1818  d->current++;
1819  setError(IO_ConnectError, errcode);
1820  }
1821  else
1822  {
1823  // hmm, socket activity and there was no error?
1824  // that means it connected
1825  // YAY!
1826  cleanError();
1827  d->status = connected;
1828  setBlockingMode(true);
1829  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1830  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1831  d->flags & outputBufferedSocket ? -1 : 0);
1832  emit connectionSuccess();
1833  return;
1834  }
1835  }
1836 
1837  // ok, we have to try something here
1838  // and sockfd == -1
1839  KResolverResults local = d->resLocal.results();
1840  unsigned localidx = 0;
1841  for ( ; d->current < remote.count(); d->current++)
1842  {
1843  // same code as in connect()
1844  if (local.count() != 0)
1845  {
1846  // scan bindres for a local resuls family
1847  for (localidx = 0; localidx < local.count(); localidx++)
1848  if (remote[d->current].family() == local[localidx].family())
1849  break;
1850 
1851  if (remote[d->current].family() != local[localidx].family())
1852  {
1853  // no matching families for this
1854  continue;
1855  }
1856 
1857  errno = 0;
1858  sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
1859  remote[d->current].protocol());
1860  setError(IO_ConnectError, errno);
1861  errcode = errno;
1862  if (sockfd == -1)
1863  continue; // cannot create this socket
1864  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1865  if (d->addressReusable)
1866  setAddressReusable(sockfd, true);
1867  setIPv6Only(d->ipv6only);
1868  cleanError();
1869  if (KSocks::self()->bind(sockfd, local[localidx].address(),
1870  local[localidx].length()) == -1)
1871  {
1872  ::close(sockfd);
1873  sockfd = -1;
1874  continue;
1875  }
1876  }
1877  else
1878  {
1879  // no need to bind, just create
1880  sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
1881  remote[d->current].protocol());
1882  if (sockfd == -1)
1883  {
1884  setError(IO_ConnectError, errno);
1885  errcode = errno;
1886  continue;
1887  }
1888  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1889  if (d->addressReusable)
1890  setAddressReusable(sockfd, true);
1891  setIPv6Only(d->ipv6only);
1892  cleanError();
1893  }
1894 
1895  if (KSocks::self()->hasWorkingAsyncConnect())
1896  setBlockingMode(false);
1897  if (KSocks::self()->connect(sockfd, remote[d->current].address(),
1898  remote[d->current].length()) == -1)
1899  {
1900  if (errno != EWOULDBLOCK && errno != EINPROGRESS)
1901  {
1902  setError(IO_ConnectError, errno);
1903  ::close(sockfd);
1904  sockfd = -1;
1905  errcode = errno;
1906  continue;
1907  }
1908 
1909  // error here is either EWOULDBLOCK or EINPROGRESS
1910  // so, it is a good condition
1911  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
1912  TQObject::connect(d->qsnIn, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityRead()));
1913  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
1914  TQObject::connect(d->qsnOut, TQ_SIGNAL(activated(int)), this, TQ_SLOT(socketActivityWrite()));
1915 
1916  // ok, let the Qt event loop do the selecting for us
1917  return;
1918  }
1919 
1920  // eh, what?
1921  // the non-blocking socket returned valid connection?
1922  // already?
1923  // I suppose that could happen...
1924  cleanError();
1925  d->status = connected;
1926  setBlockingMode(true);
1927  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1928  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1929  d->flags & outputBufferedSocket ? -1 : 0);
1930  emit connectionSuccess();
1931  return;
1932  }
1933 
1934  // if we got here, it means that there are no more options to connect
1935  d->status = lookupDone; // go back
1936  emit connectionFailed(errcode);
1937 }
1938 
1939 void KExtendedSocket::dnsResultsReady()
1940 {
1941  // check that this function was called in a valid state
1942  if (d->status != lookupInProgress)
1943  return;
1944 
1945  // valid state. Are results fully ready?
1946  if (d->resRemote.isRunning() || d->resLocal.isRunning())
1947  // no, still waiting for answer in one of the lookups
1948  return;
1949 
1950  // ok, we have all results
1951  // count how many results we have
1952  int n = d->resRemote.results().count() + d->resLocal.results().count();
1953 
1954  if (n)
1955  {
1956  d->status = lookupDone;
1957  cleanError();
1958  }
1959  else
1960  {
1961  d->status = nothing;
1962  setError(IO_LookupError, KResolver::NoName);
1963  }
1964 
1965  emit lookupFinished(n);
1966 
1967  return;
1968 }
1969 
1970 void KExtendedSocket::startAsyncConnectSlot()
1971 {
1972  TQObject::disconnect(this, TQ_SIGNAL(lookupFinished(int)), this, TQ_SLOT(startAsyncConnectSlot()));
1973 
1974  if (d->status == lookupDone)
1975  startAsyncConnect();
1976 }
1977 
1978 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, TQString &host,
1979  TQString &port, int flags)
1980 {
1981  kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
1982 
1983  int err;
1984  char h[NI_MAXHOST], s[NI_MAXSERV];
1985 
1986  h[0] = s[0] = '\0';
1987 
1988  err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
1989  host = TQString::fromUtf8(h);
1990  port = TQString::fromUtf8(s);
1991 
1992  return err;
1993 }
1994 
1995 int KExtendedSocket::resolve(::TDESocketAddress *sock, TQString &host, TQString &port,
1996  int flags)
1997 {
1998  return resolve(sock->data, sock->datasize, host, port, flags);
1999 }
2000 
2001 TQPtrList<KAddressInfo> KExtendedSocket::lookup(const TQString& host, const TQString& port,
2002  int userflags, int *error)
2003 {
2004  kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
2005 
2006  int socktype, familyMask, flags;
2007  unsigned i;
2008  TQPtrList<KAddressInfo> l;
2009 
2010  /* check socket type flags */
2011  if (!process_flags(userflags, socktype, familyMask, flags))
2012  return l;
2013 
2014 // kdDebug(170) << "Performing lookup on " << host << "|" << port << endl;
2015  KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
2016  if (res.error())
2017  {
2018  if (error)
2019  *error = res.error();
2020  return l;
2021  }
2022 
2023  for (i = 0; i < res.count(); i++)
2024  {
2025  KAddressInfo *ai = new KAddressInfo();
2026 
2027  // I should have known that using addrinfo was going to come
2028  // and bite me back some day...
2029  ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
2030  memset(ai->ai, 0, sizeof(addrinfo));
2031 
2032  ai->ai->ai_family = res[i].family();
2033  ai->ai->ai_socktype = res[i].socketType();
2034  ai->ai->ai_protocol = res[i].protocol();
2035  TQString canon = res[i].canonicalName();
2036  if (!canon.isEmpty())
2037  {
2038  ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
2039  strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional
2040  }
2041  if ((ai->ai->ai_addrlen = res[i].length()))
2042  {
2043  ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
2044  memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
2045  }
2046  else
2047  {
2048  ai->ai->ai_addr = 0;
2049  }
2050 
2051  ai->addr = ::TDESocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
2052 
2053  l.append(ai);
2054  }
2055 
2056  if ( error )
2057  *error = 0; // all is fine!
2058 
2059  return l;
2060 }
2061 
2062 ::TDESocketAddress *KExtendedSocket::localAddress(int fd)
2063 {
2064  ::TDESocketAddress *local;
2065  struct sockaddr static_sa, *sa = &static_sa;
2066  ksocklen_t len = sizeof(static_sa);
2067 
2068  /* find out the socket length, in advance
2069  * we use a sockaddr allocated on the heap just not to pass down
2070  * a NULL pointer to the first call. Some systems are reported to
2071  * set len to 0 if we pass NULL as the sockaddr */
2072  if (KSocks::self()->getsockname(fd, sa, &len) == -1)
2073  return NULL; // error!
2074 
2075  /* was it enough? */
2076  if (len > sizeof(static_sa)
2077 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2078  || sa->sa_len > sizeof(static_sa)
2079 #endif
2080  )
2081  {
2082  /* nope, malloc a new socket with the proper size */
2083 
2084 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2085  if (sa->sa_len != len)
2086  len = sa->sa_len;
2087 #endif
2088 
2089  sa = (sockaddr*)malloc(len);
2090  if (sa == NULL)
2091  return NULL; // out of memory
2092 
2093  if (KSocks::self()->getsockname(fd, sa, &len) == -1)
2094  {
2095  free(sa);
2096  return NULL;
2097  }
2098 
2099  local = ::TDESocketAddress::newAddress(sa, len);
2100  free(sa);
2101  }
2102  else
2103  local = ::TDESocketAddress::newAddress(sa, len);
2104 
2105  return local;
2106 }
2107 
2108 /* This is exactly the same code as localAddress, except
2109  * we call getpeername here */
2110 ::TDESocketAddress *KExtendedSocket::peerAddress(int fd)
2111 {
2112  ::TDESocketAddress *peer;
2113  struct sockaddr static_sa, *sa = &static_sa;
2114  ksocklen_t len = sizeof(static_sa);
2115 
2116  /* find out the socket length, in advance
2117  * we use a sockaddr allocated on the heap just not to pass down
2118  * a NULL pointer to the first call. Some systems are reported to
2119  * set len to 0 if we pass NULL as the sockaddr */
2120  if (KSocks::self()->getpeername(fd, sa, &len) == -1)
2121  return NULL; // error!
2122 
2123  /* was it enough? */
2124  if (len > sizeof(static_sa)
2125 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2126  || sa->sa_len > sizeof(static_sa)
2127 #endif
2128  )
2129  {
2130  /* nope, malloc a new socket with the proper size */
2131 
2132 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2133  if (sa->sa_len != len)
2134  len = sa->sa_len;
2135 #endif
2136 
2137  sa = (sockaddr*)malloc(len);
2138  if (sa == NULL)
2139  return NULL; // out of memory
2140 
2141  if (KSocks::self()->getpeername(fd, sa, &len) == -1)
2142  {
2143  free(sa);
2144  return NULL;
2145  }
2146 
2147  peer = ::TDESocketAddress::newAddress(sa, len);
2148  free(sa);
2149  }
2150  else
2151  peer = ::TDESocketAddress::newAddress(sa, len);
2152 
2153  return peer;
2154 }
2155 
2156 TQString KExtendedSocket::strError(int code, int syserr)
2157 {
2158  const char * msg;
2159  if (code == IO_LookupError)
2160  msg = gai_strerror(syserr);
2161  else
2162  msg = strerror(syserr);
2163 
2164  return TQString::fromLocal8Bit(msg);
2165 }
2166 
2167 
2168 TQSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
2169 TQSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
2170 
2171 /*
2172  * class KAddressInfo
2173  */
2174 
2175 #if 0
2176 KAddressInfo::KAddressInfo(addrinfo *p)
2177 {
2178  ai = (addrinfo *) malloc(sizeof(addrinfo));
2179  memcpy(ai, p, sizeof(addrinfo));
2180  ai->ai_next = NULL;
2181  if (p->ai_canonname)
2182  {
2183  ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
2184  strcpy(ai->ai_canonname, p->ai_canonname);
2185  }
2186  if (p->ai_addr && p->ai_addrlen)
2187  {
2188  ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
2189  memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
2190  }
2191  else
2192  {
2193  ai->ai_addr = 0;
2194  ai->ai_addrlen = 0;
2195  }
2196 
2197  addr = ::TDESocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
2198 }
2199 #endif
2200 KAddressInfo::~KAddressInfo()
2201 {
2202  if (ai && ai->ai_canonname)
2203  free(ai->ai_canonname);
2204 
2205  if (ai && ai->ai_addr)
2206  free(ai->ai_addr);
2207 
2208  if (ai)
2209  free(ai);
2210  delete addr;
2211 }
2212 
2213 int KAddressInfo::flags() const
2214 {
2215  return ai->ai_flags;
2216 }
2217 
2218 int KAddressInfo::family() const
2219 {
2220  return ai->ai_family;
2221 }
2222 
2223 int KAddressInfo::socktype() const
2224 {
2225  return ai->ai_socktype;
2226 }
2227 
2228 int KAddressInfo::protocol() const
2229 {
2230  return ai->ai_protocol;
2231 }
2232 
2233 const char* KAddressInfo::canonname() const
2234 {
2235  return ai->ai_canonname;
2236 }
2237 
2238 void KExtendedSocket::virtual_hook( int id, void* data )
2239 { TDEBufferedIO::virtual_hook( id, data ); }
2240 
2241 #include "kextsock.moc"
KAddressInfo
Definition: kextsock.h:1024
KAddressInfo::family
int family() const TDE_DEPRECATED
Returns the family of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2218
KAddressInfo::canonname
const char * canonname() const TDE_DEPRECATED
Returns the official name of the host (see getaddrinfo(3)).
Definition: kextsock.cpp:2233
KAddressInfo::flags
int flags() const TDE_DEPRECATED
Returns the flags of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2213
KAddressInfo::protocol
int protocol() const TDE_DEPRECATED
Returns the protocol of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2228
KAddressInfo::socktype
int socktype() const TDE_DEPRECATED
Returns the socket type of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2223
KAsyncIO::readyRead
void readyRead()
This signal gets sent when the device is ready for reading.
KAsyncIO::readyWrite
void readyWrite()
This signal gets sent when the device is ready for writing.
KExtendedSocket
The extended socket class.
Definition: kextsock.h:92
KExtendedSocket::socketStatus
int socketStatus() const
Returns the class status.
Definition: kextsock.cpp:234
KExtendedSocket::addressReusable
bool addressReusable()
Returns whether this socket's address can be reused.
Definition: kextsock.cpp:531
KExtendedSocket::bytesAvailable
virtual int bytesAvailable() const
Returns the number of available bytes yet to be read via readBlock and family of functions.
Definition: kextsock.cpp:1555
KExtendedSocket::~KExtendedSocket
virtual ~KExtendedSocket()
Destroys the socket, disconnecting if still connected and freeing any related resources still being k...
Definition: kextsock.cpp:208
KExtendedSocket::enableRead
virtual void enableRead(bool enable)
Toggles the emission of the readyRead signal.
Definition: kextsock.cpp:1613
KExtendedSocket::connectionSuccess
void connectionSuccess()
This signal is emitted whenever we connected asynchronously to a host.
KExtendedSocket::reset
void reset()
Resets the socket, disconnecting if still connected and freeing any related resources still being kep...
Definition: kextsock.cpp:225
KExtendedSocket::peekBlock
virtual int peekBlock(char *data, uint maxlen)
Peeks at a block of data from the socket.
Definition: kextsock.cpp:1533
KExtendedSocket::bindPort
TQString bindPort() const
Returns the service to which the socket will be/is bound.
Definition: kextsock.cpp:395
KExtendedSocket::readyAccept
void readyAccept()
This signal is emitted whenever this socket is ready to accept another socket.
KExtendedSocket::setAddressReusable
bool setAddressReusable(bool enable)
Sets/unsets address reusing flag for this socket.
Definition: kextsock.cpp:498
KExtendedSocket::waitForMore
virtual int waitForMore(int msec)
Waits msec milliseconds for more data to be available (use 0 to wait forever).
Definition: kextsock.cpp:1568
KExtendedSocket::setBindAddress
bool setBindAddress(const TQString &host, int port)
Sets both host and port to which we will bind the socket.
Definition: kextsock.cpp:403
KExtendedSocket::connectionFailed
void connectionFailed(int error)
This signal is emitted whenever our asynchronous connection attempt failed to all hosts listed.
KExtendedSocket::release
virtual void release()
Releases the socket and anything we have holding on it.
Definition: kextsock.cpp:1334
KExtendedSocket::unsetBindHost
bool unsetBindHost()
Unsets the bind hostname.
Definition: kextsock.cpp:353
KExtendedSocket::localAddress
const ::TDESocketAddress * localAddress()
Returns the local socket address.
Definition: kextsock.cpp:716
KExtendedSocket::setAddress
bool setAddress(const TQString &host, int port)
Sets the address where we will connect to.
Definition: kextsock.cpp:322
KExtendedSocket::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads a block of data from the socket.
Definition: kextsock.cpp:1434
KExtendedSocket::setBindPort
bool setBindPort(int port)
Sets the port/service to which we will bind before connecting.
Definition: kextsock.cpp:370
KExtendedSocket::setBlockingMode
bool setBlockingMode(bool enable)
Sets/unsets blocking mode for the socket.
Definition: kextsock.cpp:448
KExtendedSocket::connect
virtual int connect()
Attempts to connect to the remote host.
Definition: kextsock.cpp:978
KExtendedSocket::lookup
virtual int lookup()
Performs lookup on the addresses we were given before.
Definition: kextsock.cpp:744
KExtendedSocket::blockingMode
bool blockingMode()
Returns the current blocking mode for this socket.
Definition: kextsock.cpp:477
KExtendedSocket::startAsyncConnect
virtual int startAsyncConnect()
Starts an asynchronous connect.
Definition: kextsock.cpp:1205
KExtendedSocket::host
TQString host() const
Returns the hostname.
Definition: kextsock.cpp:288
KExtendedSocket::cancelAsyncLookup
virtual void cancelAsyncLookup()
Cancels any on-going asynchronous lookups.
Definition: kextsock.cpp:825
KExtendedSocket::resolve
static int resolve(sockaddr *sock, ksocklen_t len, TQString &host, TQString &port, int flags=0) TDE_DEPRECATED
Performs resolution on the given socket address.
Definition: kextsock.cpp:1978
KExtendedSocket::setHost
bool setHost(const TQString &host)
Sets the hostname to the given value.
Definition: kextsock.cpp:276
KExtendedSocket::cancelAsyncConnect
virtual void cancelAsyncConnect()
Cancels any on-going asynchronous connection attempt.
Definition: kextsock.cpp:1240
KExtendedSocket::unsetBindPort
bool unsetBindPort()
Unsets the bind port/service.
Definition: kextsock.cpp:387
KExtendedSocket::setSocketFlags
int setSocketFlags(int flags)
Sets the given flags.
Definition: kextsock.cpp:259
KExtendedSocket::lookupFinished
void lookupFinished(int count)
This signal is emitted whenever an asynchronous lookup process is done.
KExtendedSocket::closeNow
virtual void closeNow()
Closes the socket now, discarding the contents of the write buffer, if any.
Definition: kextsock.cpp:1307
KExtendedSocket::unreadBlock
virtual int unreadBlock(const char *data, uint len)
Reimplementation of unreadBlock() method.
Definition: kextsock.cpp:1548
KExtendedSocket::setBindHost
bool setBindHost(const TQString &host)
Sets the hostname to which we will bind locally before connecting.
Definition: kextsock.cpp:340
KExtendedSocket::isIPv6Only
bool isIPv6Only()
Returns the status of the v6-only flag for IPv6 sockets.
Definition: kextsock.cpp:586
KExtendedSocket::flush
virtual void flush()
Flushes the socket buffer.
Definition: kextsock.cpp:1365
KExtendedSocket::KExtendedSocket
KExtendedSocket()
Creates an empty KExtendedSocket.
Definition: kextsock.cpp:186
KExtendedSocket::socketFlags
int socketFlags() const
Returns the current flags.
Definition: kextsock.cpp:267
KExtendedSocket::bindHost
TQString bindHost() const
Returns the hostname to which the socket will be/is bound.
Definition: kextsock.cpp:361
KExtendedSocket::setPort
bool setPort(int port)
Sets the port/service.
Definition: kextsock.cpp:297
KExtendedSocket::setError
void setError(int errorkind, int error)
Sets the error code.
Definition: kextsock.cpp:244
KExtendedSocket::open
virtual bool open(int mode=(int)(IO_Raw|IO_ReadWrite))
Implementation of TQIODevice::open() pure virtual function.
Definition: kextsock.cpp:1260
KExtendedSocket::systemError
int systemError() const
Returns the related system error code Except for IO_LookupError errors, these are codes found in errn...
Definition: kextsock.cpp:250
KExtendedSocket::fd
int fd() const
Returns the file descriptor.
Definition: kextsock.h:499
KExtendedSocket::port
TQString port() const
Returns the port/service.
Definition: kextsock.cpp:314
KExtendedSocket::setIPv6Only
bool setIPv6Only(bool enable)
Sets/unsets the v6-only flag for IPv6 sockets.
Definition: kextsock.cpp:554
KExtendedSocket::listen
virtual int listen(int N=5)
Place the socket in listen mode.
Definition: kextsock.cpp:836
KExtendedSocket::setSocketStatus
void setSocketStatus(int status)
Sets the socket status.
Definition: kextsock.cpp:239
KExtendedSocket::strError
static TQString strError(int code, int syserr)
Returns the representing text of this error code.
Definition: kextsock.cpp:2156
KExtendedSocket::getch
virtual int getch()
Gets a single character (unsigned char) from the stream.
Definition: kextsock.cpp:1595
KExtendedSocket::setBufferSize
virtual bool setBufferSize(int rsize, int wsize=-2)
Sets the buffer sizes for this socket.
Definition: kextsock.cpp:616
KExtendedSocket::close
virtual void close()
Closes the socket.
Definition: kextsock.cpp:1273
KExtendedSocket::enableWrite
virtual void enableWrite(bool enable)
Toggles the emission of the readyWrite signal.
Definition: kextsock.cpp:1628
KExtendedSocket::unsetBindAddress
bool unsetBindAddress()
Unsets the bind address for the socket.
Definition: kextsock.cpp:419
KExtendedSocket::startAsyncLookup
virtual int startAsyncLookup()
Starts an asynchronous lookup for the addresses given.
Definition: kextsock.cpp:766
KExtendedSocket::peerAddress
const ::TDESocketAddress * peerAddress()
Returns the peer socket address.
Definition: kextsock.cpp:731
KExtendedSocket::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes a block of data to the socket.
Definition: kextsock.cpp:1479
KExtendedSocket::timeout
timeval timeout() const
Returns the timeout value for the connection.
Definition: kextsock.cpp:440
KExtendedSocket::putch
virtual int putch(int ch)
Writes a single character (unsigned char) to the stream.
Definition: kextsock.cpp:1606
KExtendedSocket::setTimeout
bool setTimeout(int secs, int usecs=0)
Sets the timeout value for the connection (if this is not passiveSocket) or acception (if it is).
Definition: kextsock.cpp:427
KExtendedSocket::accept
virtual int accept(KExtendedSocket *&sock)
Accepts an incoming connection from the socket.
Definition: kextsock.cpp:904
KNetwork::KResolverResults
Name and service resolution results.
Definition: kresolver.h:198
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: kresolver.cpp:247
KNetwork::KResolver
Name and service resolution class.
Definition: kresolver.h:296
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:424
KSocks::getpeername
int getpeername(int s, sockaddr *name, ksocklen_t *namelen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:548
KSocks::write
signed long int write(int fd, const void *buf, unsigned long int count)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:494
KSocks::self
static KSocks * self()
Return an instance of class KSocks *.
Definition: ksocks.cpp:212
KSocks::listen
int listen(int s, int backlog)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:580
KSocks::getsockname
int getsockname(int s, sockaddr *name, ksocklen_t *namelen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:536
KSocks::read
signed long int read(int fd, void *buf, unsigned long int count)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:487
KSocks::recv
int recv(int s, void *buf, unsigned long int len, int flags)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:522
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
TDEBufferedIO::feedWriteBuffer
virtual unsigned feedWriteBuffer(unsigned nbytes, const char *buffer)
Feeds data into the output buffer.
Definition: kbufferedio.cpp:259
TDEBufferedIO::closed
void closed(int state)
This signal gets sent when the stream is closed.
TDEBufferedIO::consumeReadBuffer
virtual unsigned consumeReadBuffer(unsigned nbytes, char *destbuffer, bool discard=true)
Consumes data from the input buffer.
Definition: kbufferedio.cpp:164
TDEBufferedIO::readBufferSize
virtual unsigned readBufferSize() const
Returns the number of bytes in the read buffer.
Definition: kbufferedio.cpp:270
TDEBufferedIO::feedReadBuffer
virtual unsigned feedReadBuffer(unsigned nbytes, const char *buffer, bool atBeginning=false)
Feeds data into the input buffer.
Definition: kbufferedio.cpp:243
TDEBufferedIO::bytesWritten
void bytesWritten(int nbytes)
This signal gets sent whenever bytes are written from the buffer.
TDEBufferedIO::outBufIndex
unsigned outBufIndex
Offset into first output buffer.
Definition: kbufferedio.h:222
TDEBufferedIO::outBuf
TQPtrList< TQByteArray > outBuf
For an explanation on how this buffer work, please refer to the comments at the top of kbufferedio....
Definition: kbufferedio.h:219
TDEBufferedIO::bytesAvailable
virtual int bytesAvailable() const
Returns the number of bytes available for reading in the read buffer.
Definition: kbufferedio.cpp:114
TDEBufferedIO::consumeWriteBuffer
virtual void consumeWriteBuffer(unsigned nbytes)
Consumes data from the output buffer.
Definition: kbufferedio.cpp:214
TDEBufferedIO::writeBufferSize
virtual unsigned writeBufferSize() const
Returns the number of bytes in the write buffer.
Definition: kbufferedio.cpp:283
TDESocketAddress::newAddress
static TDESocketAddress * newAddress(const struct sockaddr *sa, ksocklen_t size)
Creates a new TDESocketAddress or descendant class from given raw socket address.
Definition: ksockaddr.cpp:123
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
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.1
This website is maintained by Timothy Pearson.