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 if (KSocks::self()->connect(m_sockfd, address.address(), address.length()) == -1) 00122 { 00123 if (errno == EISCONN) 00124 return true; // we're already connected 00125 else if (errno == EALREADY || errno == EINPROGRESS) 00126 { 00127 setError(IO_ConnectError, InProgress); 00128 return true; 00129 } 00130 else if (errno == ECONNREFUSED) 00131 setError(IO_ConnectError, ConnectionRefused); 00132 else if (errno == ENETDOWN || errno == ENETUNREACH || 00133 errno == ENETRESET || errno == ECONNABORTED || 00134 errno == ECONNRESET || errno == EHOSTDOWN || 00135 errno == EHOSTUNREACH) 00136 setError(IO_ConnectError, NetFailure); 00137 else 00138 setError(IO_ConnectError, NotSupported); 00139 00140 return false; 00141 } 00142 00143 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00144 setState(IO_Open); 00145 return true; // all is well 00146 } 00147 00148 KSocksSocketDevice* KSocksSocketDevice::accept() 00149 { 00150 if (m_sockfd == -1) 00151 { 00152 // can't accept without a socket 00153 setError(IO_AcceptError, NotCreated); 00154 return 0L; 00155 } 00156 00157 struct sockaddr sa; 00158 kde_socklen_t len = sizeof(sa); 00159 int newfd = KSocks::self()->accept(m_sockfd, &sa, &len); 00160 if (newfd == -1) 00161 { 00162 if (errno == EAGAIN || errno == EWOULDBLOCK) 00163 setError(IO_AcceptError, WouldBlock); 00164 else 00165 setError(IO_AcceptError, UnknownError); 00166 return NULL; 00167 } 00168 00169 return new KSocksSocketDevice(newfd); 00170 } 00171 00172 static int socks_read_common(int sockfd, char *data, Q_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false) 00173 { 00174 kde_socklen_t len; 00175 if (from) 00176 { 00177 from->setLength(len = 128); // arbitrary length 00178 retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); 00179 } 00180 else 00181 retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL); 00182 00183 if (retval == -1) 00184 { 00185 if (errno == EAGAIN || errno == EWOULDBLOCK) 00186 return KSocketDevice::WouldBlock; 00187 else 00188 return KSocketDevice::UnknownError; 00189 } 00190 00191 if (from) 00192 from->setLength(len); 00193 return 0; 00194 } 00195 00196 Q_LONG KSocksSocketDevice::readBlock(char *data, Q_ULONG maxlen) 00197 { 00198 resetError(); 00199 if (m_sockfd == -1) 00200 return -1; 00201 00202 if (maxlen == 0 || data == 0L) 00203 return 0; // can't read 00204 00205 ssize_t retval; 00206 int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval); 00207 00208 if (err) 00209 { 00210 setError(IO_ReadError, static_cast<SocketError>(err)); 00211 return -1; 00212 } 00213 00214 return retval; 00215 } 00216 00217 Q_LONG KSocksSocketDevice::readBlock(char *data, Q_ULONG maxlen, KSocketAddress &from) 00218 { 00219 resetError(); 00220 if (m_sockfd == -1) 00221 return -1; // nothing to do here 00222 00223 if (data == 0L || maxlen == 0) 00224 return 0; // user doesn't want to read 00225 00226 ssize_t retval; 00227 int err = socks_read_common(m_sockfd, data, maxlen, &from, retval); 00228 00229 if (err) 00230 { 00231 setError(IO_ReadError, static_cast<SocketError>(err)); 00232 return -1; 00233 } 00234 00235 return retval; 00236 } 00237 00238 Q_LONG KSocksSocketDevice::peekBlock(char *data, Q_ULONG maxlen) 00239 { 00240 resetError(); 00241 if (m_sockfd == -1) 00242 return -1; 00243 00244 if (maxlen == 0 || data == 0L) 00245 return 0; // can't read 00246 00247 ssize_t retval; 00248 int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true); 00249 00250 if (err) 00251 { 00252 setError(IO_ReadError, static_cast<SocketError>(err)); 00253 return -1; 00254 } 00255 00256 return retval; 00257 } 00258 00259 Q_LONG KSocksSocketDevice::peekBlock(char *data, Q_ULONG maxlen, KSocketAddress& from) 00260 { 00261 resetError(); 00262 if (m_sockfd == -1) 00263 return -1; // nothing to do here 00264 00265 if (data == 0L || maxlen == 0) 00266 return 0; // user doesn't want to read 00267 00268 ssize_t retval; 00269 int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true); 00270 00271 if (err) 00272 { 00273 setError(IO_ReadError, static_cast<SocketError>(err)); 00274 return -1; 00275 } 00276 00277 return retval; 00278 } 00279 00280 Q_LONG KSocksSocketDevice::writeBlock(const char *data, Q_ULONG len) 00281 { 00282 return writeBlock(data, len, KSocketAddress()); 00283 } 00284 00285 Q_LONG KSocksSocketDevice::writeBlock(const char *data, Q_ULONG len, const KSocketAddress& to) 00286 { 00287 resetError(); 00288 if (m_sockfd == -1) 00289 return -1; // can't write to unopen socket 00290 00291 if (data == 0L || len == 0) 00292 return 0; // nothing to be written 00293 00294 ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length()); 00295 if (retval == -1) 00296 { 00297 if (errno == EAGAIN || errno == EWOULDBLOCK) 00298 setError(IO_WriteError, WouldBlock); 00299 else 00300 setError(IO_WriteError, UnknownError); 00301 return -1; // nothing written 00302 } 00303 00304 return retval; 00305 } 00306 00307 KSocketAddress KSocksSocketDevice::localAddress() const 00308 { 00309 if (m_sockfd == -1) 00310 return KSocketAddress(); // not open, empty value 00311 00312 kde_socklen_t len; 00313 KSocketAddress localAddress; 00314 localAddress.setLength(len = 32); // arbitrary value 00315 if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) 00316 // error! 00317 return KSocketAddress(); 00318 00319 if (len <= localAddress.length()) 00320 { 00321 // it has fit already 00322 localAddress.setLength(len); 00323 return localAddress; 00324 } 00325 00326 // no, the socket address is actually larger than we had anticipated 00327 // call again 00328 localAddress.setLength(len); 00329 if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) 00330 // error! 00331 return KSocketAddress(); 00332 00333 return localAddress; 00334 } 00335 00336 KSocketAddress KSocksSocketDevice::peerAddress() const 00337 { 00338 if (m_sockfd == -1) 00339 return KSocketAddress(); // not open, empty value 00340 00341 kde_socklen_t len; 00342 KSocketAddress peerAddress; 00343 peerAddress.setLength(len = 32); // arbitrary value 00344 if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00345 // error! 00346 return KSocketAddress(); 00347 00348 if (len <= peerAddress.length()) 00349 { 00350 // it has fit already 00351 peerAddress.setLength(len); 00352 return peerAddress; 00353 } 00354 00355 // no, the socket address is actually larger than we had anticipated 00356 // call again 00357 peerAddress.setLength(len); 00358 if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00359 // error! 00360 return KSocketAddress(); 00361 00362 return peerAddress; 00363 } 00364 00365 KSocketAddress KSocksSocketDevice::externalAddress() const 00366 { 00367 // return empty, indicating unknown external address 00368 return KSocketAddress(); 00369 } 00370 00371 bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception, 00372 int timeout, bool *timedout) 00373 { 00374 if (m_sockfd == -1) 00375 { 00376 setError(IO_UnspecifiedError, NotCreated); 00377 return false; 00378 } 00379 00380 resetError(); 00381 fd_set readfds, writefds, exceptfds; 00382 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; 00383 00384 if (input) 00385 { 00386 preadfds = &readfds; 00387 FD_ZERO(preadfds); 00388 FD_SET(m_sockfd, preadfds); 00389 *input = false; 00390 } 00391 if (output) 00392 { 00393 pwritefds = &writefds; 00394 FD_ZERO(pwritefds); 00395 FD_SET(m_sockfd, pwritefds); 00396 *output = false; 00397 } 00398 if (exception) 00399 { 00400 pexceptfds = &exceptfds; 00401 FD_ZERO(pexceptfds); 00402 FD_SET(m_sockfd, pexceptfds); 00403 *exception = false; 00404 } 00405 00406 int retval; 00407 if (timeout < 0) 00408 retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); 00409 else 00410 { 00411 // convert the milliseconds to timeval 00412 struct timeval tv; 00413 tv.tv_sec = timeout / 1000; 00414 tv.tv_usec = timeout % 1000 * 1000; 00415 00416 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); 00417 } 00418 00419 if (retval == -1) 00420 { 00421 setError(IO_UnspecifiedError, UnknownError); 00422 return false; 00423 } 00424 if (retval == 0) 00425 { 00426 // timeout 00427 if (timedout) 00428 *timedout = true; 00429 return true; 00430 } 00431 00432 if (input && FD_ISSET(m_sockfd, preadfds)) 00433 *input = true; 00434 if (output && FD_ISSET(m_sockfd, pwritefds)) 00435 *output = true; 00436 if (exception && FD_ISSET(m_sockfd, pexceptfds)) 00437 *exception = true; 00438 00439 return true; 00440 } 00441 00442 void KSocksSocketDevice::initSocks() 00443 { 00444 static bool init = false; 00445 00446 if (init) 00447 return; 00448 00449 if (kapp == 0L) 00450 return; // no KApplication, so don't initialise 00451 // this should, however, test for KInstance 00452 00453 init = true; 00454 00455 if (KSocks::self()->hasSocks()) 00456 delete KSocketDevice::setDefaultImpl(new KSocketDeviceFactory<KSocksSocketDevice>); 00457 } 00458 00459 #if 0 00460 static bool register() 00461 { 00462 KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0); 00463 } 00464 00465 static bool register = registered(); 00466 #endif
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:26:10 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003