Created
October 14, 2012 15:32
-
-
Save mike-zhang/3888929 to your computer and use it in GitHub Desktop.
a simple udp proxy server (cpp code)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
File : udpProxyServer.cpp | |
Author : Mike | |
E-Mail : [email protected] | |
*/ | |
#include <cstdlib> | |
#include <cstddef> | |
#include <iostream> | |
#include <string> | |
#include <boost/shared_ptr.hpp> | |
#include <boost/enable_shared_from_this.hpp> | |
#include <boost/bind.hpp> | |
#include <boost/asio.hpp> | |
#include <boost/thread/mutex.hpp> | |
namespace udpProxy | |
{ | |
namespace ip = boost::asio::ip; | |
using namespace boost::asio; | |
using namespace std; | |
const int max_data_length = 1024 * 10; | |
class m_udpProxyServer | |
{ | |
public: | |
m_udpProxyServer(io_service& io,const string& localhost, | |
const int& localport,const string& remotehost,const int& remoteport): | |
downstream_socket_(io,ip::udp::endpoint(ip::udp::v4(),localport)), | |
upstream_socket_(io), | |
_remotehost(remotehost), | |
_remoteport(remoteport), | |
upstream_remoteUdpEndpoint(ip::address_v4::from_string(_remotehost),_remoteport) | |
{ | |
start_downstream_receive(); | |
} | |
void start_downstream_receive() | |
{ | |
downstream_socket_.async_receive_from( | |
boost::asio::buffer(downstream_data_,max_data_length), | |
downstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::upstream_connect,this, | |
boost::asio::placeholders::bytes_transferred, | |
boost::asio::placeholders::error)); | |
} | |
void upstream_connect(const size_t& bytes_transferred, | |
const boost::system::error_code& error) | |
{ | |
if (!error ) | |
{ | |
upstream_socket_.async_connect( | |
upstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_upstream_connect, | |
this,bytes_transferred,boost::asio::placeholders::error)); | |
} | |
else | |
{ | |
std::cerr << "Error: " << error.message() << std::endl; | |
} | |
} | |
void handle_upstream_connect(const size_t& bytes_transferred, | |
const boost::system::error_code& error) | |
{ | |
upstream_socket_.async_send_to( | |
boost::asio::buffer(downstream_data_,bytes_transferred), | |
upstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_upstream_send, | |
this,boost::asio::placeholders::error)); | |
} | |
void handle_upstream_send(const boost::system::error_code& error) | |
{ | |
if (!error ) | |
{ | |
upstream_socket_.async_receive_from( | |
boost::asio::buffer(upstream_data_,max_data_length), | |
upstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_upstream_receive, | |
this, | |
boost::asio::placeholders::bytes_transferred, | |
boost::asio::placeholders::error)); | |
} | |
else | |
{ | |
std::cerr << "Error: " << error.message() << std::endl; | |
} | |
} | |
void handle_upstream_receive(const size_t& bytes_transferred, | |
const boost::system::error_code& error) | |
{ | |
if (!error ) | |
{ | |
downstream_socket_.async_send_to( | |
boost::asio::buffer(upstream_data_,bytes_transferred), | |
downstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_downstream_send, | |
this, | |
boost::asio::placeholders::error)); | |
} | |
else | |
{ | |
std::cerr << "Error: " << error.message() << std::endl; | |
} | |
} | |
void handle_downstream_send(const boost::system::error_code& error) | |
{ | |
if (!error ) | |
{ | |
downstream_socket_.async_receive_from( | |
boost::asio::buffer(downstream_data_,max_data_length), | |
downstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_downstream_receive,this, | |
boost::asio::placeholders::bytes_transferred, | |
boost::asio::placeholders::error)); | |
} | |
else | |
{ | |
std::cerr << "Error: " << error.message() << std::endl; | |
} | |
} | |
void handle_downstream_receive(const size_t& bytes_transferred, | |
const boost::system::error_code& error) | |
{ | |
upstream_socket_.async_send_to( | |
boost::asio::buffer(downstream_data_,bytes_transferred), | |
upstream_remoteUdpEndpoint, | |
boost::bind(&m_udpProxyServer::handle_upstream_send, | |
this,boost::asio::placeholders::error)); | |
} | |
private: | |
ip::udp::socket downstream_socket_; | |
ip::udp::socket upstream_socket_; | |
string _remotehost; | |
int _remoteport; | |
ip::udp::endpoint downstream_remoteUdpEndpoint; | |
ip::udp::endpoint upstream_remoteUdpEndpoint; | |
unsigned char downstream_data_[max_data_length]; | |
unsigned char upstream_data_[max_data_length]; | |
}; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
if (argc != 5) | |
{ | |
std::cerr << "usage: udpProxyServer<local host ip> <local port> <forward host ip> <forward port>" << std::endl; | |
return 1; | |
} | |
const unsigned short local_port = static_cast<unsigned short>(::atoi(argv[2])); | |
const unsigned short forward_port = static_cast<unsigned short>(::atoi(argv[4])); | |
const std::string local_host = argv[1]; | |
const std::string forward_host = argv[3]; | |
boost::asio::io_service ios; | |
try | |
{ | |
udpProxy::m_udpProxyServer svrTest(ios, | |
local_host,local_port, | |
forward_host,forward_port); | |
ios.run(); | |
} | |
catch(std::exception& e) | |
{ | |
std::cerr << "main : Error: " << e.what() << std::endl; | |
return 1; | |
} | |
return 0; | |
} | |
// LINK : -L/usr/lib -lstdc++ -l pthread -l boost_thread-mt -l boost_system |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@MatrixManAtYrService I believe the code was taken from this TCP Proxy Server implementation:
https://www.partow.net/programming/tcpproxy/index.html
Where the type of the sockets were changed to be ip::udp::socket