Connection.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <string.h>
00011 #include <netdb.h>
00012 #include <fcntl.h>
00013 #include <sys/time.h>
00014 #include <arpa/inet.h>
00015 #include <sys/socket.h>
00016 #include <errno.h>
00017 #include <sys/ioctl.h>
00018 #include <net/if.h>
00019 
00020 #include "Error.h"
00021 #include "Memory.h"
00022 #include "Core.h"
00023 
00024 #include "Connection.h"
00025 
00026 // Public methods.
00027 
00028 Connection::Connection(const int socket, struct sockaddr_in *addr) : Socket(socket)
00029 {
00030   int res;
00031 
00032   if (FAILED(res = setup(socket, addr)))
00033     failure(ERROR_BACKTRACE(res));
00034 }
00035 
00036 Connection::Connection() : Socket()
00037 {
00038 }
00039 
00040 Connection::~Connection()
00041 {
00042   int res;
00043 
00044   if (FAILED(res = CORE()->remove(this)))
00045     ERROR_BACKTRACE(res);
00046   if (_socket >= 0) {
00047     if (FAILED(res = shutdown(SHUT_RDWR)))
00048       ERROR_BACKTRACE(res);
00049     if (FAILED(res = close()))
00050       ERROR_BACKTRACE(res);
00051   }
00052 }
00053 
00054 int Connection::shutdown(const int how)
00055 {
00056   if (::shutdown(_socket, how) != 0)
00057     return ERROR(MSG_SOCKET_CANNOT_SHUTDOWN, strerror(errno));
00058 
00059   return OK;
00060 }
00061 
00062 int Connection::close()
00063 {
00064   if (::close(_socket) != 0)
00065     return ERROR(MSG_SOCKET_CANNOT_CLOSE, strerror(errno));
00066   _socket = -1;
00067 
00068   EMIT(closed);
00069 
00070   return OK;
00071 }
00072 
00073 String Connection::localIp() const
00074 {
00075   return _localIp;
00076 }
00077 
00078 String Connection::peerIp() const
00079 {
00080   return _peerIp;
00081 }
00082 
00083 unsigned int Connection::localPort() const
00084 {
00085   return _localPort;
00086 }
00087 
00088 unsigned int Connection::peerPort() const
00089 {
00090   return _peerPort;
00091 }
00092 
00093 int Connection::available(int &size)
00094 {
00095   if (ioctl(_socket, FIONREAD, &size) < 0)
00096     return ERROR(MSG_SOCKET_CANNOT_GET_INFO, strerror(errno));
00097 
00098   return OK;
00099 }
00100 
00101 int Connection::read(char *buffer, const unsigned int size, const unsigned int triesNum)
00102 {
00103   int actuallyRead, bytesToRead;
00104   int availableSize;
00105   unsigned int tries = 0;
00106   unsigned int bytesRead = 0;
00107   socklen_t peerLen = sizeof(_peer);
00108   int res;
00109 
00110 //  DEBUG("Reading data from socket...");
00111 
00112   while (bytesRead != size) {
00113     errno = 0;
00114     if (FAILED(res = available(availableSize)))
00115       return ERROR_BACKTRACE(res);
00116     if (availableSize <= 0) {
00117       if (triesNum != 0) {
00118         ++tries;
00119         if (tries >= triesNum)
00120           return ERROR(MSG_SOCKET_CANNOT_READ, strerror(errno));
00121       }
00122       usleep(CONNECTION_SLEEP_TIME);
00123       continue;
00124     }
00125     if ((bytesToRead = size - bytesRead) > availableSize)
00126       bytesToRead = availableSize;
00127 
00128     if ((actuallyRead = recvfrom(_socket, buffer + bytesRead, bytesToRead, 0, (struct sockaddr *)&_peer, &peerLen)) <= 0)
00129       return ERROR(MSG_SOCKET_CANNOT_READ, strerror(errno));
00130     bytesRead += actuallyRead;
00131   }
00132 
00133   return OK;
00134 }
00135 
00136 int Connection::readAvailable(char *buffer, const unsigned int maxSize, int &actuallyRead)
00137 {
00138   socklen_t peerLen = sizeof(_peer);
00139 
00140   errno = 0;
00141   if ((actuallyRead = recvfrom(_socket, buffer, maxSize, 0, (struct sockaddr *)&_peer, &peerLen)) < 0)
00142     return ERROR(MSG_SOCKET_CANNOT_READ, strerror(errno));
00143 
00144   return OK;
00145 }
00146 
00147 int Connection::readLn(String &buffer, const unsigned int maxSize, const unsigned int triesNum)
00148 {
00149   int actuallyRead;
00150   unsigned int tries = 0;
00151   unsigned int bytesRead = 0;
00152   unsigned char c;
00153   socklen_t peerLen = sizeof(_peer);
00154 
00155   buffer = "";
00156   while (1) {
00157     errno = 0;
00158     while ((actuallyRead = recvfrom(_socket, &c, 1, 0, (struct sockaddr *)&_peer, &peerLen)) <= 0 && errno == EAGAIN) {
00159       usleep(CONNECTION_SLEEP_TIME);
00160       errno = 0;
00161       if (triesNum > 0) {
00162         ++tries;
00163         if (tries >= triesNum && bytesRead == 0)
00164           return OK;
00165       }
00166     }
00167     if (actuallyRead > 0) {
00168       bytesRead += actuallyRead;
00169       if (bytesRead >= maxSize - 1)
00170         break;
00171       if (c != '\n' && c != '\r')
00172         buffer += c;
00173       if (c == '\n')
00174         break;
00175     } else
00176         if (bytesRead == 0)
00177           return actuallyRead < 0 ? ERROR(MSG_SOCKET_CANNOT_READ, strerror(errno)) : OK;
00178         else
00179           break;
00180   }
00181 
00182   return OK;
00183 }
00184 
00185 int Connection::write(const char *data, const unsigned int size, int &actuallyWritten)
00186 {
00187   if ((actuallyWritten = sendto(_socket, data, size, 0, (struct sockaddr *)&_peer, sizeof(_peer))) < 0)
00188     return errno != EAGAIN ? ERROR(MSG_SOCKET_CANNOT_WRITE, strerror(errno)) : OK;
00189 
00190   return OK;
00191 }
00192 
00193 int Connection::writeStr(const String &str)
00194 {
00195   int actuallyWritten;
00196   unsigned int len = str.length();
00197   int res;
00198 
00199 //  DEBUG("Writing to socket: '%s'.", str.c_str());
00200   if (FAILED(res = write(CSTRING(str), len, actuallyWritten)))
00201     return ERROR_BACKTRACE(res);
00202 
00203   if (actuallyWritten != (int)len)
00204     return ERROR(MSG_SOCKET_CANNOT_WRITE, strerror(errno));
00205 
00206   return OK;
00207 }
00208 
00209 int Connection::writeStr(char *str)
00210 {
00211   int actuallyWritten;
00212   unsigned int len = strlen(str);
00213   int res;
00214 
00215 //  DEBUG("Writing to socket: '%s'.", str);
00216   if (FAILED(res = write(str, len, actuallyWritten)))
00217     return ERROR_BACKTRACE(res);
00218 
00219   if (actuallyWritten != (int)len)
00220     return ERROR(MSG_SOCKET_CANNOT_WRITE, strerror(errno));
00221 
00222   return OK;
00223 }
00224 
00225 int Connection::writeLn(char *data, const char *eol)
00226 {
00227   int actuallyWritten;
00228   unsigned int len = strlen(data);
00229   int res;
00230 
00231   if (FAILED(res = write(data, len, actuallyWritten)))
00232     return ERROR_BACKTRACE(res);
00233   if (actuallyWritten != (int)len)
00234     return ERROR(MSG_SOCKET_CANNOT_WRITE, strerror(errno));
00235 
00236   if (eol) {
00237     len = strlen(eol);
00238     res = write(eol, len, actuallyWritten);
00239   } else {
00240       len = strlen(String::eol());
00241       res = write(String::eol(), len, actuallyWritten);
00242     }
00243   if (FAILED(res))
00244     return ERROR_BACKTRACE(res);
00245 
00246   if (actuallyWritten != (int)len)
00247     return ERROR(MSG_SOCKET_CANNOT_WRITE, strerror(errno));
00248 
00249   return OK;
00250 }
00251 
00252 int Connection::vprintf(const char *format, va_list ap)
00253 {
00254   String msg;
00255   int res;
00256 
00257   msg.vsprintf(format, ap);
00258   if (FAILED(res = writeStr(msg)))
00259     return ERROR_BACKTRACE(res);
00260 
00261   return OK;
00262 }
00263 
00264 int Connection::printf(const char *format, ...)
00265 {
00266   va_list ap;
00267   int res;
00268 
00269   va_start(ap, format);
00270   res = vprintf(format, ap);
00271   va_end(ap);
00272 
00273   if (FAILED(res))
00274     return ERROR_BACKTRACE(res);
00275 
00276   return OK;
00277 }
00278 
00279 int Connection::isAlive(bool &yes)
00280 {
00281   char ready;
00282   socklen_t peerLen = sizeof(_peer);
00283   ssize_t res;
00284 
00285   errno = 0;
00286   res = recvfrom(_socket, &ready, 1, MSG_PEEK, (struct sockaddr *)&_peer, &peerLen);
00287   yes = (res > 0 || res < 0 && errno == EAGAIN);
00288 
00289   return OK;
00290 }
00291 
00292 int Connection::clear()
00293 {
00294   char buff[LIMIT_CSTRING_SIZE];
00295   socklen_t peerLen = sizeof(_peer);
00296   int size, actuallyRead;
00297   unsigned int bytesRead = 0, bytesToRead;
00298   int res;
00299 
00300   if (FAILED(res = available(size)))
00301     return ERROR_BACKTRACE(res);
00302 
00303   if (size <= 0)
00304     return OK;
00305 
00306   while ((int)bytesRead < size) {
00307     if ((bytesToRead = size - (int)bytesRead) > sizeof(buff))
00308       bytesToRead = sizeof(buff);
00309     if ((actuallyRead = recvfrom(_socket, buff, bytesToRead, 0, (struct sockaddr *)&_peer, &peerLen)) < 0)
00310       break;
00311     bytesRead += actuallyRead;
00312   }
00313 
00314   return OK;
00315 }
00316 
00317 int Connection::setAddress(const char *host, const char *service, const char *protocol, struct sockaddr_in *sap)
00318 {
00319   struct servent *sp;
00320   struct hostent *hp;
00321   char *endptr;
00322   short port;
00323 
00324   bzero(sap, sizeof(*sap));
00325   sap->sin_family = AF_INET;
00326   if (host && strlen(host)) {
00327     if (!inet_aton(host, &sap->sin_addr)) {
00328       hp = gethostbyname(host);
00329       if (hp == NULL)
00330         return ERROR(MSG_SOCKET_UNKNOWN_HOST, host);
00331       sap->sin_addr = *(struct in_addr *)hp->h_addr;
00332     }
00333   } else
00334       sap->sin_addr.s_addr = htonl(INADDR_ANY);
00335 
00336   port = strtol(service, &endptr, 0);
00337   if (*endptr == '\0')
00338     sap->sin_port = htons(port);
00339   else {
00340     sp = getservbyname(service, protocol);
00341     if (sp == NULL)
00342       return ERROR(MSG_SOCKET_UNKNOWN_SERVICE, service);
00343     sap->sin_port = sp->s_port;
00344   }
00345 
00346   return OK;
00347 }
00348 
00349 int Connection::localIp(String &ip)
00350 {
00351   struct ifreq ifReq;
00352   int sock;
00353 
00354   memset(&ifReq, 0, sizeof(ifReq));
00355   strcpy(ifReq.ifr_name, CONNECTION_DEFAULT_INT_NAME);
00356 
00357   if ((sock = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00358     return ERROR(MSG_SOCKET_CANNOT_CREATE, strerror(errno));
00359 
00360   if (ioctl(sock, SIOCGIFADDR, &ifReq) != 0) {
00361     ::close(sock);
00362     return ERROR(MSG_SOCKET_CANNOT_GET_INFO, strerror(errno));
00363   }
00364 
00365   ip = inet_ntoa(((struct sockaddr_in *)&ifReq.ifr_addr)->sin_addr);
00366 
00367   if (::close(sock) != 0)
00368     return ERROR(MSG_SOCKET_CANNOT_CLOSE, strerror(errno));
00369 
00370   return OK;
00371 }
00372 
00373 // Protected methods.
00374 
00375 int Connection::setup(const int socket, struct sockaddr_in *addr)
00376 {
00377   socklen_t localLen;
00378   int res;
00379 
00380   _socket = socket;
00381   _peer = *addr;
00382   localLen = sizeof(_local);
00383   getsockname(_socket, (struct sockaddr *)&(_local), &localLen);
00384 
00385   _localIp = inet_ntoa(_local.sin_addr);
00386   _localPort = ntohs(_local.sin_port);
00387   _peerIp = inet_ntoa(_peer.sin_addr);
00388   _peerPort = ntohs(_peer.sin_port);
00389 
00390   if (FAILED(res = CORE()->add(this)))
00391     return ERROR_BACKTRACE(res);
00392 
00393   return OK;
00394 }
00395 
00396 int Connection::setDataReady()
00397 {
00398   EMIT(dataReady);
00399   return OK;
00400 }
00401 
00402 int Connection::setDead()
00403 {
00404   _socket = -1;
00405   EMIT(dead);
00406   return OK;
00407 }

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1