You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Socket.cxx 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #ifdef WIN32
  22. //#include <io.h>
  23. #include <winsock2.h>
  24. #include <ws2tcpip.h>
  25. #define errorNumber WSAGetLastError()
  26. #else
  27. #define errorNumber errno
  28. #define closesocket close
  29. #include <sys/socket.h>
  30. #endif
  31. #include <unistd.h>
  32. #include <signal.h>
  33. #include <fcntl.h>
  34. #include <errno.h>
  35. #include <network/Socket.h>
  36. using namespace network;
  37. // -=- Socket initialisation
  38. static bool socketsInitialised = false;
  39. void network::initSockets() {
  40. if (socketsInitialised)
  41. return;
  42. #ifdef WIN32
  43. WORD requiredVersion = MAKEWORD(2,0);
  44. WSADATA initResult;
  45. if (WSAStartup(requiredVersion, &initResult) != 0)
  46. throw SocketException("unable to initialise Winsock2", errorNumber);
  47. #else
  48. signal(SIGPIPE, SIG_IGN);
  49. #endif
  50. socketsInitialised = true;
  51. }
  52. bool network::isSocketListening(int sock)
  53. {
  54. int listening = 0;
  55. socklen_t listening_size = sizeof(listening);
  56. if (getsockopt(sock, SOL_SOCKET, SO_ACCEPTCONN,
  57. (char *)&listening, &listening_size) < 0)
  58. return false;
  59. return listening != 0;
  60. }
  61. Socket::Socket(int fd)
  62. : instream(0), outstream(0),
  63. isShutdown_(false), queryConnection(false)
  64. {
  65. initSockets();
  66. setFd(fd);
  67. }
  68. Socket::Socket()
  69. : instream(0), outstream(0),
  70. isShutdown_(false), queryConnection(false)
  71. {
  72. initSockets();
  73. }
  74. Socket::~Socket()
  75. {
  76. if (instream && outstream)
  77. closesocket(getFd());
  78. delete instream;
  79. delete outstream;
  80. }
  81. // if shutdown() is overridden then the override MUST call on to here
  82. void Socket::shutdown()
  83. {
  84. isShutdown_ = true;
  85. ::shutdown(getFd(), 2);
  86. }
  87. bool Socket::isShutdown() const
  88. {
  89. return isShutdown_;
  90. }
  91. // Was there a "?" in the ConnectionFilter used to accept this Socket?
  92. void Socket::setRequiresQuery()
  93. {
  94. queryConnection = true;
  95. }
  96. bool Socket::requiresQuery() const
  97. {
  98. return queryConnection;
  99. }
  100. void Socket::setFd(int fd)
  101. {
  102. #ifndef WIN32
  103. // - By default, close the socket on exec()
  104. fcntl(fd, F_SETFD, FD_CLOEXEC);
  105. #endif
  106. instream = new rdr::FdInStream(fd);
  107. outstream = new rdr::FdOutStream(fd);
  108. isShutdown_ = false;
  109. }
  110. SocketListener::SocketListener(int fd)
  111. : fd(fd), filter(0)
  112. {
  113. initSockets();
  114. }
  115. SocketListener::SocketListener()
  116. : fd(-1), filter(0)
  117. {
  118. initSockets();
  119. }
  120. SocketListener::~SocketListener()
  121. {
  122. if (fd != -1)
  123. closesocket(fd);
  124. }
  125. void SocketListener::shutdown()
  126. {
  127. #ifdef WIN32
  128. closesocket(fd);
  129. fd = -1;
  130. #else
  131. ::shutdown(fd, 2);
  132. #endif
  133. }
  134. Socket* SocketListener::accept() {
  135. int new_sock = -1;
  136. // Accept an incoming connection
  137. if ((new_sock = ::accept(fd, 0, 0)) < 0)
  138. throw SocketException("unable to accept new connection", errorNumber);
  139. // Create the socket object & check connection is allowed
  140. Socket* s = createSocket(new_sock);
  141. if (filter && !filter->verifyConnection(s)) {
  142. delete s;
  143. return NULL;
  144. }
  145. return s;
  146. }
  147. void SocketListener::listen(int sock)
  148. {
  149. // - Set it to be a listening socket
  150. if (::listen(sock, 5) < 0) {
  151. int e = errorNumber;
  152. closesocket(sock);
  153. throw SocketException("unable to set socket to listening mode", e);
  154. }
  155. fd = sock;
  156. }