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 if (d->resRemote.error() != KResolver::NoError) 00753 return d->resRemote.error(); 00754 if (d->resLocal.error() != KResolver::NoError) 00755 return d->resLocal.error(); 00756 return 0; 00757 } 00758 00759 /* 00760 * Performs an asynchronous lookup on the given address(es) 00761 */ 00762 int KExtendedSocket::startAsyncLookup() 00763 { 00764 cleanError(); 00765 if (d->status > lookupInProgress) 00766 return -1; 00767 if (d->status == lookupInProgress) 00768 // already in progress 00769 return 0; 00770 00771 /* check socket type flags */ 00772 int socktype, familyMask, flags; 00773 if (!process_flags(d->flags, socktype, familyMask, flags)) 00774 return -2; 00775 00776 // perform the global lookup before 00777 if (!d->resRemote.isRunning()) 00778 { 00779 d->resRemote.setFlags(flags); 00780 d->resRemote.setFamily(familyMask); 00781 d->resRemote.setSocketType(socktype); 00782 QObject::connect(&d->resRemote, SIGNAL(finished(KResolverResults)), 00783 this, SLOT(dnsResultsReady())); 00784 00785 if (!d->resRemote.start()) 00786 { 00787 setError(IO_LookupError, d->resRemote.error()); 00788 return d->resRemote.error(); 00789 } 00790 } 00791 00792 if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning()) 00793 { 00794 /* keep flags, but make this passive */ 00795 flags |= KResolver::Passive; 00796 d->resLocal.setFlags(flags); 00797 d->resLocal.setFamily(familyMask); 00798 d->resLocal.setSocketType(socktype); 00799 QObject::connect(&d->resLocal, SIGNAL(finished(KResolverResults)), 00800 this, SLOT(dnsResultsReady())); 00801 00802 if (!d->resLocal.start()) 00803 { 00804 setError(IO_LookupError, d->resLocal.error()); 00805 return d->resLocal.error(); 00806 } 00807 } 00808 00809 // if we are here, there were no errors 00810 if (d->resRemote.isRunning() || d->resLocal.isRunning()) 00811 d->status = lookupInProgress; // only if there actually is a running lookup 00812 else 00813 { 00814 d->status = lookupDone; 00815 emit lookupFinished(d->resRemote.results().count() + 00816 d->resLocal.results().count()); 00817 } 00818 return 0; 00819 } 00820 00821 void KExtendedSocket::cancelAsyncLookup() 00822 { 00823 cleanError(); 00824 if (d->status != lookupInProgress) 00825 return; // what's to cancel? 00826 00827 d->status = nothing; 00828 d->resLocal.cancel(false); 00829 d->resRemote.cancel(false); 00830 } 00831 00832 int KExtendedSocket::listen(int N) 00833 { 00834 cleanError(); 00835 if ((d->flags & passiveSocket) == 0 || d->status >= listening) 00836 return -2; 00837 if (d->status < lookupDone) 00838 if (lookup() != 0) 00839 return -2; // error! 00840 if (d->resRemote.error()) 00841 return -2; 00842 00843 // doing the loop: 00844 KResolverResults::const_iterator it; 00845 KResolverResults res = d->resRemote.results(); 00846 for (it = res.begin(); it != res.end(); ++it) 00847 { 00848 //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl; 00849 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 00850 if (sockfd == -1) 00851 { 00852 // socket failed creating 00853 //kdDebug(170) << "Failed to create: " << perror << endl; 00854 continue; 00855 } 00856 00857 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 00858 00859 if (d->addressReusable) 00860 setAddressReusable(sockfd, true); 00861 setIPv6Only(d->ipv6only); 00862 cleanError(); 00863 if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1) 00864 { 00865 //kdDebug(170) << "Failed to bind: " << perror << endl; 00866 ::close(sockfd); 00867 sockfd = -1; 00868 continue; 00869 } 00870 00871 // ok, socket has bound 00872 // kdDebug(170) << "Socket bound: " << sockfd << endl; 00873 00874 d->status = bound; 00875 break; 00876 } 00877 00878 if (sockfd == -1) 00879 { 00880 setError(IO_ListenError, errno); 00881 //kdDebug(170) << "Listen error - sockfd is -1 " << endl; 00882 return -1; 00883 } 00884 00885 d->status = bound; 00886 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00887 00888 int retval = KSocks::self()->listen(sockfd, N); 00889 if (retval == -1) 00890 setError(IO_ListenError, errno); 00891 else 00892 { 00893 d->status = listening; 00894 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read); 00895 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead())); 00896 } 00897 return retval == -1 ? -1 : 0; 00898 } 00899 00900 int KExtendedSocket::accept(KExtendedSocket *&sock) 00901 { 00902 cleanError(); 00903 sock = NULL; 00904 if ((d->flags & passiveSocket) == 0 || d->status >= accepting) 00905 return -2; 00906 if (d->status < listening) 00907 if (listen() < 0) 00908 return -2; // error! 00909 00910 // let's see 00911 // if we have a timeout in place, we have to place this socket in non-blocking 00912 // mode 00913 bool block = blockingMode(); 00914 struct sockaddr sa; 00915 ksocklen_t len = sizeof(sa); 00916 sock = NULL; 00917 00918 if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0) 00919 { 00920 fd_set set; 00921 00922 setBlockingMode(false); // turn on non-blocking 00923 FD_ZERO(&set); 00924 FD_SET(sockfd, &set); 00925 00926 //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n", 00927 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec); 00928 // check if there is anything to accept now 00929 int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout); 00930 if (retval == -1) 00931 { 00932 setError(IO_UnspecifiedError, errno); 00933 return -1; // system error 00934 } 00935 else if (retval == 0 || !FD_ISSET(sockfd, &set)) 00936 { 00937 setError(IO_TimeOutError, 0); 00938 return -3; // timeout 00939 } 00940 } 00941 00942 // it's common stuff here 00943 int newfd = KSocks::self()->accept(sockfd, &sa, &len); 00944 00945 if (newfd == -1) 00946 { 00947 setError(IO_AcceptError, errno); 00948 kdWarning(170) << "Error accepting on socket " << sockfd << ":" 00949 << perror << endl; 00950 return -1; 00951 } 00952 00953 fcntl(newfd, F_SETFD, FD_CLOEXEC); 00954 00955 //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd); 00956 00957 setBlockingMode(block); // restore blocking mode 00958 00959 sock = new KExtendedSocket; 00960 sock->d->status = connected; 00961 sock->sockfd = newfd; 00962 sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 00963 sock->setBufferSize(0, 0); // always unbuffered here. User can change that later 00964 00965 return 0; 00966 } 00967 00968 /* 00969 * tries to connect 00970 * 00971 * FIXME! 00972 * This function is critical path. It has to be cleaned up and made faster 00973 */ 00974 int KExtendedSocket::connect() 00975 { 00976 cleanError(); 00977 if (d->flags & passiveSocket || d->status >= connected) 00978 return -2; 00979 if (d->status < lookupDone) 00980 if (lookup() != 0) 00981 return -2; 00982 00983 timeval end, now; 00984 // Ok, things are a little tricky here 00985 // Let me explain 00986 // getaddrinfo() will return several different families of sockets 00987 // When we have to bind before we connect, we have to make sure we're binding 00988 // and connecting to the same family, or things won't work 00989 00990 bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0; 00991 if (doingtimeout) 00992 { 00993 gettimeofday(&end, NULL); 00994 end.tv_usec += d->timeout.tv_usec; 00995 end.tv_sec += d->timeout.tv_sec; 00996 if (end.tv_usec > 1000*1000) 00997 { 00998 end.tv_usec -= 1000*1000; 00999 end.tv_sec++; 01000 } 01001 // kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n", 01002 // d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec); 01003 } 01004 01005 KResolverResults remote = d->resRemote.results(), 01006 local = d->resLocal.results(); 01007 KResolverResults::const_iterator it, it2; 01008 //kdDebug(170) << "Starting connect to " << host() << '|' << port() 01009 // << ": have " << local.count() << " local entries and " 01010 // << remote.count() << " remote" << endl; 01011 for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it) 01012 { 01013 //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl; 01014 if (it2 != local.end()) 01015 { 01016 // //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl; 01017 if ((*it).family() != (*it2).family()) 01018 // differing families, scan local for a matching family 01019 for (it2 = local.begin(); it2 != local.end(); ++it2) 01020 if ((*it).family() == (*it2).family()) 01021 break; 01022 01023 if ((*it).family() != (*it2).family()) 01024 { 01025 // no matching families for this 01026 //kdDebug(170) << "No matching family for bind socket\n"; 01027 it2 = local.begin(); 01028 continue; 01029 } 01030 01031 //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl; 01032 errno = 0; 01033 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 01034 setError(IO_ConnectError, errno); 01035 if (sockfd == -1) 01036 continue; // cannot create this socket 01037 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01038 if (d->addressReusable) 01039 setAddressReusable(sockfd, true); 01040 setIPv6Only(d->ipv6only); 01041 cleanError(); 01042 if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length())) 01043 { 01044 //kdDebug(170) << "Bind failed: " << perror << endl; 01045 ::close(sockfd); 01046 sockfd = -1; 01047 continue; 01048 } 01049 } 01050 else 01051 { 01052 // no need to bind, just create 01053 sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol()); 01054 if (sockfd == -1) 01055 { 01056 setError(IO_ConnectError, errno); 01057 continue; 01058 } 01059 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01060 if (d->addressReusable) 01061 setAddressReusable(sockfd, true); 01062 setIPv6Only(d->ipv6only); 01063 cleanError(); 01064 } 01065 01066 // kdDebug(170) << "Socket " << sockfd << " created" << endl; 01067 d->status = created; 01068 01069 // check if we have to do timeout 01070 if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect()) 01071 { 01072 fd_set rd, wr; 01073 01074 setBlockingMode(false); 01075 01076 // now try and connect 01077 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1) 01078 { 01079 // this could be EWOULDBLOCK 01080 if (errno != EWOULDBLOCK && errno != EINPROGRESS) 01081 { 01082 //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl; 01083 setError(IO_ConnectError, errno); 01084 ::close(sockfd); 01085 sockfd = -1; 01086 continue; // nope, another error 01087 } 01088 01089 FD_ZERO(&rd); 01090 FD_ZERO(&wr); 01091 FD_SET(sockfd, &rd); 01092 FD_SET(sockfd, &wr); 01093 01094 int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout); 01095 if (retval == -1) 01096 { 01097 setError(IO_FatalError, errno); 01098 continue; // system error 01099 } 01100 else if (retval == 0) 01101 { 01102 ::close(sockfd); 01103 sockfd = -1; 01104 // kdDebug(170) << "Time out while trying to connect to " << 01105 // (*it).address().toString() << endl; 01106 d->status = lookupDone; 01107 setError(IO_TimeOutError, 0); 01108 return -3; // time out 01109 } 01110 01111 // adjust remaining time 01112 gettimeofday(&now, NULL); 01113 d->timeout.tv_sec = end.tv_sec - now.tv_sec; 01114 d->timeout.tv_usec = end.tv_usec - now.tv_usec; 01115 if (d->timeout.tv_usec < 0) 01116 { 01117 d->timeout.tv_usec += 1000*1000; 01118 d->timeout.tv_sec--; 01119 } 01120 // kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n", 01121 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec); 01122 01123 // this means that an event occurred in the socket 01124 int errcode; 01125 socklen_t len = sizeof(errcode); 01126 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, 01127 &len); 01128 if (retval == -1 || errcode != 0) 01129 { 01130 // socket did not connect 01131 //kdDebug(170) << "Socket " << sockfd << " did not connect: " 01132 // << strerror(errcode) << endl; 01133 ::close(sockfd); 01134 sockfd = -1; 01135 01136 // this is HIGHLY UNLIKELY 01137 if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0) 01138 { 01139 d->status = lookupDone; 01140 setError(IO_TimeOutError, 0); 01141 return -3; // time out 01142 } 01143 01144 setError(IO_ConnectError, errcode); 01145 continue; 01146 } 01147 } 01148 01149 // getting here means it connected 01150 // setBufferSize() takes care of creating the socket notifiers 01151 setBlockingMode(true); 01152 d->status = connected; 01153 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01154 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01155 d->flags & outputBufferedSocket ? -1 : 0); 01156 emit connectionSuccess(); 01157 // kdDebug(170) << "Socket " << sockfd << " connected\n"; 01158 return 0; 01159 } 01160 else 01161 { 01162 // without timeouts 01163 if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1) 01164 { 01165 //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString() 01166 // << " did not connect: " << perror << endl; 01167 setError(IO_ConnectError, errno); 01168 ::close(sockfd); 01169 sockfd = -1; 01170 continue; 01171 } 01172 01173 d->status = connected; 01174 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01175 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01176 d->flags & outputBufferedSocket ? -1 : 0); 01177 emit connectionSuccess(); 01178 // kdDebug(170) << "Socket " << sockfd << " connected\n"; 01179 return 0; // it connected 01180 } 01181 } 01182 01183 // getting here means no socket connected or stuff like that 01184 emit connectionFailed(d->syserror); 01185 //kdDebug(170) << "Failed to connect\n"; 01186 return -1; 01187 } 01188 01189 int KExtendedSocket::startAsyncConnect() 01190 { 01191 cleanError(); 01192 // check status 01193 if (d->status >= connected || d->flags & passiveSocket) 01194 return -2; 01195 01196 if (d->status == connecting) 01197 // already on async connect 01198 return 0; 01199 01200 // check if we have to do lookup 01201 // if we do, then we'll use asynchronous lookup and use 01202 // signal lookupFinished to do connection 01203 if (d->status < lookupDone) 01204 { 01205 QObject::connect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot())); 01206 if (d->status < lookupInProgress) 01207 return startAsyncLookup(); 01208 else 01209 return 0; // we still have to wait 01210 } 01211 01212 // here we have d->status >= lookupDone and <= connecting 01213 // we can do our connection 01214 d->status = connecting; 01215 QGuardedPtr<QObject> p = this; 01216 connectionEvent(); 01217 if (!p) 01218 return -1; // We have been deleted. 01219 if (d->status < connecting) 01220 return -1; 01221 return 0; 01222 } 01223 01224 void KExtendedSocket::cancelAsyncConnect() 01225 { 01226 if (d->status != connecting) 01227 return; 01228 01229 if (sockfd != -1) 01230 { 01231 // we have a waiting connection 01232 if (d->qsnIn) 01233 delete d->qsnIn; 01234 if (d->qsnOut) 01235 delete d->qsnOut; 01236 d->qsnIn = d->qsnOut = NULL; 01237 01238 ::close(sockfd); 01239 sockfd = -1; 01240 } 01241 d->status = lookupDone; 01242 } 01243 01244 bool KExtendedSocket::open(int mode) 01245 { 01246 if (mode != IO_Raw | IO_ReadWrite) 01247 return false; // invalid open mode 01248 01249 if (d->flags & passiveSocket) 01250 return listen() == 0; 01251 else if (d->status < connecting) 01252 return connect() == 0; 01253 else 01254 return false; 01255 } 01256 01257 void KExtendedSocket::close() 01258 { 01259 if (sockfd == -1 || d->status >= closing) 01260 return; // nothing to close 01261 01262 // LOCK BUFFER MUTEX 01263 if (d->flags & outputBufferedSocket && writeBufferSize() > 0) 01264 { 01265 // write buffer not empty, go into closing state 01266 d->status = closing; 01267 if (d->qsnIn) 01268 delete d->qsnIn; 01269 d->qsnIn = NULL; 01270 // we keep the outgoing socket notifier because we want 01271 // to send data, but not receive 01272 } 01273 else 01274 { 01275 // nope, write buffer is empty 01276 // we can close now 01277 if (d->qsnIn) 01278 delete d->qsnIn; 01279 if (d->qsnOut) 01280 delete d->qsnOut; 01281 d->qsnIn = d->qsnOut = NULL; 01282 01283 ::close(sockfd); 01284 d->status = done; 01285 emit closed(readBufferSize() != 0 ? availRead : 0); 01286 } 01287 // UNLOCK BUFFER MUTEX 01288 } 01289 01290 01291 void KExtendedSocket::closeNow() 01292 { 01293 if (d->status >= done) 01294 return; // nothing to close 01295 01296 // close the socket 01297 delete d->qsnIn; 01298 delete d->qsnOut; 01299 d->qsnIn = d->qsnOut = NULL; 01300 01301 if (d->status > connecting && sockfd != -1) 01302 { 01303 ::close(sockfd); 01304 sockfd = -1; 01305 } 01306 else if (d->status == connecting) 01307 cancelAsyncConnect(); 01308 else if (d->status == lookupInProgress) 01309 cancelAsyncLookup(); 01310 01311 d->status = done; 01312 01313 emit closed(closedNow | 01314 (readBufferSize() != 0 ? availRead : 0) | 01315 (writeBufferSize() != 0 ? dirtyWrite : 0)); 01316 } 01317 01318 void KExtendedSocket::release() 01319 { 01320 // release our hold on the socket 01321 sockfd = -1; 01322 d->status = done; 01323 01324 d->resRemote.cancel(false); 01325 d->resLocal.cancel(false); 01326 01327 if (d->local != NULL) 01328 delete d->local; 01329 if (d->peer != NULL) 01330 delete d->peer; 01331 01332 d->peer = d->local = NULL; 01333 01334 if (d->qsnIn != NULL) 01335 delete d->qsnIn; 01336 if (d->qsnOut != NULL) 01337 delete d->qsnOut; 01338 01339 d->qsnIn = d->qsnOut = NULL; 01340 01341 // now that the socket notificators are done with, we can flush out the buffers 01342 consumeReadBuffer(readBufferSize(), NULL, true); 01343 consumeWriteBuffer(writeBufferSize()); 01344 01345 // don't delete d 01346 // leave that for the destructor 01347 } 01348 01349 void KExtendedSocket::flush() 01350 { 01351 cleanError(); 01352 if (d->status < connected || d->status >= done || d->flags & passiveSocket) 01353 return; 01354 01355 if (sockfd == -1) 01356 return; 01357 01358 if ((d->flags & outputBufferedSocket) == 0) 01359 return; // nothing to do 01360 01361 // LOCK MUTEX 01362 01363 unsigned written = 0; 01364 unsigned offset = outBufIndex; // this happens only for the first 01365 while (writeBufferSize() - written > 0) 01366 { 01367 // we have to write each output buffer in outBuf 01368 // but since we can have several very small buffers, we can make things 01369 // better by concatenating a few of them into a big buffer 01370 // question is: how big should that buffer be? 16 kB should be enough 01371 01372 QByteArray buf(16384); 01373 QByteArray *a = outBuf.first(); 01374 unsigned count = 0; 01375 01376 while (a && count + (a->size() - offset) <= buf.size()) 01377 { 01378 memcpy(buf.data() + count, a->data() + offset, a->size() - offset); 01379 count += a->size() - offset; 01380 offset = 0; 01381 a = outBuf.next(); 01382 } 01383 01384 // see if we can still fit more 01385 if (a && count < buf.size()) 01386 { 01387 // getting here means this buffer (a) is larger than 01388 // (buf.size() - count) (even for count == 0). 01389 memcpy(buf.data() + count, a->data() + offset, buf.size() - count); 01390 offset += buf.size() - count; 01391 count = buf.size(); 01392 } 01393 01394 // now try to write those bytes 01395 int wrote = KSocks::self()->write(sockfd, buf, count); 01396 01397 if (wrote == -1) 01398 { 01399 // could be EAGAIN (EWOULDBLOCK) 01400 setError(IO_WriteError, errno); 01401 break; 01402 } 01403 written += wrote; 01404 01405 if ((unsigned)wrote != count) 01406 break; 01407 } 01408 if (written) 01409 { 01410 consumeWriteBuffer(written); 01411 emit bytesWritten(written); 01412 } 01413 01414 // UNLOCK MUTEX 01415 } 01416 01417 01418 Q_LONG KExtendedSocket::readBlock(char *data, Q_ULONG maxlen) 01419 { 01420 cleanError(); 01421 if (d->status < connected || d->flags & passiveSocket) 01422 return -2; 01423 01424 int retval; 01425 01426 if ((d->flags & inputBufferedSocket) == 0) 01427 { 01428 // we aren't buffering this socket, so just pass along 01429 // the call to the real read method 01430 01431 if (sockfd == -1) 01432 return -2; 01433 if (data) 01434 retval = KSocks::self()->read(sockfd, data, maxlen); 01435 else 01436 retval = skipData(sockfd, maxlen); 01437 if (retval == -1) 01438 setError(IO_ReadError, errno); 01439 } 01440 else 01441 { 01442 // this socket is being buffered. So read from the buffer 01443 01444 // LOCK BUFFER MUTEX 01445 01446 retval = consumeReadBuffer(maxlen, data); 01447 if (retval == 0) 01448 { 01449 // consumeReadBuffer returns 0 only if the buffer is 01450 // empty 01451 if (sockfd == -1) 01452 return 0; // buffer is clear now, indicate EOF 01453 setError(IO_ReadError, EWOULDBLOCK); 01454 retval = -1; 01455 } 01456 01457 // UNLOCK BUFFER MUTEX 01458 01459 } 01460 return retval; 01461 } 01462 01463 Q_LONG KExtendedSocket::writeBlock(const char *data, Q_ULONG len) 01464 { 01465 cleanError(); 01466 if (d->status < connected || d->status >= closing || d->flags & passiveSocket) 01467 return -2; 01468 if (sockfd == -1) 01469 return -2; 01470 01471 if (len == 0) 01472 return 0; // what's to write? 01473 01474 int retval; 01475 01476 if ((d->flags & outputBufferedSocket) == 0) 01477 { 01478 // socket not buffered. Just call write 01479 retval = KSocks::self()->write(sockfd, data, len); 01480 if (retval == -1) 01481 setError(IO_WriteError, errno); 01482 else 01483 emit bytesWritten(retval); 01484 } 01485 else 01486 { 01487 // socket is buffered. Feed the write buffer 01488 01489 // LOCK BUFFER MUTEX 01490 01491 register unsigned wsize = writeBufferSize(); 01492 if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning 01493 { 01494 // buffer is full! 01495 setError(IO_WriteError, EWOULDBLOCK); 01496 retval = -1; 01497 } 01498 else 01499 { 01500 if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize) 01501 // we cannot write all data. Write just as much as to fill the buffer 01502 len = d->outMaxSize - wsize; 01503 01504 // len > 0 here 01505 retval = feedWriteBuffer(len, data); 01506 if (wsize == 0 || d->emitWrite) 01507 // buffer was empty, which means that the notifier is probably disabled 01508 d->qsnOut->setEnabled(true); 01509 } 01510 01511 // UNLOCK BUFFER MUTEX 01512 } 01513 01514 return retval; 01515 } 01516 01517 int KExtendedSocket::peekBlock(char *data, uint maxlen) 01518 { 01519 if (d->status < connected || d->flags & passiveSocket) 01520 return -2; 01521 if (sockfd == -1) 01522 return -2; 01523 01524 // need to LOCK MUTEX around this call... 01525 01526 if (d->flags & inputBufferedSocket) 01527 return consumeReadBuffer(maxlen, data, false); 01528 01529 return 0; 01530 } 01531 01532 int KExtendedSocket::unreadBlock(const char *, uint) 01533 { 01534 // Always return -1, indicating this is not supported 01535 setError(IO_ReadError, ENOSYS); 01536 return -1; 01537 } 01538 01539 int KExtendedSocket::bytesAvailable() const 01540 { 01541 if (d->status < connected || d->flags & passiveSocket) 01542 return -2; 01543 01544 // as of now, we don't do any extra processing 01545 // we only work in input-buffered sockets 01546 if (d->flags & inputBufferedSocket) 01547 return KBufferedIO::bytesAvailable(); 01548 01549 return 0; // TODO: FIONREAD ioctl 01550 } 01551 01552 int KExtendedSocket::waitForMore(int msecs) 01553 { 01554 cleanError(); 01555 if (d->flags & passiveSocket || d->status < connected || d->status >= closing) 01556 return -2; 01557 if (sockfd == -1) 01558 return -2; 01559 01560 fd_set rd; 01561 FD_ZERO(&rd); 01562 FD_SET(sockfd, &rd); 01563 timeval tv; 01564 tv.tv_sec = msecs / 1000; 01565 tv.tv_usec = (msecs % 1000) * 1000; 01566 01567 int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv); 01568 if (retval == -1) 01569 { 01570 setError(IO_FatalError, errno); 01571 return -1; 01572 } 01573 else if (retval != 0) 01574 socketActivityRead(); // do read processing 01575 01576 return bytesAvailable(); 01577 } 01578 01579 int KExtendedSocket::getch() 01580 { 01581 unsigned char c; 01582 int retval; 01583 retval = readBlock((char*)&c, sizeof(c)); 01584 01585 if (retval < 0) 01586 return retval; 01587 return c; 01588 } 01589 01590 int KExtendedSocket::putch(int ch) 01591 { 01592 unsigned char c = (char)ch; 01593 return writeBlock((char*)&c, sizeof(c)); 01594 } 01595 01596 // sets the emission of the readyRead signal 01597 void KExtendedSocket::enableRead(bool enable) 01598 { 01599 // check if we can disable the socket notifier 01600 // saves us a few cycles 01601 // this is so because in buffering mode, we rely on these signals 01602 // being emitted to do our I/O. We couldn't disable them here 01603 if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn) 01604 d->qsnIn->setEnabled(false); 01605 else if (enable && d->qsnIn) 01606 // we can enable it always 01607 d->qsnIn->setEnabled(true); 01608 d->emitRead = enable; 01609 } 01610 01611 // sets the emission of the readyWrite signal 01612 void KExtendedSocket::enableWrite(bool enable) 01613 { 01614 // same thing as above 01615 if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut) 01616 d->qsnOut->setEnabled(false); 01617 else if (enable && d->qsnOut) 01618 // we can enable it always 01619 d->qsnOut->setEnabled(true); 01620 d->emitWrite = enable; 01621 } 01622 01623 // protected slot 01624 // this is connected to d->qsnIn::activated(int) 01625 void KExtendedSocket::socketActivityRead() 01626 { 01627 if (d->flags & passiveSocket) 01628 { 01629 emit readyAccept(); 01630 return; 01631 } 01632 if (d->status == connecting) 01633 { 01634 connectionEvent(); 01635 return; 01636 } 01637 if (d->status != connected) 01638 return; 01639 01640 // do we need to do I/O here? 01641 if (d->flags & inputBufferedSocket) 01642 { 01643 // aye. Do read from the socket and feed our buffer 01644 QByteArray a; 01645 char buf[1024]; 01646 int len, totalread = 0; 01647 01648 // LOCK MUTEX 01649 01650 unsigned cursize = readBufferSize(); 01651 01652 if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize) 01653 { 01654 do 01655 { 01656 // check that we can read that many bytes 01657 if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf)) 01658 // no, that would overrun the buffer 01659 // note that this will also make us exit the loop 01660 len = d->inMaxSize - (cursize + totalread); 01661 else 01662 len = sizeof(buf); 01663 01664 len = KSocks::self()->read(sockfd, buf, len); 01665 if (len > 0) 01666 { 01667 // normal read operation 01668 a.resize(a.size() + len); 01669 memcpy(a.data() + totalread, buf, len); 01670 totalread += len; // totalread == a.size() now 01671 } 01672 else if (len == 0) 01673 { 01674 // EOF condition here 01675 ::close(sockfd); 01676 sockfd = -1; // we're closed 01677 d->qsnIn->deleteLater(); 01678 delete d->qsnOut; 01679 d->qsnIn = d->qsnOut = NULL; 01680 d->status = done; 01681 emit closed(involuntary | 01682 (readBufferSize() ? availRead : 0) | 01683 (writeBufferSize() ? dirtyWrite : 0)); 01684 return; 01685 } 01686 else 01687 { 01688 // error! 01689 setError(IO_ReadError, errno); 01690 return; 01691 } 01692 // will loop only for normal read operations 01693 } 01694 while (len == sizeof(buf)); 01695 01696 feedReadBuffer(a.size(), a.data()); 01697 } 01698 01699 // UNLOCK MUTEX 01700 } 01701 else 01702 { 01703 // No input buffering, but the notifier fired 01704 // That means that either there is data to be read or that the 01705 // socket closed. 01706 01707 // try to read one byte. If we can't, then the socket got closed 01708 01709 char c; 01710 int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK); 01711 if (len == 0) 01712 { 01713 // yes, it's an EOF condition 01714 d->qsnIn->setEnabled(false); 01715 ::close(sockfd); 01716 sockfd = -1; 01717 d->status = done; 01718 emit closed(involuntary); 01719 return; 01720 } 01721 } 01722 01723 if (d->emitRead) 01724 emit readyRead(); 01725 } 01726 01727 void KExtendedSocket::socketActivityWrite() 01728 { 01729 if (d->flags & passiveSocket) 01730 return; 01731 if (d->status == connecting) 01732 { 01733 connectionEvent(); 01734 return; 01735 } 01736 if (d->status != connected && d->status != closing) 01737 return; 01738 01739 flush(); 01740 01741 bool empty = writeBufferSize() == 0; 01742 01743 if (d->emitWrite && empty) 01744 emit readyWrite(); 01745 else if (!d->emitWrite) 01746 { 01747 // check if we can disable the notifier 01748 d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send 01749 } 01750 if (d->status == closing && empty) 01751 { 01752 // done sending the missing data! 01753 d->status = done; 01754 01755 delete d->qsnOut; 01756 ::close(sockfd); 01757 01758 d->qsnOut = NULL; 01759 sockfd = -1; 01760 emit closed(delayed | (readBufferSize() ? availRead : 0)); 01761 } 01762 } 01763 01764 // this function is called whenever we have a "connection event" 01765 // that is, whenever our asynchronously connecting socket throws 01766 // an event 01767 void KExtendedSocket::connectionEvent() 01768 { 01769 if (d->status != connecting) 01770 return; // move along. There's nothing to see here 01771 01772 KResolverResults remote = d->resRemote.results(); 01773 if (remote.count() == 0) 01774 { 01775 // We have a problem! Abort? 01776 kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n"; 01777 return; 01778 } 01779 01780 int errcode = 0; 01781 01782 if (sockfd != -1) 01783 { 01784 // our socket has activity 01785 // find out what it was 01786 int retval; 01787 socklen_t len = sizeof(errcode); 01788 retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len); 01789 01790 if (retval == -1 || errcode != 0) 01791 { 01792 // socket activity and there was error? 01793 // that means the socket probably did not connect 01794 if (d->qsnIn) 01795 delete d->qsnIn; 01796 if (d->qsnOut) 01797 delete d->qsnOut; 01798 ::close(sockfd); 01799 01800 sockfd = -1; 01801 d->qsnIn = d->qsnOut = NULL; 01802 d->current++; 01803 setError(IO_ConnectError, errcode); 01804 } 01805 else 01806 { 01807 // hmm, socket activity and there was no error? 01808 // that means it connected 01809 // YAY! 01810 cleanError(); 01811 d->status = connected; 01812 setBlockingMode(true); 01813 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01814 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01815 d->flags & outputBufferedSocket ? -1 : 0); 01816 emit connectionSuccess(); 01817 return; 01818 } 01819 } 01820 01821 // ok, we have to try something here 01822 // and sockfd == -1 01823 KResolverResults local = d->resLocal.results(); 01824 unsigned localidx = 0; 01825 for ( ; d->current < remote.count(); d->current++) 01826 { 01827 // same code as in connect() 01828 if (local.count() != 0) 01829 { 01830 // scan bindres for a local resuls family 01831 for (localidx = 0; localidx < local.count(); localidx++) 01832 if (remote[d->current].family() == local[localidx].family()) 01833 break; 01834 01835 if (remote[d->current].family() != local[localidx].family()) 01836 { 01837 // no matching families for this 01838 continue; 01839 } 01840 01841 errno = 0; 01842 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(), 01843 remote[d->current].protocol()); 01844 setError(IO_ConnectError, errno); 01845 errcode = errno; 01846 if (sockfd == -1) 01847 continue; // cannot create this socket 01848 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01849 if (d->addressReusable) 01850 setAddressReusable(sockfd, true); 01851 setIPv6Only(d->ipv6only); 01852 cleanError(); 01853 if (KSocks::self()->bind(sockfd, local[localidx].address(), 01854 local[localidx].length()) == -1) 01855 { 01856 ::close(sockfd); 01857 sockfd = -1; 01858 continue; 01859 } 01860 } 01861 else 01862 { 01863 // no need to bind, just create 01864 sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(), 01865 remote[d->current].protocol()); 01866 if (sockfd == -1) 01867 { 01868 setError(IO_ConnectError, errno); 01869 errcode = errno; 01870 continue; 01871 } 01872 fcntl(sockfd, F_SETFD, FD_CLOEXEC); 01873 if (d->addressReusable) 01874 setAddressReusable(sockfd, true); 01875 setIPv6Only(d->ipv6only); 01876 cleanError(); 01877 } 01878 01879 if (KSocks::self()->hasWorkingAsyncConnect()) 01880 setBlockingMode(false); 01881 if (KSocks::self()->connect(sockfd, remote[d->current].address(), 01882 remote[d->current].length()) == -1) 01883 { 01884 if (errno != EWOULDBLOCK && errno != EINPROGRESS) 01885 { 01886 setError(IO_ConnectError, errno); 01887 ::close(sockfd); 01888 sockfd = -1; 01889 errcode = errno; 01890 continue; 01891 } 01892 01893 // error here is either EWOULDBLOCK or EINPROGRESS 01894 // so, it is a good condition 01895 d->qsnIn = new QSocketNotifier(sockfd, QSocketNotifier::Read); 01896 QObject::connect(d->qsnIn, SIGNAL(activated(int)), this, SLOT(socketActivityRead())); 01897 d->qsnOut = new QSocketNotifier(sockfd, QSocketNotifier::Write); 01898 QObject::connect(d->qsnOut, SIGNAL(activated(int)), this, SLOT(socketActivityWrite())); 01899 01900 // ok, let the Qt event loop do the selecting for us 01901 return; 01902 } 01903 01904 // eh, what? 01905 // the non-blocking socket returned valid connection? 01906 // already? 01907 // I suppose that could happen... 01908 cleanError(); 01909 d->status = connected; 01910 setBlockingMode(true); 01911 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); 01912 setBufferSize(d->flags & inputBufferedSocket ? -1 : 0, 01913 d->flags & outputBufferedSocket ? -1 : 0); 01914 emit connectionSuccess(); 01915 return; 01916 } 01917 01918 // if we got here, it means that there are no more options to connect 01919 d->status = lookupDone; // go back 01920 emit connectionFailed(errcode); 01921 } 01922 01923 void KExtendedSocket::dnsResultsReady() 01924 { 01925 // check that this function was called in a valid state 01926 if (d->status != lookupInProgress) 01927 return; 01928 01929 // valid state. Are results fully ready? 01930 if (d->resRemote.isRunning() || d->resLocal.isRunning()) 01931 // no, still waiting for answer in one of the lookups 01932 return; 01933 01934 // ok, we have all results 01935 // count how many results we have 01936 int n = d->resRemote.results().count() + d->resLocal.results().count(); 01937 01938 if (n) 01939 { 01940 d->status = lookupDone; 01941 cleanError(); 01942 } 01943 else 01944 { 01945 d->status = nothing; 01946 setError(IO_LookupError, KResolver::NoName); 01947 } 01948 01949 emit lookupFinished(n); 01950 01951 return; 01952 } 01953 01954 void KExtendedSocket::startAsyncConnectSlot() 01955 { 01956 QObject::disconnect(this, SIGNAL(lookupFinished(int)), this, SLOT(startAsyncConnectSlot())); 01957 01958 if (d->status == lookupDone) 01959 startAsyncConnect(); 01960 } 01961 01962 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, QString &host, 01963 QString &port, int flags) 01964 { 01965 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl; 01966 01967 int err; 01968 char h[NI_MAXHOST], s[NI_MAXSERV]; 01969 01970 h[0] = s[0] = '\0'; 01971 01972 err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags); 01973 host = QString::fromUtf8(h); 01974 port = QString::fromUtf8(s); 01975 01976 return err; 01977 } 01978 01979 int KExtendedSocket::resolve(::KSocketAddress *sock, QString &host, QString &port, 01980 int flags) 01981 { 01982 return resolve(sock->data, sock->datasize, host, port, flags); 01983 } 01984 01985 QPtrList<KAddressInfo> KExtendedSocket::lookup(const QString& host, const QString& port, 01986 int userflags, int *error) 01987 { 01988 kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl; 01989 01990 int socktype, familyMask, flags; 01991 unsigned i; 01992 QPtrList<KAddressInfo> l; 01993 01994 /* check socket type flags */ 01995 if (!process_flags(userflags, socktype, familyMask, flags)) 01996 return l; 01997 01998 // kdDebug(170) << "Performing lookup on " << host << "|" << port << endl; 01999 KResolverResults res = KResolver::resolve(host, port, flags, familyMask); 02000 if (res.error()) 02001 { 02002 if (error) 02003 *error = res.error(); 02004 return l; 02005 } 02006 02007 for (i = 0; i < res.count(); i++) 02008 { 02009 KAddressInfo *ai = new KAddressInfo(); 02010 02011 // I should have known that using addrinfo was going to come 02012 // and bite me back some day... 02013 ai->ai = (addrinfo *) malloc(sizeof(addrinfo)); 02014 memset(ai->ai, 0, sizeof(addrinfo)); 02015 02016 ai->ai->ai_family = res[i].family(); 02017 ai->ai->ai_socktype = res[i].socketType(); 02018 ai->ai->ai_protocol = res[i].protocol(); 02019 QString canon = res[i].canonicalName(); 02020 if (!canon.isEmpty()) 02021 { 02022 ai->ai->ai_canonname = (char *) malloc(canon.length()+1); 02023 strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional 02024 } 02025 if ((ai->ai->ai_addrlen = res[i].length())) 02026 { 02027 ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length()); 02028 memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length()); 02029 } 02030 else 02031 { 02032 ai->ai->ai_addr = 0; 02033 } 02034 02035 ai->addr = ::KSocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen); 02036 02037 l.append(ai); 02038 } 02039 02040 if ( error ) 02041 *error = 0; // all is fine! 02042 02043 return l; 02044 } 02045 02046 ::KSocketAddress *KExtendedSocket::localAddress(int fd) 02047 { 02048 ::KSocketAddress *local; 02049 struct sockaddr static_sa, *sa = &static_sa; 02050 ksocklen_t len = sizeof(static_sa); 02051 02052 /* find out the socket length, in advance 02053 * we use a sockaddr allocated on the heap just not to pass down 02054 * a NULL pointer to the first call. Some systems are reported to 02055 * set len to 0 if we pass NULL as the sockaddr */ 02056 if (KSocks::self()->getsockname(fd, sa, &len) == -1) 02057 return NULL; // error! 02058 02059 /* was it enough? */ 02060 if (len > sizeof(static_sa) 02061 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02062 || sa->sa_len > sizeof(static_sa) 02063 #endif 02064 ) 02065 { 02066 /* nope, malloc a new socket with the proper size */ 02067 02068 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02069 if (sa->sa_len != len) 02070 len = sa->sa_len; 02071 #endif 02072 02073 sa = (sockaddr*)malloc(len); 02074 if (sa == NULL) 02075 return NULL; // out of memory 02076 02077 if (KSocks::self()->getsockname(fd, sa, &len) == -1) 02078 { 02079 free(sa); 02080 return NULL; 02081 } 02082 02083 local = ::KSocketAddress::newAddress(sa, len); 02084 free(sa); 02085 } 02086 else 02087 local = ::KSocketAddress::newAddress(sa, len); 02088 02089 return local; 02090 } 02091 02092 /* This is exactly the same code as localAddress, except 02093 * we call getpeername here */ 02094 ::KSocketAddress *KExtendedSocket::peerAddress(int fd) 02095 { 02096 ::KSocketAddress *peer; 02097 struct sockaddr static_sa, *sa = &static_sa; 02098 ksocklen_t len = sizeof(static_sa); 02099 02100 /* find out the socket length, in advance 02101 * we use a sockaddr allocated on the heap just not to pass down 02102 * a NULL pointer to the first call. Some systems are reported to 02103 * set len to 0 if we pass NULL as the sockaddr */ 02104 if (KSocks::self()->getpeername(fd, sa, &len) == -1) 02105 return NULL; // error! 02106 02107 /* was it enough? */ 02108 if (len > sizeof(static_sa) 02109 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02110 || sa->sa_len > sizeof(static_sa) 02111 #endif 02112 ) 02113 { 02114 /* nope, malloc a new socket with the proper size */ 02115 02116 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 02117 if (sa->sa_len != len) 02118 len = sa->sa_len; 02119 #endif 02120 02121 sa = (sockaddr*)malloc(len); 02122 if (sa == NULL) 02123 return NULL; // out of memory 02124 02125 if (KSocks::self()->getpeername(fd, sa, &len) == -1) 02126 { 02127 free(sa); 02128 return NULL; 02129 } 02130 02131 peer = ::KSocketAddress::newAddress(sa, len); 02132 free(sa); 02133 } 02134 else 02135 peer = ::KSocketAddress::newAddress(sa, len); 02136 02137 return peer; 02138 } 02139 02140 QString KExtendedSocket::strError(int code, int syserr) 02141 { 02142 const char * msg; 02143 if (code == IO_LookupError) 02144 msg = gai_strerror(syserr); 02145 else 02146 msg = strerror(syserr); 02147 02148 return QString::fromLocal8Bit(msg); 02149 } 02150 02151 02152 QSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; } 02153 QSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; } 02154 02155 /* 02156 * class KAddressInfo 02157 */ 02158 02159 #if 0 02160 KAddressInfo::KAddressInfo(addrinfo *p) 02161 { 02162 ai = (addrinfo *) malloc(sizeof(addrinfo)); 02163 memcpy(ai, p, sizeof(addrinfo)); 02164 ai->ai_next = NULL; 02165 if (p->ai_canonname) 02166 { 02167 ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1); 02168 strcpy(ai->ai_canonname, p->ai_canonname); 02169 } 02170 if (p->ai_addr && p->ai_addrlen) 02171 { 02172 ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen); 02173 memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen); 02174 } 02175 else 02176 { 02177 ai->ai_addr = 0; 02178 ai->ai_addrlen = 0; 02179 } 02180 02181 addr = ::KSocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen); 02182 } 02183 #endif 02184 KAddressInfo::~KAddressInfo() 02185 { 02186 if (ai && ai->ai_canonname) 02187 free(ai->ai_canonname); 02188 02189 if (ai && ai->ai_addr) 02190 free(ai->ai_addr); 02191 02192 if (ai) 02193 free(ai); 02194 delete addr; 02195 } 02196 02197 int KAddressInfo::flags() const 02198 { 02199 return ai->ai_flags; 02200 } 02201 02202 int KAddressInfo::family() const 02203 { 02204 return ai->ai_family; 02205 } 02206 02207 int KAddressInfo::socktype() const 02208 { 02209 return ai->ai_socktype; 02210 } 02211 02212 int KAddressInfo::protocol() const 02213 { 02214 return ai->ai_protocol; 02215 } 02216 02217 const char* KAddressInfo::canonname() const 02218 { 02219 return ai->ai_canonname; 02220 } 02221 02222 void KExtendedSocket::virtual_hook( int id, void* data ) 02223 { KBufferedIO::virtual_hook( id, data ); } 02224 02225 #include "kextsock.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 22:47:34 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003