• 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
56using namespace KNetwork;
57
58//
59// Internal class definitions
60//
61
62class KExtendedSocketPrivate
63{
64public:
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
94static 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
160static 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
186KExtendedSocket::KExtendedSocket() :
187 sockfd(-1), d(new KExtendedSocketPrivate)
188{
189}
190
191// constructor with hostname
192KExtendedSocket::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
200KExtendedSocket::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
208KExtendedSocket::~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
225void KExtendedSocket::reset()
226{
227 closeNow();
228 release();
229 d->current = 0;
230 d->status = nothing;
231 d->syserror = 0;
232}
233
234int KExtendedSocket::socketStatus() const
235{
236 return d->status;
237}
238
239void KExtendedSocket::setSocketStatus(int newstatus)
240{
241 d->status = newstatus;
242}
243
244void KExtendedSocket::setError(int errorcode, int syserror)
245{
246 setStatus(errorcode);
247 d->syserror = syserror;
248}
249
250int 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 */
259int KExtendedSocket::setSocketFlags(int flags)
260{
261 if (d->status > nothing)
262 return -1; // error!
263
264 return d->flags = flags;
265}
266
267int 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 */
276bool 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 */
288TQString 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 */
297bool KExtendedSocket::setPort(int port)
298{
299 return setPort(TQString::number(port));
300}
301
302bool 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 */
314TQString KExtendedSocket::port() const
315{
316 return d->resRemote.serviceName();
317}
318
319/*
320 * sets the address
321 */
322bool KExtendedSocket::setAddress(const TQString& host, int port)
323{
324 return setHost(host) && setPort(port);
325}
326
327/*
328 * the same
329 */
330bool 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 */
340bool 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 */
353bool KExtendedSocket::unsetBindHost()
354{
355 return setBindHost(TQString::null);
356}
357
358/*
359 * returns the binding host
360 */
361TQString KExtendedSocket::bindHost() const
362{
363 return d->resLocal.serviceName();
364}
365
366/*
367 * Sets the bind port
368 * Same condition as setBindHost
369 */
370bool KExtendedSocket::setBindPort(int port)
371{
372 return setBindPort(TQString::number(port));
373}
374
375bool 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 */
387bool KExtendedSocket::unsetBindPort()
388{
389 return setBindPort(TQString::null);
390}
391
392/*
393 * returns the binding port
394 */
395TQString KExtendedSocket::bindPort() const
396{
397 return d->resLocal.serviceName();
398}
399
400/*
401 * sets the binding address
402 */
403bool KExtendedSocket::setBindAddress(const TQString& host, int port)
404{
405 return setBindHost(host) && setBindPort(port);
406}
407
408/*
409 * same
410 */
411bool KExtendedSocket::setBindAddress(const TQString& host, const TQString& service)
412{
413 return setBindHost(host) && setBindPort(service);
414}
415
416/*
417 * unsets binding address
418 */
419bool KExtendedSocket::unsetBindAddress()
420{
421 return unsetBindHost() && unsetBindPort();
422}
423
424/*
425 * sets the timeout for the connection
426 */
427bool 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 */
440timeval KExtendedSocket::timeout() const
441{
442 return d->timeout;
443}
444
445/*
446 * Sets the blocking mode on this socket
447 */
448bool 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 */
477bool 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 */
498bool 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
516bool 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 */
531bool 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 */
554bool 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 */
586bool 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 */
616bool 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 */
716const ::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 */
731const ::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 */
744int 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 */
766int 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
825void 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
836int 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
904int 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 */
978int 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
1205int 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
1240void 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
1260bool 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
1273void 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
1307void 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
1334void 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
1365void 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
1434TQ_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
1479TQ_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
1533int 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
1548int 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
1555int 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
1568int 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
1595int 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
1606int 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
1613void 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
1628void 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)
1641void 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
1743void 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
1783void 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
1939void 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
1970void 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
1978int 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
1995int KExtendedSocket::resolve(::TDESocketAddress *sock, TQString &host, TQString &port,
1996 int flags)
1997{
1998 return resolve(sock->data, sock->datasize, host, port, flags);
1999}
2000
2001TQPtrList<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
2156TQString 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
2168TQSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
2169TQSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
2170
2171/*
2172 * class KAddressInfo
2173 */
2174
2175#if 0
2176KAddressInfo::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
2200KAddressInfo::~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
2213int KAddressInfo::flags() const
2214{
2215 return ai->ai_flags;
2216}
2217
2218int KAddressInfo::family() const
2219{
2220 return ai->ai_family;
2221}
2222
2223int KAddressInfo::socktype() const
2224{
2225 return ai->ai_socktype;
2226}
2227
2228int KAddressInfo::protocol() const
2229{
2230 return ai->ai_protocol;
2231}
2232
2233const char* KAddressInfo::canonname() const
2234{
2235 return ai->ai_canonname;
2236}
2237
2238void 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.4
This website is maintained by Timothy Pearson.