libpm – a handy port mapping class based on Boost::Asio

Higher  bandwidth is required when games/videos have higher definition. Even cost on purchasing bandwidth is getting cheaper, but never too much.  P2P is an option which make transferring faster when more users are requesting the same content.

Many factors are unable to change if the cost is fixed, but at least two factors affecting P2P efficiency are able to change.

  1. System firewall.
  2. Gateway port mapping.

We already have classes to control Windows builtin firewall, support both winxp and Win7(and above).

A new library is created based on boost::asio, based on the code found in libtorrent.

It has following features:

  1. support both upnp(found in most rouers) and natpmp(found in apple products and some products from asus)
  2. based on c++ 11, very easy to add port mapping in client applications.
  3. able to provide external addresses and mapped port
  4. auto renew and manage mapping from multi sources(applications add mapping, and the library will talk to routers with upnp and natpmp)

 

Here is the interface:

class PortMapper
{
public:
enum protocol_type { none = 0, udp = 1, tcp = 2 };
enum map_source { source_natpmp = 1, source_upnp = 2 };
typedef std::function<void(int)> callback_t;
struct MappingStatus
{
int local_port = 0;
int external_port = 0;
int protocol = none;
boost::asio::ip::address external_address = boost::asio::ip::address();
int source = 0;
};

virtual int add_mapping(protocol_type protocol, int local_port/* >0 */, callback_t const& callback, int external_port = 0) = 0;
virtual void delete_mapping(int mapping_index)=0;
virtual bool get_mapping(int mapping_index, MappingStatus& status)=0;
};

std::shared_ptr<PortMapper> CreatePortMapper();

And here is the example:

auto pm = CreatePortMapper();

int tcp_index = pm->add_mapping(PortMapper::tcp, 6001, std::bind(&on_port_mapping, pm.get(), std::placeholders::_1));
int udp_index = pm->add_mapping(PortMapper::udp, 6002, std::bind(&on_port_mapping, pm.get(), std::placeholders::_1));

In real application, we will add the pm instance as an application scope variable.

We can get mapping notification in callback, we can also check mapping from any thread at any time.

Known limitations:

  1. due to security concern, many routers turn off upnp by default.
  2. once we auto add application to system firewall exception list and router port mapping, any user can connect to it, this causes more upload than usual during transferring.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s