kdecore Library API Documentation

ksockssocketdevice.cpp

00001 /* -*- C++ -*- 00002 * Copyright (C) 2004 Thiago Macieira <thiago.macieira@kdemail.net> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public License 00015 * along with this library; see the file COPYING.LIB. If not, write to 00016 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include <config.h> 00021 00022 #include <errno.h> 00023 #include <sys/types.h> 00024 #include <sys/socket.h> 00025 00026 #if defined(HAVE_UNISTD_H) 00027 #include <unistd.h> 00028 #endif 00029 00030 #include "kapplication.h" 00031 00032 #include "ksocks.h" 00033 #include "ksocketaddress.h" 00034 #include "kresolver.h" 00035 #include "ksockssocketdevice.h" 00036 00037 using namespace KNetwork; 00038 00039 // constructor 00040 // nothing to do 00041 KSocksSocketDevice::KSocksSocketDevice(const KSocketBase* obj) 00042 : KSocketDevice(obj) 00043 { 00044 } 00045 00046 // constructor with argument 00047 // nothing to do 00048 KSocksSocketDevice::KSocksSocketDevice(int fd) 00049 : KSocketDevice(fd) 00050 { 00051 } 00052 00053 // destructor 00054 // also nothing to do 00055 KSocksSocketDevice::~KSocksSocketDevice() 00056 { 00057 } 00058 00059 // returns the capabilities 00060 int KSocksSocketDevice::capabilities() const 00061 { 00062 return 0; // can do everything! 00063 } 00064 00065 // From here on, the code is almost exactly a copy of KSocketDevice 00066 // the differences are the use of KSocks where appropriate 00067 00068 bool KSocksSocketDevice::bind(const KResolverEntry& address) 00069 { 00070 resetError(); 00071 00072 if (m_sockfd == -1 && !create(address)) 00073 return false; // failed creating 00074 00075 // we have a socket, so try and bind 00076 if (KSocks::self()->bind(m_sockfd, address.address(), address.length()) == -1) 00077 { 00078 if (errno == EADDRINUSE) 00079 setError(IO_BindError, AddressInUse); 00080 else if (errno == EINVAL) 00081 setError(IO_BindError, AlreadyBound); 00082 else 00083 // assume the address is the cause 00084 setError(IO_BindError, NotSupported); 00085 return false; 00086 } 00087 00088 return true; 00089 } 00090 00091 00092 bool KSocksSocketDevice::listen(int backlog) 00093 { 00094 if (m_sockfd != -1) 00095 { 00096 if (KSocks::self()->listen(m_sockfd, backlog) == -1) 00097 { 00098 setError(IO_ListenError, NotSupported); 00099 return false; 00100 } 00101 00102 resetError(); 00103 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00104 setState(IO_Open); 00105 return true; 00106 } 00107 00108 // we don't have a socket 00109 // can't listen 00110 setError(IO_ListenError, NotCreated); 00111 return false; 00112 } 00113 00114 bool KSocksSocketDevice::connect(const KResolverEntry& address) 00115 { 00116 resetError(); 00117 00118 if (m_sockfd == -1 && !create(address)) 00119 return false; // failed creating! 00120 00121 int retval; 00122 if (KSocks::self()->hasWorkingAsyncConnect()) 00123 retval = KSocks::self()->connect(m_sockfd, address.address(), 00124 address.length()); 00125 else 00126 { 00127 // work around some SOCKS implementation bugs 00128 // we will do a *synchronous* connection here! 00129 // FIXME: KDE4, write a proper SOCKS implementation 00130 bool isBlocking = blocking(); 00131 setBlocking(true); 00132 retval = KSocks::self()->connect(m_sockfd, address.address(), 00133 address.length()); 00134 setBlocking(isBlocking); 00135 } 00136 00137 if (retval == -1) 00138 { 00139 if (errno == EISCONN) 00140 return true; // we're already connected 00141 else if (errno == EALREADY || errno == EINPROGRESS) 00142 { 00143 setError(IO_ConnectError, InProgress); 00144 return true; 00145 } 00146 else if (errno == ECONNREFUSED) 00147 setError(IO_ConnectError, ConnectionRefused); 00148 else if (errno == ENETDOWN || errno == ENETUNREACH || 00149 errno == ENETRESET || errno == ECONNABORTED || 00150 errno == ECONNRESET || errno == EHOSTDOWN || 00151 errno == EHOSTUNREACH) 00152 setError(IO_ConnectError, NetFailure); 00153 else 00154 setError(IO_ConnectError, NotSupported); 00155 00156 return false; 00157 } 00158 00159 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00160 setState(IO_Open); 00161 return true; // all is well 00162 } 00163 00164 KSocksSocketDevice* KSocksSocketDevice::accept() 00165 { 00166 if (m_sockfd == -1) 00167 { 00168 // can't accept without a socket 00169 setError(IO_AcceptError, NotCreated); 00170 return 0L; 00171 } 00172 00173 struct sockaddr sa; 00174 kde_socklen_t len = sizeof(sa); 00175 int newfd = KSocks::self()->accept(m_sockfd, &sa, &len); 00176 if (newfd == -1) 00177 { 00178 if (errno == EAGAIN || errno == EWOULDBLOCK) 00179 setError(IO_AcceptError, WouldBlock); 00180 else 00181 setError(IO_AcceptError, UnknownError); 00182 return NULL; 00183 } 00184 00185 return new KSocksSocketDevice(newfd); 00186 } 00187 00188 static int socks_read_common(int sockfd, char *data, Q_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false) 00189 { 00190 kde_socklen_t len; 00191 if (from) 00192 { 00193 from->setLength(len = 128); // arbitrary length 00194 retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); 00195 } 00196 else 00197 retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL); 00198 00199 if (retval == -1) 00200 { 00201 if (errno == EAGAIN || errno == EWOULDBLOCK) 00202 return KSocketDevice::WouldBlock; 00203 else 00204 return KSocketDevice::UnknownError; 00205 } 00206 00207 if (from) 00208 from->setLength(len); 00209 return 0; 00210 } 00211 00212 Q_LONG KSocksSocketDevice::readBlock(char *data, Q_ULONG maxlen) 00213 { 00214 resetError(); 00215 if (m_sockfd == -1) 00216 return -1; 00217 00218 if (maxlen == 0 || data == 0L) 00219 return 0; // can't read 00220 00221 ssize_t retval; 00222 int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval); 00223 00224 if (err) 00225 { 00226 setError(IO_ReadError, static_cast<SocketError>(err)); 00227 return -1; 00228 } 00229 00230 return retval; 00231 } 00232 00233 Q_LONG KSocksSocketDevice::readBlock(char *data, Q_ULONG maxlen, KSocketAddress &from) 00234 { 00235 resetError(); 00236 if (m_sockfd == -1) 00237 return -1; // nothing to do here 00238 00239 if (data == 0L || maxlen == 0) 00240 return 0; // user doesn't want to read 00241 00242 ssize_t retval; 00243 int err = socks_read_common(m_sockfd, data, maxlen, &from, retval); 00244 00245 if (err) 00246 { 00247 setError(IO_ReadError, static_cast<SocketError>(err)); 00248 return -1; 00249 } 00250 00251 return retval; 00252 } 00253 00254 Q_LONG KSocksSocketDevice::peekBlock(char *data, Q_ULONG maxlen) 00255 { 00256 resetError(); 00257 if (m_sockfd == -1) 00258 return -1; 00259 00260 if (maxlen == 0 || data == 0L) 00261 return 0; // can't read 00262 00263 ssize_t retval; 00264 int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true); 00265 00266 if (err) 00267 { 00268 setError(IO_ReadError, static_cast<SocketError>(err)); 00269 return -1; 00270 } 00271 00272 return retval; 00273 } 00274 00275 Q_LONG KSocksSocketDevice::peekBlock(char *data, Q_ULONG maxlen, KSocketAddress& from) 00276 { 00277 resetError(); 00278 if (m_sockfd == -1) 00279 return -1; // nothing to do here 00280 00281 if (data == 0L || maxlen == 0) 00282 return 0; // user doesn't want to read 00283 00284 ssize_t retval; 00285 int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true); 00286 00287 if (err) 00288 { 00289 setError(IO_ReadError, static_cast<SocketError>(err)); 00290 return -1; 00291 } 00292 00293 return retval; 00294 } 00295 00296 Q_LONG KSocksSocketDevice::writeBlock(const char *data, Q_ULONG len) 00297 { 00298 return writeBlock(data, len, KSocketAddress()); 00299 } 00300 00301 Q_LONG KSocksSocketDevice::writeBlock(const char *data, Q_ULONG len, const KSocketAddress& to) 00302 { 00303 resetError(); 00304 if (m_sockfd == -1) 00305 return -1; // can't write to unopen socket 00306 00307 if (data == 0L || len == 0) 00308 return 0; // nothing to be written 00309 00310 ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length()); 00311 if (retval == -1) 00312 { 00313 if (errno == EAGAIN || errno == EWOULDBLOCK) 00314 setError(IO_WriteError, WouldBlock); 00315 else 00316 setError(IO_WriteError, UnknownError); 00317 return -1; // nothing written 00318 } 00319 00320 return retval; 00321 } 00322 00323 KSocketAddress KSocksSocketDevice::localAddress() const 00324 { 00325 if (m_sockfd == -1) 00326 return KSocketAddress(); // not open, empty value 00327 00328 kde_socklen_t len; 00329 KSocketAddress localAddress; 00330 localAddress.setLength(len = 32); // arbitrary value 00331 if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) 00332 // error! 00333 return KSocketAddress(); 00334 00335 if (len <= localAddress.length()) 00336 { 00337 // it has fit already 00338 localAddress.setLength(len); 00339 return localAddress; 00340 } 00341 00342 // no, the socket address is actually larger than we had anticipated 00343 // call again 00344 localAddress.setLength(len); 00345 if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) 00346 // error! 00347 return KSocketAddress(); 00348 00349 return localAddress; 00350 } 00351 00352 KSocketAddress KSocksSocketDevice::peerAddress() const 00353 { 00354 if (m_sockfd == -1) 00355 return KSocketAddress(); // not open, empty value 00356 00357 kde_socklen_t len; 00358 KSocketAddress peerAddress; 00359 peerAddress.setLength(len = 32); // arbitrary value 00360 if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00361 // error! 00362 return KSocketAddress(); 00363 00364 if (len <= peerAddress.length()) 00365 { 00366 // it has fit already 00367 peerAddress.setLength(len); 00368 return peerAddress; 00369 } 00370 00371 // no, the socket address is actually larger than we had anticipated 00372 // call again 00373 peerAddress.setLength(len); 00374 if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00375 // error! 00376 return KSocketAddress(); 00377 00378 return peerAddress; 00379 } 00380 00381 KSocketAddress KSocksSocketDevice::externalAddress() const 00382 { 00383 // return empty, indicating unknown external address 00384 return KSocketAddress(); 00385 } 00386 00387 bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception, 00388 int timeout, bool *timedout) 00389 { 00390 if (m_sockfd == -1) 00391 { 00392 setError(IO_UnspecifiedError, NotCreated); 00393 return false; 00394 } 00395 00396 resetError(); 00397 fd_set readfds, writefds, exceptfds; 00398 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; 00399 00400 if (input) 00401 { 00402 preadfds = &readfds; 00403 FD_ZERO(preadfds); 00404 FD_SET(m_sockfd, preadfds); 00405 *input = false; 00406 } 00407 if (output) 00408 { 00409 pwritefds = &writefds; 00410 FD_ZERO(pwritefds); 00411 FD_SET(m_sockfd, pwritefds); 00412 *output = false; 00413 } 00414 if (exception) 00415 { 00416 pexceptfds = &exceptfds; 00417 FD_ZERO(pexceptfds); 00418 FD_SET(m_sockfd, pexceptfds); 00419 *exception = false; 00420 } 00421 00422 int retval; 00423 if (timeout < 0) 00424 retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); 00425 else 00426 { 00427 // convert the milliseconds to timeval 00428 struct timeval tv; 00429 tv.tv_sec = timeout / 1000; 00430 tv.tv_usec = timeout % 1000 * 1000; 00431 00432 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); 00433 } 00434 00435 if (retval == -1) 00436 { 00437 setError(IO_UnspecifiedError, UnknownError); 00438 return false; 00439 } 00440 if (retval == 0) 00441 { 00442 // timeout 00443 if (timedout) 00444 *timedout = true; 00445 return true; 00446 } 00447 00448 if (input && FD_ISSET(m_sockfd, preadfds)) 00449 *input = true; 00450 if (output && FD_ISSET(m_sockfd, pwritefds)) 00451 *output = true; 00452 if (exception && FD_ISSET(m_sockfd, pexceptfds)) 00453 *exception = true; 00454 00455 return true; 00456 } 00457 00458 void KSocksSocketDevice::initSocks() 00459 { 00460 static bool init = false; 00461 00462 if (init) 00463 return; 00464 00465 if (kapp == 0L) 00466 return; // no KApplication, so don't initialise 00467 // this should, however, test for KInstance 00468 00469 init = true; 00470 00471 if (KSocks::self()->hasSocks()) 00472 delete KSocketDevice::setDefaultImpl(new KSocketDeviceFactory<KSocksSocketDevice>); 00473 } 00474 00475 #if 0 00476 static bool register() 00477 { 00478 KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0); 00479 } 00480 00481 static bool register = registered(); 00482 #endif
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:40 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003