Skip to content

Instantly share code, notes, and snippets.

@mike-zhang
Created October 14, 2012 15:32
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mike-zhang/3888929 to your computer and use it in GitHub Desktop.
Save mike-zhang/3888929 to your computer and use it in GitHub Desktop.
a simple udp proxy server (cpp code)
/*
File : udpProxyServer.cpp
Author : Mike
E-Mail : Mike_Zhang@live.com
*/
#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
@MatrixManAtYrService
Copy link

Is the localhost parameter needed? Unless I'm missing something it doesn't get used

@ArashPartow
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment