kdecore Library API Documentation

kextsock.cpp

00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 **/ 00020 00021 #include <config.h> 00022 00023 #include <sys/types.h> 00024 #include <sys/socket.h> 00025 #include <sys/times.h> 00026 #include <netinet/in.h> 00027 #include <arpa/inet.h> 00028 #include <sys/un.h> 00029 00030 #include <stdio.h> 00031 #include <errno.h> 00032 #include <fcntl.h> 00033 00034 #include <netdb.h> 00035 00036 #include <stdlib.h> 00037 #include <unistd.h> 00038 00039 #include <qglobal.h> 00040 #include <qstring.h> 00041 #include <qiodevice.h> 00042 #include <qsocketnotifier.h> 00043 #include <qguardedptr.h> 00044 00045 #include "kresolver.h" 00046 00047 #include "kdebug.h" 00048 #include "kextsock.h" 00049 #include "ksockaddr.h" 00050 #include "ksocks.h" 00051 00052 using namespace KNetwork; 00053 00054 // 00055 // Internal class definitions 00056 // 00057 00058 class KExtendedSocketPrivate 00059 { 00060 public: 00061 int flags; // socket flags 00062 int status; // status 00063 int syserror; // the system error value 00064 00065 timeval timeout; // connection/acception timeout 00066 00067 KResolver resRemote; // the resolved addresses 00068 KResolver resLocal; // binding resolution 00069 unsigned current; // used by the asynchronous connection 00070 00071 ::KSocketAddress *local; // local socket address 00072 ::KSocketAddress *peer; // peer socket address 00073 00074 QSocketNotifier *qsnIn, *qsnOut; 00075 int inMaxSize, outMaxSize; 00076 bool emitRead : 1, emitWrite : 1; 00077 mutable bool addressReusable : 1, ipv6only : 1; 00078 00079 KExtendedSocketPrivate() : 00080 flags(0), status(0), syserror(0), 00081 current(0), local(0), peer(0), 00082 qsnIn(0), qsnOut(0), inMaxSize(-1), outMaxSize(-1), emitRead(false), emitWrite(false), 00083 addressReusable(false), ipv6only(false) 00084 { 00085 timeout.tv_sec = timeout.tv_usec = 0; 00086 } 00087 }; 00088 00089 // translate KExtendedSocket flags into KResolver ones 00090 static bool process_flags(int flags, int& socktype, int& familyMask, int& outflags) 00091 { 00092 switch (flags & (KExtendedSocket::streamSocket | KExtendedSocket::datagramSocket | KExtendedSocket::rawSocket)) 00093 { 00094 case 0: 00095 /* No flags given, use default */ 00096 00097 case KExtendedSocket::streamSocket: 00098 /* streaming socket requested */ 00099 socktype = SOCK_STREAM; 00100 break; 00101 00102 case KExtendedSocket::datagramSocket: 00103 /* datagram packet socket requested */ 00104 socktype = SOCK_DGRAM; 00105 break; 00106 00107 case KExtendedSocket::rawSocket: 00108 /* raw socket requested. I wouldn't do this if I were you... */ 00109 socktype = SOCK_RAW; 00110 break; 00111 00112 default: 00113 /* the flags were used in an invalid manner */ 00114 return false; 00115 } 00116 00117 if (flags & KExtendedSocket::knownSocket) 00118 { 00119 familyMask = 0; 00120 if ((flags & KExtendedSocket::unixSocket) == KExtendedSocket::unixSocket) 00121 familyMask |= KResolver::UnixFamily; 00122 00123 switch ((flags & (KExtendedSocket::ipv6Socket|KExtendedSocket::ipv4Socket))) 00124 { 00125 case KExtendedSocket::ipv4Socket: 00126 familyMask |= KResolver::IPv4Family; 00127 break; 00128 case KExtendedSocket::ipv6Socket: 00129 familyMask |= KResolver::IPv6Family; 00130 break; 00131 case KExtendedSocket::inetSocket: 00132 familyMask |= KResolver::InternetFamily; 00133 break; 00134 } 00135 00136 // those are all the families we know about 00137 } 00138 else 00139 familyMask = KResolver::KnownFamily; 00140 00141 /* check other flags */ 00142 outflags = (flags & KExtendedSocket::passiveSocket ? KResolver::Passive : 0) | 00143 (flags & KExtendedSocket::canonName ? KResolver::CanonName : 0) | 00144 (flags & KExtendedSocket::noResolve ? KResolver::NoResolve : 0); 00145 00146 if (getenv("KDE_NO_IPV6")) 00147 familyMask &= ~KResolver::IPv6Family; 00148 00149 return true; 00150 } 00151 00152 // "skips" at most len bytes from file descriptor fd 00153 // that is, we will try and read that much data and discard 00154 // it. We will stop when we have read those or when the read 00155 // function returns error 00156 static int skipData(int fd, unsigned len) 00157 { 00158 char buf[1024]; 00159 unsigned skipped = 0; 00160 while (len) 00161 { 00162 int count = sizeof(buf); 00163 if ((unsigned)count > len) 00164 count = len; 00165 count = KSocks::self()->read(fd, buf, count); 00166 if (count == -1) 00167 return -1; 00168 else 00169 { 00170 len -= count; 00171 skipped += count; 00172 } 00173 } 00174 return skipped; 00175 } 00176 00177 /* 00178 * class KExtendedSocket 00179 */ 00180 00181 // default constructor 00182 KExtendedSocket::KExtendedSocket() : 00183 sockfd(-1), d(new KExtendedSocketPrivate) 00184 { 00185 } 00186 00187 // constructor with hostname 00188 KExtendedSocket::KExtendedSocket(const QString& host, int port, int flags) : 00189 sockfd(-1), d(new KExtendedSocketPrivate) 00190 { 00191 setAddress(host, port); 00192 setSocketFlags(flags); 00193 } 00194 00195 // same 00196 KExtendedSocket::KExtendedSocket(const QString& host, const QString& service, int flags) : 00197 sockfd(-1), d(new KExtendedSocketPrivate) 00198 { 00199 setAddress(host, service); 00200 setSocketFlags(flags); 00201 } 00202 00203 // destroy the class 00204 KExtendedSocket::~KExtendedSocket() 00205 { 00206 closeNow(); 00207 00208 if (d->local != NULL) 00209 delete d->local; 00210 if (d->peer != NULL) 00211 delete d->peer; 00212 00213 if (d->qsnIn != NULL) 00214 delete d->qsnIn; 00215 if (d->qsnOut != NULL) 00216 delete d->qsnOut; 00217 00218 delete d; 00219 } 00220 00221 void KExtendedSocket::reset() 00222 { 00223 closeNow(); 00224 release(); 00225 d->current = 0; 00226 d->status = nothing; 00227 d->syserror = 0; 00228 } 00229 00230 int KExtendedSocket::socketStatus() const 00231 { 00232 return d->status; 00233 } 00234 00235 void KExtendedSocket::setSocketStatus(int newstatus) 00236 { 00237 d->status = newstatus; 00238 } 00239 00240 void KExtendedSocket::setError(int errorcode, int syserror) 00241 { 00242 setStatus(errorcode); 00243 d->syserror = syserror; 00244 } 00245 00246 int KExtendedSocket::systemError() const 00247 { 00248 return d->syserror; 00249 } 00250 00251 /* 00252 * Sets socket flags 00253 * This is only allowed if we are in nothing state 00254 */ 00255 int KExtendedSocket::setSocketFlags(int flags) 00256 { 00257 if (d->status > nothing) 00258 return -1; // error! 00259 00260 return d->flags = flags; 00261 } 00262 00263 int KExtendedSocket::socketFlags() const 00264 { 00265 return d->flags; 00266 } 00267 00268 /* 00269 * Sets socket target hostname 00270 * This is only allowed if we are in nothing state 00271 */ 00272 bool KExtendedSocket::setHost(const QString& host) 00273 { 00274 if (d->status > nothing) 00275 return false; // error! 00276 00277 d->resRemote.setNodeName(host); 00278 return true; 00279 } 00280 00281 /* 00282 * returns the hostname 00283 */ 00284 QString KExtendedSocket::host() const 00285 { 00286 return d->resRemote.nodeName(); 00287 } 00288 00289 /* 00290 * Sets the socket target port/service 00291 * Same thing: only state 'nothing' 00292 */ 00293 bool KExtendedSocket::setPort(int port) 00294 { 00295 return setPort(QString::number(port)); 00296 } 00297 00298 bool KExtendedSocket::setPort(const QString& service) 00299 { 00300 if (d->status > nothing) 00301 return false; // error 00302 00303 d->resRemote.setServiceName(service); 00304 return true; 00305 } 00306 00307 /* 00308 * returns the service port number 00309 */ 00310 QString KExtendedSocket::port() const 00311 { 00312 return d->resRemote.serviceName(); 00313 } 00314 00315 /* 00316 * sets the address 00317 */ 00318 bool KExtendedSocket::setAddress(const QString& host, int port) 00319 { 00320 return setHost(host) && setPort(port); 00321 } 00322 00323 /* 00324 * the same 00325 */ 00326 bool KExtendedSocket::setAddress(const QString& host, const QString& serv) 00327 { 00328 return setHost(host) && setPort(serv); 00329 } 00330 00331 /* 00332 * Sets the bind hostname 00333 * This is only valid in the 'nothing' state and if this is not a 00334 * passiveSocket socket 00335 */ 00336 bool KExtendedSocket::setBindHost(const QString& host) 00337 { 00338 if (d->status > nothing || d->flags & passiveSocket) 00339 return false; // error 00340 00341 d->resLocal.setServiceName(host); 00342 return true; 00343 } 00344 00345 /* 00346 * Unsets the bind hostname 00347 * same thing 00348 */ 00349 bool KExtendedSocket::unsetBindHost() 00350 { 00351 return setBindHost(QString::null); 00352 } 00353 00354 /* 00355 * returns the binding host 00356 */ 00357 QString KExtendedSocket::bindHost() const 00358 { 00359 return d->resLocal.serviceName(); 00360 } 00361 00362 /* 00363 * Sets the bind port 00364 * Same condition as setBindHost 00365 */ 00366 bool KExtendedSocket::setBindPort(int port) 00367 { 00368 return setBindPort(QString::number(port)); 00369 } 00370 00371 bool KExtendedSocket::setBindPort(const QString& service) 00372 { 00373 if (d->status > nothing || d->flags & passiveSocket) 00374 return false; // error 00375 00376 d->resLocal.setServiceName(service); 00377 return true; 00378 } 00379 00380 /* 00381 * unsets the bind port 00382 */ 00383 bool KExtendedSocket::unsetBindPort() 00384 { 00385 return setBindPort(QString::null); 00386 } 00387 00388 /* 00389 * returns the binding port 00390 */ 00391 QString KExtendedSocket::bindPort() const 00392 { 00393 return d->resLocal.serviceName(); 00394 } 00395 00396 /* 00397 * sets the binding address 00398 */ 00399 bool KExtendedSocket::setBindAddress(const QString& host, int port) 00400 { 00401 return setBindHost(host) && setBindPort(port); 00402 } 00403 00404 /* 00405 * same 00406 */ 00407 bool KExtendedSocket::setBindAddress(const QString& host, const QString& service) 00408 { 00409 return setBindHost(host) && setBindPort(service); 00410 } 00411 00412 /* 00413 * unsets binding address 00414 */ 00415 bool KExtendedSocket::unsetBindAddress() 00416 { 00417 return unsetBindHost() && unsetBindPort(); 00418 } 00419 00420 /* 00421 * sets the timeout for the connection 00422 */ 00423 bool KExtendedSocket::setTimeout(int secs, int usecs) 00424 { 00425 if (d->status >= connected) // closed? 00426 return false; 00427 00428 d->timeout.tv_sec = secs; 00429 d->timeout.tv_usec = usecs; 00430 return true; 00431 } 00432 00433 /* 00434 * returns the timeout 00435 */ 00436 timeval KExtendedSocket::timeout() const 00437 { 00438 return d->timeout; 00439 } 00440 00441 /* 00442 * Sets the blocking mode on this socket 00443 */ 00444 bool KExtendedSocket::setBlockingMode(bool enable) 00445 { 00446 cleanError(); 00447 if (d->status < created) 00448 return false; 00449 00450 if (sockfd == -1) 00451 return false; // error! 00452 00453 int fdflags = fcntl(sockfd, F_GETFL, 0); 00454 if (fdflags == -1) 00455 return false; // error! 00456 00457 if (!enable) 00458 fdflags |= O_NONBLOCK; 00459 else 00460 fdflags &= ~O_NONBLOCK; 00461 00462 if (fcntl(sockfd, F_SETFL, fdflags) == -1) 00463 { 00464 setError(IO_UnspecifiedError, errno); 00465 return false; 00466 } 00467 return true; 00468 } 00469 00470 /* 00471 * Returns the blocking mode on the socket 00472 */ 00473 bool KExtendedSocket::blockingMode() 00474 { 00475 cleanError(); 00476 if (d->status < created) 00477 return false; // sockets not created are in blocking mode 00478 00479 if (sockfd == -1) 00480 return false; // error 00481 00482 int fdflags = fcntl(sockfd, F_GETFL, 0); 00483 if (fdflags == -1) 00484 { 00485 setError(IO_UnspecifiedError, errno); 00486 return false; 00487 } 00488 return (fdflags & O_NONBLOCK) == 0; // non-blocking == false 00489 } 00490 00491 /* 00492 * Sets the reusability flag for this socket in the OS 00493 */ 00494 bool KExtendedSocket::setAddressReusable(bool enable) 00495 { 00496 cleanError(); 00497 d->addressReusable = enable; 00498 if (d->status < created) 00499 return true; 00500 00501 if (sockfd == -1) 00502 return true; 00503 00504 if (!setAddressReusable(sockfd, enable)) 00505 { 00506 setError(IO_UnspecifiedError, errno); 00507 return false; 00508 } 00509 return true; 00510 } 00511 00512 bool KExtendedSocket::setAddressReusable(int fd, bool enable) 00513 { 00514 if (fd == -1) 00515 return false; 00516 00517 int on = enable; // just to be on the safe side 00518 00519 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) 00520 return false; 00521 return true; 00522 } 00523 00524 /* 00525 * Retrieves the reusability flag for this socket 00526 */ 00527 bool KExtendedSocket::addressReusable() 00528 { 00529 cleanError(); 00530 if (d->status < created) 00531 return d->addressReusable; 00532 00533 if (sockfd == -1) 00534 return d->addressReusable; 00535 00536 int on; 00537 socklen_t onsiz = sizeof(on); 00538 if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, &onsiz) == -1) 00539 { 00540 setError(IO_UnspecifiedError, errno); 00541 return false; 00542 } 00543 00544 return on != 0; 00545 } 00546 00547 /* 00548 * Set the IPV6_V6ONLY flag 00549 */ 00550 bool KExtendedSocket::setIPv6Only(bool enable) 00551 { 00552 #ifdef IPV6_V6ONLY 00553 cleanError(); 00554 00555 d->ipv6only = enable; 00556 if (sockfd == -1) 00557 return true; // can't set on a non-existing socket 00558 00559 int on = enable; 00560 00561 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, 00562 (char *)&on, sizeof(on)) == -1) 00563 { 00564 setError(IO_UnspecifiedError, errno); 00565 return false; 00566 } 00567 else 00568 return true; 00569 00570 #else 00571 // we don't have the IPV6_V6ONLY constant in this system 00572 d->ipv6only = enable; 00573 00574 setError(IO_UnspecifiedError, ENOSYS); 00575 return false; // can't set if we don't know about this flag 00576 #endif 00577 } 00578 00579 /* 00580 * retrieve the IPV6_V6ONLY flag 00581 */ 00582 bool KExtendedSocket::isIPv6Only() 00583 { 00584 #ifdef IPV6_V6ONLY 00585 cleanError(); 00586 00587 if (d->status < created || sockfd == -1) 00588 return d->ipv6only; 00589 00590 int on; 00591 socklen_t onsiz = sizeof(on); 00592 if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, 00593 (char *)&on, &onsiz) == -1) 00594 { 00595 setError(IO_UnspecifiedError, errno); 00596 return false; 00597 } 00598 00599 return d->ipv6only = on; 00600 00601 #else 00602 // we don't have the constant 00603 setError(IO_UnspecifiedError, ENOSYS); 00604 return false; 00605 #endif 00606 } 00607 00608 /* 00609 * Sets the buffer sizes in this socket 00610 * Also, we create or delete the socket notifiers 00611 */ 00612 bool KExtendedSocket::setBufferSize(int rsize, int wsize) 00613 { 00614 cleanError(); 00615 if (d->status < created) 00616 return false; 00617 00618 if (sockfd == -1) 00619 return false; 00620 00621 if (d->flags & passiveSocket) 00622 return false; // no I/O on passive sockets 00623 00624 if (rsize < -2) 00625 return false; 00626 00627 if (wsize < -2) 00628 return false; 00629 00630 // LOCK BUFFER MUTEX 00631 00632 // The input socket notifier is always enabled 00633 // That happens because we want to be notified of when the socket gets 00634 // closed 00635 if (d->qsnIn == NULL) 00636 { 00637 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read); 00638 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead())); 00639 d->qsnIn->setEnabled(true); 00640 } 00641 00642 if (rsize == 0 && d->flags & inputBufferedSocket) 00643 { 00644 // user wants to disable input buffering 00645 d->flags &= ~inputBufferedSocket; 00646 00647 consumeReadBuffer(readBufferSize(), NULL, true); 00648 d->inMaxSize = 0; 00649 } 00650 else if (rsize != -2) 00651 { 00652 // enabling input buffering 00653 if (rsize) 00654 d->flags |= inputBufferedSocket; 00655 d->inMaxSize = rsize; 00656 00657 if (rsize > 0 && (unsigned)rsize < readBufferSize()) 00658 // input buffer has more data than the new size; discard 00659 consumeReadBuffer(readBufferSize() - rsize, NULL, true); 00660 00661 } 00662 00663 if (wsize == 0 && d->flags & outputBufferedSocket) 00664 { 00665 // disabling output buffering 00666 d->flags &= ~outputBufferedSocket; 00667 if (d->qsnOut && !d->emitWrite) 00668 d->qsnOut->setEnabled(false); 00669 consumeWriteBuffer(writeBufferSize()); 00670 d->outMaxSize = 0; 00671 } 00672 else if (wsize != -2) 00673 { 00674 // enabling input buffering 00675 if (wsize) 00676 d->flags |= outputBufferedSocket; 00677 d->outMaxSize = wsize; 00678 00679 if (wsize > 0 && (unsigned)wsize < writeBufferSize()) 00680 // output buffer is bigger than it is to become; shrink 00681 consumeWriteBuffer(writeBufferSize() - wsize); 00682 00683 if (d->qsnOut == NULL) 00684 { 00685 d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write); 00686 QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite())); 00687 // if the class is being created now, there's nothing to write yet 00688 // so socketActivityWrite() will get called once and disable 00689 // the notifier 00690 } 00691 } 00692 00693 // UNLOCK BUFFER MUTEX 00694 00695 setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw)); 00696 00697 // check we didn't turn something off we shouldn't 00698 if (d->emitWrite && d->qsnOut == NULL) 00699 { 00700 d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write); 00701 QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite())); 00702 } 00703 00704 return true; 00705 } 00706 00707 /* 00708 * Finds the local address for this socket 00709 * if we have done this already, we return it. Otherwise, we'll have 00710 * to find the socket name 00711 */ 00712 const ::KSocketAddress *KExtendedSocket::localAddress() 00713 { 00714 if (d->local != NULL) 00715 return d->local; 00716 if (d->status < bound) 00717 return NULL; 00718 00719 return d->local = localAddress(sockfd); 00720 } 00721 00722 /* 00723 * Same thing, but for peer address. Which means this does not work on 00724 * passiveSocket and that we require to be connected already. Also note that 00725 * the behavior on connectionless sockets is not defined here. 00726 */ 00727 const ::KSocketAddress* KExtendedSocket::peerAddress() 00728 { 00729 if (d->peer != NULL) 00730 return d->peer; 00731 if (d->flags & passiveSocket || d->status < connected) 00732 return NULL; 00733 00734 return d->peer = peerAddress(sockfd); 00735 } 00736 00737 /* 00738 * Perform the lookup on the addresses given 00739 */ 00740 int KExtendedSocket::lookup() 00741 { 00742 if (startAsyncLookup() != 0) 00743 return -1; 00744 00745 if (!d->resRemote.wait() || !d->resLocal.wait()) 00746 { 00747 d->status = nothing; 00748 return -1; 00749 } 00750 00751 d->status = lookupDone; 00752 return 0; 00753 } 00754 00755 /* 00756 * Performs an asynchronous lookup on the given address(es) 00757 */ 00758 int KExtendedSocket::startAsyncLookup() 00759 { 00760 cleanError(); 00761 if (d->status > lookupInProgress) 00762 return -1; 00763 if (d->status == lookupInProgress) 00764 // already in progress 00765 return 0; 00766 00767 /* check socket type flags */ 00768 int socktype, familyMask, flags; 00769 if (!process_flags(d->flags, socktype, familyMask, flags)) 00770 return -2; 00771 00772 // perform the global lookup before 00773 if (!d->resRemote.isRunning()) 00774 { 00775 d->resRemote.setFlags(flags); 00776 d->resRemote.setFamily(familyMask); 00777 d->resRemote.setSocketType(socktype); 00778 QObject::connect(&d->resRemote, SIGNAL(finished(KResolverResults)), 00779 this, SLOT(dnsResultsReady())); 00780 00781 if (!d->resRemote.start()) 00782 { 00783 setError(IO_LookupError, d->resRemote.error()); 00784 return d->resRemote.error(); 00785 } 00786 } 00787 00788 if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning()) 00789 { 00790 /* keep flags, but make this passive */ 00791 flags |= KResolver::Passive; 00792 d->resLocal.setFlags(flags); 00793 d->resLocal.setFamily(familyMask); 00794 d->resLocal.setSocketType(socktype); 00795 QObject::connect(&d->resLocal, SIGNAL(finished(KResolverResults)), 00796 this, SLOT(dnsResultsReady())); 00797 00798 if (!d->resLocal.start()) 00799 { 00800 setError(IO_LookupError, d->resLocal.error()); 00801 return d->resLocal.error(); 00802 } 00803 } 00804 00805 // if we are here, there were no errors 00806 if (d->resRemote.isRunning() || d->resLocal.isRunning()) 00807 d->status = lookupInProgress; // only if there actually is a running lookup 00808 else 00809 { 00810 d->status = lookupDone; 00811 emit lookupFinished(d->resRemote.results().count() + 00812 d->resLocal.results().count()); 00813 } 00814 return 0; 00815 } 00816 00817 void KExtendedSocket::cancelAsyncLookup() 00818 { 00819 cleanError(); 00820 if (d->status != lookupInProgress) 00821 return; // what's to cancel? 00822 00823 d->status = nothing; 00824 d->resLocal.cancel(false); 00825 d->resRemote.cancel(false); 00826 } 00827 00828 int KExtendedSocket::listen(int N) 00829 { 00830 cleanError(); 00831 if ((d->flags & passiveSocket) == 0 || d->status >= listening) 00832 return -2; 00833 if (d->status < lookupDone) 00834 if (lookup() != 0) 00835 return -2; // error! 00836 if (d->resRemote.error()) 00837 return -2; 00838 00839 // doing the loop: 00840 KResolverResults::const_iterator it; 00841 KResolverResults res = d->resRemote.results(); 00842 for (it = res.begin(); it != res.end(); ++it) 00843 { 00844 //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl; 00845 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 00846 if (sockfd == -1) 00847 { 00848 // socket failed creating 00849 //kdDebug(170) << "Failed to create: " << perror << endl; 00850 continue; 00851 } 00852 00853 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 00854 00855 if (d->addressReusable) 00856 setAddressReusable(sockfd, true); 00857 setIPv6Only(d->ipv6only); 00858 cleanError(); 00859 if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1) 00860 { 00861 //kdDebug(170) << "Failed to bind: " << perror << endl; 00862 ::close(sockfd); 00863 sockfd = -1; 00864 continue; 00865 } 00866 00867 // ok, socket has bound 00868 // kdDebug(170) << "Socket bound: " << sockfd << endl; 00869 00870 d->status = bound; 00871 break; 00872 } 00873 00874 if (sockfd == -1) 00875 { 00876 setError(IO_ListenError, errno); 00877 //kdDebug(170) << "Listen error - sockfd is -1 " << endl; 00878 return -1; 00879 } 00880 00881 d->status = bound; 00882 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00883 00884 int retval = KSocks::self()->listen(sockfd, N); 00885 if (retval == -1) 00886 setError(IO_ListenError, errno); 00887 else 00888 { 00889 d->status = listening; 00890 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read); 00891 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead())); 00892 } 00893 return retval == -1 ? -1 : 0; 00894 } 00895 00896 int KExtendedSocket::accept(KExtendedSocket *&sock) 00897 { 00898 cleanError(); 00899 sock = NULL; 00900 if ((d->flags & passiveSocket) == 0 || d->status >= accepting) 00901 return -2; 00902 if (d->status < listening) 00903 if (listen() < 0) 00904 return -2; // error! 00905 00906 // let's see 00907 // if we have a timeout in place, we have to place this socket in non-blocking 00908 // mode 00909 bool block = blockingMode(); 00910 struct sockaddr sa; 00911 ksocklen_t len = sizeof(sa); 00912 sock = NULL; 00913 00914 if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0) 00915 { 00916 fd_set set; 00917 00918 setBlockingMode(false); // turn on non-blocking 00919 FD_ZERO(&set); 00920 FD_SET(sockfd, &set); 00921 00922 //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n", 00923 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec); 00924 // check if there is anything to accept now 00925 int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout); 00926 if (retval == -1) 00927 { 00928 setError(IO_UnspecifiedError, errno); 00929 return -1; // system error 00930 } 00931 else if (retval == 0 || !FD_ISSET(sockfd, &set)) 00932 { 00933 setError(IO_TimeOutError, 0); 00934 return -3; // timeout 00935 } 00936 } 00937 00938 // it's common stuff here 00939 int newfd = KSocks::self()->accept(sockfd, &sa, &len); 00940 00941 if (newfd == -1) 00942 { 00943 setError(IO_AcceptError, errno); 00944 kdWarning(170) << "Error accepting on socket " << sockfd << ":" 00945 << perror << endl; 00946 return -1; 00947 } 00948 00949 fcntl(newfd, F_SETFD, FD_CLOEXEC); 00950 00951 //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd); 00952 00953 setBlockingMode(block); // restore blocking mode 00954 00955 sock = new KExtendedSocket; 00956 sock->d->status = connected; 00957 sock->sockfd = newfd; 00958 sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 00959 sock->setBufferSize(0, 0); // always unbuffered here. User can change that later 00960 00961 return 0; 00962 } 00963 00964 /* 00965 * tries to connect 00966 * 00967 * FIXME! 00968 * This function is critical path. It has to be cleaned up and made faster 00969 */ 00970 int KExtendedSocket::connect() 00971 { 00972 cleanError(); 00973 if (d->flags & passiveSocket || d->status >= connected) 00974 return -2; 00975 if (d->status < lookupDone) 00976 if (lookup() != 0) 00977 return -2; 00978 00979 timeval end, now; 00980 // Ok, things are a little tricky here 00981 // Let me explain 00982 // getaddrinfo() will return several different families of sockets 00983 // When we have to bind before we connect, we have to make sure we're binding 00984 // and connecting to the same family, or things won't work 00985 00986 bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0; 00987 if (doingtimeout) 00988 { 00989 gettimeofday(&end, NULL); 00990 end.tv_usec += d->timeout.tv_usec; 00991 end.tv_sec += d->timeout.tv_sec; 00992 if (end.tv_usec > 1000*1000) 00993 { 00994 end.tv_usec -= 1000*1000; 00995 end.tv_sec++; 00996 } 00997 // kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n", 00998 // d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec); 00999 } 01000 01001 KResolverResults remote = d->resRemote.results(), 01002 local = d->resLocal.results(); 01003 KResolverResults::const_iterator it, it2; 01004 //kdDebug(170) << "Starting connect to " << host() << '|' << port() 01005 // << ": have " << local.count() << " local entries and " 01006 // << remote.count() << " remote" << endl; 01007 for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it) 01008 { 01009 //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl; 01010 if (it2 != local.end()) 01011 { 01012 // //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl; 01013 if ((*it).family() != (*it2).family()) 01014 // differing families, scan local for a matching family 01015 for (it2 = local.begin(); it2 != local.end(); ++it2) 01016 if ((*it).family() == (*it2).family()) 01017 break; 01018 01019 if ((*it).family() != (*it2).family()) 01020 { 01021 // no matching families for this 01022 //kdDebug(170) << "No matching family for bind socket\n"; 01023 it2 = local.begin(); 01024 continue; 01025 } 01026 01027 //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl; 01028 errno = 0; 01029 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 01030 setError(IO_ConnectError, errno); 01031 if (sockfd == -1) 01032 continue; // cannot create this socket 01033 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01034 if (d->addressReusable) 01035 setAddressReusable(sockfd, true); 01036 setIPv6Only(d->ipv6only); 01037 cleanError(); 01038 if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length())) 01039 { 01040 //kdDebug(170) << "Bind failed: " << perror << endl; 01041 ::close(sockfd); 01042 sockfd = -1; 01043 continue; 01044 } 01045 } 01046 else 01047 { 01048 // no need to bind, just create 01049 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 01050 if (sockfd == -1) 01051 { 01052 setError(IO_ConnectError, errno); 01053 continue; 01054 } 01055 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01056 if (d->addressReusable) 01057 setAddressReusable(sockfd, true); 01058 setIPv6Only(d->ipv6only); 01059 cleanError(); 01060 } 01061 01062 // kdDebug(170) << "Socket " << sockfd << " created" << endl; 01063 d->status = created; 01064 01065 // check if we have to do timeout 01066 if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect()) 01067 { 01068 fd_set rd, wr; 01069 01070 setBlockingMode(false); 01071 01072 // now try and connect 01073 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1) 01074 { 01075 // this could be EWOULDBLOCK 01076 if (errno != EWOULDBLOCK && errno != EINPROGRESS) 01077 { 01078 //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl; 01079 setError(IO_ConnectError, errno); 01080 ::close(sockfd); 01081 sockfd = -1; 01082 continue; // nope, another error 01083 } 01084 01085 FD_ZERO(&rd); 01086 FD_ZERO(&wr); 01087 FD_SET(sockfd, &rd); 01088 FD_SET(sockfd, &wr); 01089 01090 int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout); 01091 if (retval == -1) 01092 { 01093 setError(IO_FatalError, errno); 01094 continue; // system error 01095 } 01096 else if (retval == 0) 01097 { 01098 ::close(sockfd); 01099 sockfd = -1; 01100 // kdDebug(170) << "Time out while trying to connect to " << 01101 // (*it).address().toString() << endl; 01102 d->status = lookupDone; 01103 setError(IO_TimeOutError, 0); 01104 return -3; // time out 01105 } 01106 01107 // adjust remaining time 01108 gettimeofday(&now, NULL); 01109 d->timeout.tv_sec = end.tv_sec - now.tv_sec; 01110 d->timeout.tv_usec = end.tv_usec - now.tv_usec; 01111 if (d->timeout.tv_usec < 0) 01112 { 01113 d->timeout.tv_usec += 1000*1000; 01114 d->timeout.tv_sec--; 01115 } 01116 // kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n", 01117 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec); 01118 01119 // this means that an event occurred in the socket 01120 int errcode; 01121 socklen_t len = sizeof(errcode); 01122 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, 01123 &len); 01124 if (retval == -1 || errcode != 0) 01125 { 01126 // socket did not connect 01127 //kdDebug(170) << "Socket " << sockfd << " did not connect: " 01128 // << strerror(errcode) << endl; 01129 ::close(sockfd); 01130 sockfd = -1; 01131 01132 // this is HIGHLY UNLIKELY 01133 if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0) 01134 { 01135 d->status = lookupDone; 01136 setError(IO_TimeOutError, 0); 01137 return -3; // time out 01138 } 01139 01140 setError(IO_ConnectError, errcode); 01141 continue; 01142 } 01143 } 01144 01145 // getting here means it connected 01146 // setBufferSize() takes care of creating the socket notifiers 01147 setBlockingMode(true); 01148 d->status = connected; 01149 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01150 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01151 d->flags & outputBufferedSocket ? -1 : 0); 01152 emit connectionSuccess(); 01153 // kdDebug(170) << "Socket " << sockfd << " connected\n"; 01154 return 0; 01155 } 01156 else 01157 { 01158 // without timeouts 01159 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1) 01160 { 01161 //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString() 01162 // << " did not connect: " << perror << endl; 01163 setError(IO_ConnectError, errno); 01164 ::close(sockfd); 01165 sockfd = -1; 01166 continue; 01167 } 01168 01169 d->status = connected; 01170 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01171 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01172 d->flags & outputBufferedSocket ? -1 : 0); 01173 emit connectionSuccess(); 01174 // kdDebug(170) << "Socket " << sockfd << " connected\n"; 01175 return 0; // it connected 01176 } 01177 } 01178 01179 // getting here means no socket connected or stuff like that 01180 emit connectionFailed(d->syserror); 01181 //kdDebug(170) << "Failed to connect\n"; 01182 return -1; 01183 } 01184 01185 int KExtendedSocket::startAsyncConnect() 01186 { 01187 cleanError(); 01188 // check status 01189 if (d->status >= connected || d->flags & passiveSocket) 01190 return -2; 01191 01192 if (d->status == connecting) 01193 // already on async connect 01194 return 0; 01195 01196 // check if we have to do lookup 01197 // if we do, then we'll use asynchronous lookup and use 01198 // signal lookupFinished to do connection 01199 if (d->status < lookupDone) 01200 { 01201 QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot())); 01202 if (d->status < lookupInProgress) 01203 return startAsyncLookup(); 01204 else 01205 return 0; // we still have to wait 01206 } 01207 01208 // here we have d->status >= lookupDone and <= connecting 01209 // we can do our connection 01210 d->status = connecting; 01211 QGuardedPtr<QObject> p = this; 01212 connectionEvent(); 01213 if (!p) 01214 return -1; // We have been deleted. 01215 if (d->status < connecting) 01216 return -1; 01217 return 0; 01218 } 01219 01220 void KExtendedSocket::cancelAsyncConnect() 01221 { 01222 if (d->status != connecting) 01223 return; 01224 01225 if (sockfd != -1) 01226 { 01227 // we have a waiting connection 01228 if (d->qsnIn) 01229 delete d->qsnIn; 01230 if (d->qsnOut) 01231 delete d->qsnOut; 01232 d->qsnIn = d->qsnOut = NULL; 01233 01234 ::close(sockfd); 01235 sockfd = -1; 01236 } 01237 d->status = lookupDone; 01238 } 01239 01240 bool KExtendedSocket::open(int mode) 01241 { 01242 if (mode != IO_Raw | IO_ReadWrite) 01243 return false; // invalid open mode 01244 01245 if (d->flags & passiveSocket) 01246 return listen() == 0; 01247 else if (d->status < connecting) 01248 return connect() == 0; 01249 else 01250 return false; 01251 } 01252 01253 void KExtendedSocket::close() 01254 { 01255 if (sockfd == -1 || d->status >= closing) 01256 return; // nothing to close 01257 01258 // LOCK BUFFER MUTEX 01259 if (d->flags & outputBufferedSocket && writeBufferSize() > 0) 01260 { 01261 // write buffer not empty, go into closing state 01262 d->status = closing; 01263 if (d->qsnIn) 01264 delete d->qsnIn; 01265 d->qsnIn = NULL; 01266 // we keep the outgoing socket notifier because we want 01267 // to send data, but not receive 01268 } 01269 else 01270 { 01271 // nope, write buffer is empty 01272 // we can close now 01273 if (d->qsnIn) 01274 delete d->qsnIn; 01275 if (d->qsnOut) 01276 delete d->qsnOut; 01277 d->qsnIn = d->qsnOut = NULL; 01278 01279 ::close(sockfd); 01280 d->status = done; 01281 emit closed(readBufferSize() != 0 ? availRead : 0); 01282 } 01283 // UNLOCK BUFFER MUTEX 01284 } 01285 01286 01287 void KExtendedSocket::closeNow() 01288 { 01289 if (d->status >= done) 01290 return; // nothing to close 01291 01292 // close the socket 01293 delete d->qsnIn; 01294 delete d->qsnOut; 01295 d->qsnIn = d->qsnOut = NULL; 01296 01297 if (d->status > connecting && sockfd != -1) 01298 { 01299 ::close(sockfd); 01300 sockfd = -1; 01301 } 01302 else if (d->status == connecting) 01303 cancelAsyncConnect(); 01304 else if (d->status == lookupInProgress) 01305 cancelAsyncLookup(); 01306 01307 d->status = done; 01308 01309 emit closed(closedNow | 01310 (readBufferSize() != 0 ? availRead : 0) | 01311 (writeBufferSize() != 0 ? dirtyWrite : 0)); 01312 } 01313 01314 void KExtendedSocket::release() 01315 { 01316 // release our hold on the socket 01317 sockfd = -1; 01318 d->status = done; 01319 01320 d->resRemote.cancel(false); 01321 d->resLocal.cancel(false); 01322 01323 if (d->local != NULL) 01324 delete d->local; 01325 if (d->peer != NULL) 01326 delete d->peer; 01327 01328 d->peer = d->local = NULL; 01329 01330 if (d->qsnIn != NULL) 01331 delete d->qsnIn; 01332 if (d->qsnOut != NULL) 01333 delete d->qsnOut; 01334 01335 d->qsnIn = d->qsnOut = NULL; 01336 01337 // now that the socket notificators are done with, we can flush out the buffers 01338 consumeReadBuffer(readBufferSize(), NULL, true); 01339 consumeWriteBuffer(writeBufferSize()); 01340 01341 // don't delete d 01342 // leave that for the destructor 01343 } 01344 01345 void KExtendedSocket::flush() 01346 { 01347 cleanError(); 01348 if (d->status < connected || d->status >= done || d->flags & passiveSocket) 01349 return; 01350 01351 if (sockfd == -1) 01352 return; 01353 01354 if ((d->flags & outputBufferedSocket) == 0) 01355 return; // nothing to do 01356 01357 // LOCK MUTEX 01358 01359 unsigned written = 0; 01360 unsigned offset = outBufIndex; // this happens only for the first 01361 while (writeBufferSize() - written > 0) 01362 { 01363 // we have to write each output buffer in outBuf 01364 // but since we can have several very small buffers, we can make things 01365 // better by concatenating a few of them into a big buffer 01366 // question is: how big should that buffer be? 16 kB should be enough 01367 01368 QByteArray buf(16384); 01369 QByteArray *a = outBuf.first(); 01370 unsigned count = 0; 01371 01372 while (a && count + (a->size() - offset) < buf.size()) 01373 { 01374 memcpy(buf.data() + count, a->data() + offset, a->size() - offset); 01375 count += a->size() - offset; 01376 offset = 0; 01377 a = outBuf.next(); 01378 } 01379 01380 // now try to write those bytes 01381 int wrote = KSocks::self()->write(sockfd, buf, count); 01382 01383 if (wrote == -1) 01384 { 01385 // could be EAGAIN (EWOULDBLOCK) 01386 setError(IO_WriteError, errno); 01387 break; 01388 } 01389 written += wrote; 01390 01391 if ((unsigned)wrote != count) 01392 break; 01393 } 01394 if (written) 01395 { 01396 consumeWriteBuffer(written); 01397 emit bytesWritten(written); 01398 } 01399 01400 // UNLOCK MUTEX 01401 } 01402 01403 01404 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen) 01405 { 01406 cleanError(); 01407 if (d->status < connected || d->flags & passiveSocket) 01408 return -2; 01409 01410 int retval; 01411 01412 if ((d->flags & inputBufferedSocket) == 0) 01413 { 01414 // we aren't buffering this socket, so just pass along 01415 // the call to the real read method 01416 01417 if (sockfd == -1) 01418 return -2; 01419 if (data) 01420 retval = KSocks::self()->read(sockfd, data, maxlen); 01421 else 01422 retval = skipData(sockfd, maxlen); 01423 if (retval == -1) 01424 setError(IO_ReadError, errno); 01425 } 01426 else 01427 { 01428 // this socket is being buffered. So read from the buffer 01429 01430 // LOCK BUFFER MUTEX 01431 01432 retval = consumeReadBuffer(maxlen, data); 01433 if (retval == 0) 01434 { 01435 // consumeReadBuffer returns 0 only if the buffer is 01436 // empty 01437 if (sockfd == -1) 01438 return 0; // buffer is clear now, indicate EOF 01439 setError(IO_ReadError, EWOULDBLOCK); 01440 retval = -1; 01441 } 01442 01443 // UNLOCK BUFFER MUTEX 01444 01445 } 01446 return retval; 01447 } 01448 01449 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len) 01450 { 01451 cleanError(); 01452 if (d->status < connected || d->status >= closing || d->flags & passiveSocket) 01453 return -2; 01454 if (sockfd == -1) 01455 return -2; 01456 01457 if (len == 0) 01458 return 0; // what's to write? 01459 01460 int retval; 01461 01462 if ((d->flags & outputBufferedSocket) == 0) 01463 { 01464 // socket not buffered. Just call write 01465 retval = KSocks::self()->write(sockfd, data, len); 01466 if (retval == -1) 01467 setError(IO_WriteError, errno); 01468 else 01469 emit bytesWritten(retval); 01470 } 01471 else 01472 { 01473 // socket is buffered. Feed the write buffer 01474 01475 // LOCK BUFFER MUTEX 01476 01477 register unsigned wsize = writeBufferSize(); 01478 if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning 01479 { 01480 // buffer is full! 01481 setError(IO_WriteError, EWOULDBLOCK); 01482 retval = -1; 01483 } 01484 else 01485 { 01486 if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize) 01487 // we cannot write all data. Write just as much as to fill the buffer 01488 len = d->outMaxSize - wsize; 01489 01490 // len > 0 here 01491 retval = feedWriteBuffer(len, data); 01492 if (wsize == 0 || d->emitWrite) 01493 // buffer was empty, which means that the notifier is probably disabled 01494 d->qsnOut->setEnabled(true); 01495 } 01496 01497 // UNLOCK BUFFER MUTEX 01498 } 01499 01500 return retval; 01501 } 01502 01503 int KExtendedSocket::peekBlock(char *data, uint maxlen) 01504 { 01505 if (d->status < connected || d->flags & passiveSocket) 01506 return -2; 01507 if (sockfd == -1) 01508 return -2; 01509 01510 // need to LOCK MUTEX around this call... 01511 01512 if (d->flags & inputBufferedSocket) 01513 return consumeReadBuffer(maxlen, data, false); 01514 01515 return 0; 01516 } 01517 01518 int KExtendedSocket::unreadBlock(const char *, uint) 01519 { 01520 // Always return -1, indicating this is not supported 01521 setError(IO_ReadError, ENOSYS); 01522 return -1; 01523 } 01524 01525 int KExtendedSocket::bytesAvailable() const 01526 { 01527 if (d->status < connected || d->flags & passiveSocket) 01528 return -2; 01529 01530 // as of now, we don't do any extra processing 01531 // we only work in input-buffered sockets 01532 if (d->flags & inputBufferedSocket) 01533 return KBufferedIO::bytesAvailable(); 01534 01535 return 0; // TODO: FIONREAD ioctl 01536 } 01537 01538 int KExtendedSocket::waitForMore(int msecs) 01539 { 01540 cleanError(); 01541 if (d->flags & passiveSocket || d->status < connected || d->status >= closing) 01542 return -2; 01543 if (sockfd == -1) 01544 return -2; 01545 01546 fd_set rd; 01547 FD_ZERO(&rd); 01548 FD_SET(sockfd, &rd); 01549 timeval tv; 01550 tv.tv_sec = msecs / 1000; 01551 tv.tv_usec = (msecs % 1000) * 1000; 01552 01553 int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv); 01554 if (retval == -1) 01555 { 01556 setError(IO_FatalError, errno); 01557 return -1; 01558 } 01559 else if (retval != 0) 01560 socketActivityRead(); // do read processing 01561 01562 return bytesAvailable(); 01563 } 01564 01565 int KExtendedSocket::getch() 01566 { 01567 unsigned char c; 01568 int retval; 01569 retval = readBlock((char*)&c, sizeof(c)); 01570 01571 if (retval < 0) 01572 return retval; 01573 return c; 01574 } 01575 01576 int KExtendedSocket::putch(int ch) 01577 { 01578 unsigned char c = (char)ch; 01579 return writeBlock((char*)&c, sizeof(c)); 01580 } 01581 01582 // sets the emission of the readyRead signal 01583 void KExtendedSocket::enableRead(bool enable) 01584 { 01585 // check if we can disable the socket notifier 01586 // saves us a few cycles 01587 // this is so because in buffering mode, we rely on these signals 01588 // being emitted to do our I/O. We couldn't disable them here 01589 if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn) 01590 d->qsnIn->setEnabled(false); 01591 else if (enable && d->qsnIn) 01592 // we can enable it always 01593 d->qsnIn->setEnabled(true); 01594 d->emitRead = enable; 01595 } 01596 01597 // sets the emission of the readyWrite signal 01598 void KExtendedSocket::enableWrite(bool enable) 01599 { 01600 // same thing as above 01601 if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut) 01602 d->qsnOut->setEnabled(false); 01603 else if (enable && d->qsnOut) 01604 // we can enable it always 01605 d->qsnOut->setEnabled(true); 01606 d->emitWrite = enable; 01607 } 01608 01609 // protected slot 01610 // this is connected to d->qsnIn::activated(int) 01611 void KExtendedSocket::socketActivityRead() 01612 { 01613 if (d->flags & passiveSocket) 01614 { 01615 emit readyAccept(); 01616 return; 01617 } 01618 if (d->status == connecting) 01619 { 01620 connectionEvent(); 01621 return; 01622 } 01623 if (d->status != connected) 01624 return; 01625 01626 // do we need to do I/O here? 01627 if (d->flags & inputBufferedSocket) 01628 { 01629 // aye. Do read from the socket and feed our buffer 01630 QByteArray a; 01631 char buf[1024]; 01632 int len, totalread = 0; 01633 01634 // LOCK MUTEX 01635 01636 unsigned cursize = readBufferSize(); 01637 01638 if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize) 01639 { 01640 do 01641 { 01642 // check that we can read that many bytes 01643 if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf)) 01644 // no, that would overrun the buffer 01645 // note that this will also make us exit the loop 01646 len = d->inMaxSize - (cursize + totalread); 01647 else 01648 len = sizeof(buf); 01649 01650 len = KSocks::self()->read(sockfd, buf, len); 01651 if (len > 0) 01652 { 01653 // normal read operation 01654 a.resize(a.size() + len); 01655 memcpy(a.data() + totalread, buf, len); 01656 totalread += len; // totalread == a.size() now 01657 } 01658 else if (len == 0) 01659 { 01660 // EOF condition here 01661 ::close(sockfd); 01662 sockfd = -1; // we're closed 01663 d->qsnIn->deleteLater(); 01664 delete d->qsnOut; 01665 d->qsnIn = d->qsnOut = NULL; 01666 d->status = done; 01667 emit closed(involuntary | 01668 (readBufferSize() ? availRead : 0) | 01669 (writeBufferSize() ? dirtyWrite : 0)); 01670 return; 01671 } 01672 else 01673 { 01674 // error! 01675 setError(IO_ReadError, errno); 01676 return; 01677 } 01678 // will loop only for normal read operations 01679 } 01680 while (len == sizeof(buf)); 01681 01682 feedReadBuffer(a.size(), a.data()); 01683 } 01684 01685 // UNLOCK MUTEX 01686 } 01687 else 01688 { 01689 // No input buffering, but the notifier fired 01690 // That means that either there is data to be read or that the 01691 // socket closed. 01692 01693 // try to read one byte. If we can't, then the socket got closed 01694 01695 char c; 01696 int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK); 01697 if (len == 0) 01698 { 01699 // yes, it's an EOF condition 01700 d->qsnIn->setEnabled(false); 01701 ::close(sockfd); 01702 sockfd = -1; 01703 d->status = done; 01704 emit closed(involuntary); 01705 return; 01706 } 01707 } 01708 01709 if (d->emitRead) 01710 emit readyRead(); 01711 } 01712 01713 void KExtendedSocket::socketActivityWrite() 01714 { 01715 if (d->flags & passiveSocket) 01716 return; 01717 if (d->status == connecting) 01718 { 01719 connectionEvent(); 01720 return; 01721 } 01722 if (d->status != connected && d->status != closing) 01723 return; 01724 01725 flush(); 01726 01727 bool empty = writeBufferSize() == 0; 01728 01729 if (d->emitWrite && empty) 01730 emit readyWrite(); 01731 else if (!d->emitWrite) 01732 { 01733 // check if we can disable the notifier 01734 d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send 01735 } 01736 if (d->status == closing && empty) 01737 { 01738 // done sending the missing data! 01739 d->status = done; 01740 01741 delete d->qsnOut; 01742 ::close(sockfd); 01743 01744 d->qsnOut = NULL; 01745 sockfd = -1; 01746 emit closed(delayed | (readBufferSize() ? availRead : 0)); 01747 } 01748 } 01749 01750 // this function is called whenever we have a "connection event" 01751 // that is, whenever our asynchronously connecting socket throws 01752 // an event 01753 void KExtendedSocket::connectionEvent() 01754 { 01755 if (d->status != connecting) 01756 return; // move along. There's nothing to see here 01757 01758 KResolverResults remote = d->resRemote.results(); 01759 if (remote.count() == 0) 01760 { 01761 // We have a problem! Abort? 01762 kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n"; 01763 return; 01764 } 01765 01766 int errcode = 0; 01767 01768 if (sockfd != -1) 01769 { 01770 // our socket has activity 01771 // find out what it was 01772 int retval; 01773 socklen_t len = sizeof(errcode); 01774 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len); 01775 01776 if (retval == -1 || errcode != 0) 01777 { 01778 // socket activity and there was error? 01779 // that means the socket probably did not connect 01780 if (d->qsnIn) 01781 delete d->qsnIn; 01782 if (d->qsnOut) 01783 delete d->qsnOut; 01784 ::close(sockfd); 01785 01786 sockfd = -1; 01787 d->qsnIn = d->qsnOut = NULL; 01788 setError(IO_ConnectError, errcode); 01789 } 01790 else 01791 { 01792 // hmm, socket activity and there was no error? 01793 // that means it connected 01794 // YAY! 01795 cleanError(); 01796 d->status = connected; 01797 setBlockingMode(true); 01798 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01799 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01800 d->flags & outputBufferedSocket ? -1 : 0); 01801 emit connectionSuccess(); 01802 return; 01803 } 01804 } 01805 01806 // ok, we have to try something here 01807 // and sockfd == -1 01808 KResolverResults local = d->resLocal.results(); 01809 unsigned localidx = 0; 01810 for ( ; d->current < remote.count(); d->current++) 01811 { 01812 // same code as in connect() 01813 if (local.count() != 0) 01814 { 01815 // scan bindres for a local resuls family 01816 for (localidx = 0; localidx < local.count(); localidx++) 01817 if (remote[d->current].family() == local[localidx].family()) 01818 break; 01819 01820 if (remote[d->current].family() != local[localidx].family()) 01821 { 01822 // no matching families for this 01823 continue; 01824 } 01825 01826 errno = 0; 01827 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(), 01828 remote[d->current].protocol()); 01829 setError(IO_ConnectError, errno); 01830 errcode = errno; 01831 if (sockfd == -1) 01832 continue; // cannot create this socket 01833 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01834 if (d->addressReusable) 01835 setAddressReusable(sockfd, true); 01836 setIPv6Only(d->ipv6only); 01837 cleanError(); 01838 if (KSocks::self()->bind(sockfd, local[localidx].address(), 01839 local[localidx].length()) == -1) 01840 { 01841 ::close(sockfd); 01842 sockfd = -1; 01843 continue; 01844 } 01845 } 01846 else 01847 { 01848 // no need to bind, just create 01849 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(), 01850 remote[d->current].protocol()); 01851 if (sockfd == -1) 01852 { 01853 setError(IO_ConnectError, errno); 01854 errcode = errno; 01855 continue; 01856 } 01857 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01858 if (d->addressReusable) 01859 setAddressReusable(sockfd, true); 01860 setIPv6Only(d->ipv6only); 01861 cleanError(); 01862 } 01863 01864 if (KSocks::self()->hasWorkingAsyncConnect()) 01865 setBlockingMode(false); 01866 if (KSocks::self()->connect(sockfd, remote[d->current].address(), 01867 remote[d->current].length()) == -1) 01868 { 01869 if (errno != EWOULDBLOCK && errno != EINPROGRESS) 01870 { 01871 setError(IO_ConnectError, errno); 01872 ::close(sockfd); 01873 sockfd = -1; 01874 errcode = errno; 01875 continue; 01876 } 01877 01878 // error here is either EWOULDBLOCK or EINPROGRESS 01879 // so, it is a good condition 01880 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read); 01881 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead())); 01882 d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write); 01883 QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite())); 01884 01885 // ok, let the Qt event loop do the selecting for us 01886 return; 01887 } 01888 01889 // eh, what? 01890 // the non-blocking socket returned valid connection? 01891 // already? 01892 // I suppose that could happen... 01893 cleanError(); 01894 d->status = connected; 01895 setBlockingMode(true); 01896 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01897 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01898 d->flags & outputBufferedSocket ? -1 : 0); 01899 emit connectionSuccess(); 01900 return; 01901 } 01902 01903 // if we got here, it means that there are no more options to connect 01904 d->status = lookupDone; // go back 01905 emit connectionFailed(errcode); 01906 } 01907 01908 void KExtendedSocket::dnsResultsReady() 01909 { 01910 // check that this function was called in a valid state 01911 if (d->status != lookupInProgress) 01912 return; 01913 01914 // valid state. Are results fully ready? 01915 if (d->resRemote.isRunning() || d->resLocal.isRunning()) 01916 // no, still waiting for answer in one of the lookups 01917 return; 01918 01919 // ok, we have all results 01920 // count how many results we have 01921 int n = d->resRemote.results().count() + d->resLocal.results().count(); 01922 01923 if (n) 01924 { 01925 d->status = lookupDone; 01926 cleanError(); 01927 } 01928 else 01929 { 01930 d->status = nothing; 01931 setError(IO_LookupError, KResolver::NoName); 01932 } 01933 01934 emit lookupFinished(n); 01935 01936 return; 01937 } 01938 01939 void KExtendedSocket::startAsyncConnectSlot() 01940 { 01941 QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot())); 01942 01943 if (d->status == lookupDone) 01944 startAsyncConnect(); 01945 } 01946 01947 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host, 01948 QString &port, int flags) 01949 { 01950 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl; 01951 01952 int err; 01953 char h[NI_MAXHOST], s[NI_MAXSERV]; 01954 01955 h[0] = s[0] = '\0'; 01956 01957 err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags); 01958 host = QString::fromUtf8(h); 01959 port = QString::fromUtf8(s); 01960 01961 return err; 01962 } 01963 01964 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port, 01965 int flags) 01966 { 01967 return resolve(sock->data, sock->datasize, host, port, flags); 01968 } 01969 01970 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port, 01971 int userflags, int *error) 01972 { 01973 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl; 01974 01975 int socktype, familyMask, flags; 01976 unsigned i; 01977 QPtrList<KAddressInfo> l; 01978 01979 /* check socket type flags */ 01980 if (!process_flags(userflags, socktype, familyMask, flags)) 01981 return l; 01982 01983 // kdDebug(170) << "Performing lookup on " << host << "|" << port << endl; 01984 KResolverResults res = KResolver::resolve(host, port, flags, familyMask); 01985 if (res.error()) 01986 { 01987 if (error) 01988 *error = res.error(); 01989 return l; 01990 } 01991 01992 for (i = 0; i < res.count(); i++) 01993 { 01994 KAddressInfo *ai = new KAddressInfo(); 01995 01996 // I should have known that using addrinfo was going to come 01997 // and bite me back some day... 01998 ai->ai = (addrinfo *) malloc(sizeof(addrinfo)); 01999 memset(ai->ai, 0, sizeof(addrinfo)); 02000 02001 ai->ai->ai_family = res[i].family(); 02002 ai->ai->ai_socktype = res[i].socketType(); 02003 ai->ai->ai_protocol = res[i].protocol(); 02004 QString canon = res[i].canonicalName(); 02005 if (!canon.isEmpty()) 02006 { 02007 ai->ai->ai_canonname = (char *) malloc(canon.length()+1); 02008 strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional 02009 } 02010 if ((ai->ai->ai_addrlen = res[i].length())) 02011 { 02012 ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length()); 02013 memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length()); 02014 } 02015 else 02016 { 02017 ai->ai->ai_addr = 0; 02018 } 02019 02020 ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen); 02021 02022 l.append(ai); 02023 } 02024 02025 if ( error ) 02026 *error = 0; // all is fine! 02027 02028 return l; 02029 } 02030 02031 ::KSocketAddress *KExtendedSocket::localAddress(int fd) 02032 { 02033 ::KSocketAddress *local; 02034 struct sockaddr static_sa, *sa = &static_sa; 02035 ksocklen_t len = sizeof(static_sa); 02036 02037 /* find out the socket length, in advance 02038 * we use a sockaddr allocated on the heap just not to pass down 02039 * a NULL pointer to the first call. Some systems are reported to 02040 * set len to 0 if we pass NULL as the sockaddr */ 02041 if (KSocks::self()->getsockname(fd, sa, &len) == -1) 02042 return NULL; // error! 02043 02044 /* was it enough? */ 02045 if (len > sizeof(static_sa) 02046 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02047 || sa->sa_len > sizeof(static_sa) 02048 #endif 02049 ) 02050 { 02051 /* nope, malloc a new socket with the proper size */ 02052 02053 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02054 if (sa->sa_len != len) 02055 len = sa->sa_len; 02056 #endif 02057 02058 sa = (sockaddr*)malloc(len); 02059 if (sa == NULL) 02060 return NULL; // out of memory 02061 02062 if (KSocks::self()->getsockname(fd, sa, &len) == -1) 02063 { 02064 free(sa); 02065 return NULL; 02066 } 02067 02068 local = ::KSocketAddress::newAddress(sa, len); 02069 free(sa); 02070 } 02071 else 02072 local = ::KSocketAddress::newAddress(sa, len); 02073 02074 return local; 02075 } 02076 02077 /* This is exactly the same code as localAddress, except 02078 * we call getpeername here */ 02079 ::KSocketAddress *KExtendedSocket::peerAddress(int fd) 02080 { 02081 ::KSocketAddress *peer; 02082 struct sockaddr static_sa, *sa = &static_sa; 02083 ksocklen_t len = sizeof(static_sa); 02084 02085 /* find out the socket length, in advance 02086 * we use a sockaddr allocated on the heap just not to pass down 02087 * a NULL pointer to the first call. Some systems are reported to 02088 * set len to 0 if we pass NULL as the sockaddr */ 02089 if (KSocks::self()->getpeername(fd, sa, &len) == -1) 02090 return NULL; // error! 02091 02092 /* was it enough? */ 02093 if (len > sizeof(static_sa) 02094 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02095 || sa->sa_len > sizeof(static_sa) 02096 #endif 02097 ) 02098 { 02099 /* nope, malloc a new socket with the proper size */ 02100 02101 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02102 if (sa->sa_len != len) 02103 len = sa->sa_len; 02104 #endif 02105 02106 sa = (sockaddr*)malloc(len); 02107 if (sa == NULL) 02108 return NULL; // out of memory 02109 02110 if (KSocks::self()->getpeername(fd, sa, &len) == -1) 02111 { 02112 free(sa); 02113 return NULL; 02114 } 02115 02116 peer = ::KSocketAddress::newAddress(sa, len); 02117 free(sa); 02118 } 02119 else 02120 peer = ::KSocketAddress::newAddress(sa, len); 02121 02122 return peer; 02123 } 02124 02125 QString KExtendedSocket::strError(int code, int syserr) 02126 { 02127 const char * msg; 02128 if (code == IO_LookupError) 02129 msg = gai_strerror(syserr); 02130 else 02131 msg = strerror(syserr); 02132 02133 return QString::fromLocal8Bit(msg); 02134 } 02135 02136 02137 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; } 02138 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; } 02139 02140 /* 02141 * class KAddressInfo 02142 */ 02143 02144 #if 0 02145 KAddressInfo::KAddressInfo(addrinfo *p) 02146 { 02147 ai = (addrinfo *) malloc(sizeof(addrinfo)); 02148 memcpy(ai, p, sizeof(addrinfo)); 02149 ai->ai_next = NULL; 02150 if (p->ai_canonname) 02151 { 02152 ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1); 02153 strcpy(ai->ai_canonname, p->ai_canonname); 02154 } 02155 if (p->ai_addr && p->ai_addrlen) 02156 { 02157 ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen); 02158 memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen); 02159 } 02160 else 02161 { 02162 ai->ai_addr = 0; 02163 ai->ai_addrlen = 0; 02164 } 02165 02166 addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen); 02167 } 02168 #endif 02169 KAddressInfo::~KAddressInfo() 02170 { 02171 if (ai && ai->ai_canonname) 02172 free(ai->ai_canonname); 02173 02174 if (ai && ai->ai_addr) 02175 free(ai->ai_addr); 02176 02177 if (ai) 02178 free(ai); 02179 delete addr; 02180 } 02181 02182 int KAddressInfo::flags() const 02183 { 02184 return ai->ai_flags; 02185 } 02186 02187 int KAddressInfo::family() const 02188 { 02189 return ai->ai_family; 02190 } 02191 02192 int KAddressInfo::socktype() const 02193 { 02194 return ai->ai_socktype; 02195 } 02196 02197 int KAddressInfo::protocol() const 02198 { 02199 return ai->ai_protocol; 02200 } 02201 02202 const char* KAddressInfo::canonname() const 02203 { 02204 return ai->ai_canonname; 02205 } 02206 02207 void KExtendedSocket::virtual_hook( int id, void* data ) 02208 { KBufferedIO::virtual_hook( id, data ); } 02209 02210 #include "kextsock.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:10 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003