Bridge.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2002-2009 Moxie Marlinspike
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. * USA
  18. */
  19. #ifndef __BRIDGE_H__
  20. #define __BRIDGE_H__
  21. #include <boost/asio.hpp>
  22. #include <boost/enable_shared_from_this.hpp>
  23. #include <boost/shared_ptr.hpp>
  24. #include <boost/bind.hpp>
  25. #include "Logger.hpp"
  26. #define BUFFER_SIZE 4096
  27. using namespace boost::asio;
  28. class Bridge : public boost::enable_shared_from_this<Bridge> {
  29. public:
  30. typedef boost::shared_ptr<Bridge> ptr;
  31. virtual void close() = 0;
  32. virtual ip::tcp::socket& getClientSocket() = 0;
  33. virtual ip::tcp::socket& getServerSocket() = 0;
  34. virtual void shuttle() = 0;
  35. private:
  36. ip::tcp::socket *clientSocket;
  37. ip::tcp::socket *serverSocket;
  38. void read(ip::tcp::socket *socket, char *buffer) {
  39. socket->async_read_some(boost::asio::buffer(buffer, BUFFER_SIZE),
  40. boost::bind(&Bridge::readComplete,
  41. shared_from_this(), socket, buffer,
  42. placeholders::error,
  43. placeholders::bytes_transferred));
  44. }
  45. void readComplete(ip::tcp::socket *socket, char *buffer,
  46. const boost::system::error_code& error, size_t bytesRead)
  47. {
  48. if (!error) {
  49. if (socket == clientSocket)
  50. processClientInput(buffer, bytesRead);
  51. async_write((socket == clientSocket) ? *serverSocket : *clientSocket,
  52. boost::asio::buffer(buffer, bytesRead),
  53. boost::bind(&Bridge::writeComplete, shared_from_this(),
  54. socket, buffer, placeholders::error));
  55. } else if (error != error::operation_aborted) {
  56. std::stringstream errorStream;
  57. errorStream << "Read error: " << error;
  58. std::string error = errorStream.str();
  59. Logger::logError(error);
  60. close();
  61. }
  62. }
  63. void writeComplete(ip::tcp::socket *socket, char *buffer,
  64. const boost::system::error_code &error)
  65. {
  66. if (!error) read(socket, buffer);
  67. else if (error != error::operation_aborted) close();
  68. }
  69. protected:
  70. char clientBuffer[BUFFER_SIZE];
  71. char serverBuffer[BUFFER_SIZE];
  72. virtual void processClientInput(char *buffer, int length) = 0;
  73. void shuttle(ip::tcp::socket *clientSocket,
  74. ip::tcp::socket *serverSocket)
  75. {
  76. this->clientSocket = clientSocket;
  77. this->serverSocket = serverSocket;
  78. read(clientSocket, clientBuffer);
  79. read(serverSocket, serverBuffer);
  80. }
  81. ptr getSmartPointer() {
  82. return shared_from_this();
  83. }
  84. };
  85. #endif