Sign in to follow this  

Help with UPnP? (code)

This topic is 2665 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I need a little help with uPnP if anyone can spare a minute.

I wanted to learn socket programming, so I made a nice little web server that uses IO completion ports and all that good stuff. When I forward the port manually from within the my router's settings, the server runs fine. I recently tried to get it to work with uPnP, but had no luck.

I tried connecting to the server from outside my home network, but couldn't get a response.

I checked that:

1) uPnP is enabled in the router's settings
2) I am not receiving any errors from my code


This is the code for the wrapper that I made:

mappedport.h
#ifndef INC_MAPPEDPORT_H
#define INC_MAPPEDPORT_H

#pragma comment (lib, "ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#include <Natupnp.h>
#include <Windows.h>

class MappedPort
{
private:
HRESULT hr;
wchar_t protocol_[4];
long lport_;
bool initialized_;
bool mapped_;

IUPnPNAT *uPnP;
IStaticPortMapping *spmOut;
IStaticPortMappingCollection *spmCol;
bool Initialize();

public:
MappedPort();
MappedPort(long lPort, wchar_t *protocol /* "TCP" or "UDP" */, wchar_t *description);
~MappedPort();

bool Map(long lPort, wchar_t *protocol /* "TCP" or "UDP" */, wchar_t *description);
bool Unmap();
bool IsMapped();
};
#endif /* INC_MAPPEDPORT_H */



mappedport.cpp
#include "mappedport.h"
MappedPort::MappedPort()
{
Initialize();
}
MappedPort::MappedPort(long lPort, wchar_t *protocol, wchar_t *description)
{
if(Initialize())
mapped_ = Map(lPort, protocol, description);
}
bool MappedPort::Initialize()
{
lport_ = 0;
mapped_ = false;
initialized_ = false;
hr = 0;
uPnP = NULL;
spmOut = NULL;
spmCol = NULL;

if(CoInitialize(NULL) == S_OK)
{
hr = CoCreateInstance(__uuidof(UPnPNAT), NULL, CLSCTX_ALL, __uuidof(IUPnPNAT), (void **)&uPnP);
if(hr == S_OK && uPnP != NULL)
{
hr = uPnP->get_StaticPortMappingCollection(&spmCol);
if(hr == S_OK && spmCol != NULL)
{
initialized_ = true;
}
}
}
return initialized_;
}
MappedPort::~MappedPort()
{
if(mapped_)
this->Unmap();

if(uPnP) uPnP->Release();
if(spmCol) spmCol->Release();
if(spmOut) spmOut->Release();

if(initialized_)
CoUninitialize();

}

bool MappedPort::Map(long lPort, wchar_t *protocol, wchar_t *description)
{
WSADATA wsaData;
char hostname[256];
PHOSTENT hostinfo;
wchar_t ip[16];

lport_ = lPort;
wcscpy_s(protocol_, 4, protocol);

if((initialized_ == true) && (mapped_ == false))
{
spmCol->Remove(lport_, protocol_);

if(WSAStartup(MAKEWORD(2,2), &wsaData) == 0)
{
if(gethostname(hostname, sizeof(hostname)) == 0)
{
hostinfo = gethostbyname(hostname);
if(hostinfo != NULL)
{
if(InetNtopW(AF_INET, (struct in_addr*)*hostinfo->h_addr_list, ip, sizeof(ip)) != NULL)
{
if(spmCol->Add(lPort, protocol, lPort, ip, TRUE, description, &spmOut) == S_OK)
{
mapped_ = true;
}
}
}
}
WSACleanup();
}
}

return mapped_;
}
bool MappedPort::Unmap()
{
return (spmCol->Remove(lport_, protocol_) == S_OK);
}
bool MappedPort::IsMapped()
{
return mapped_;
}



If someone could point out any obvious errors that I am making here, it would be greatly appreciated.

bonus: if you can fix it, you can keep it =D

thanks

[Edited by - CPPNick on August 30, 2010 8:46:13 AM]

Share this post


Link to post
Share on other sites
I'm really surprised I didn't get any answers for this. Anyways, it works now. I edited the code above to reflect the newest, working code, for uPnP (automatic port forwarding).

Share this post


Link to post
Share on other sites
The reason is probably that most people think UPnP is a bad idea, for two reasons:

1) It removes one of the securities of a firewall -- the firewall administrator is no longer in control of traffic.

2) It's fundamentally broken -- if two users want to host the same port, they can't. A real game hosting system/broker would allocate different ports to different users behind the same firewall.

Share this post


Link to post
Share on other sites
Do you know how this problem will be handled in the future then?
Does the IPv6 protocol address this somehow?

I imagine that all it would take to overcome this would be to update the TCP/IP packet header to also contain a private network IP.

anyways, imo, if people download illegally cracked software, and get a trojan, that should be their problem...and as far as operating systems go, I would rather click "allow" for each incoming or outgoing connection then have to deal with virus scanners or firewalls.. people take computers for granted way to easily... I am not going to try and start a flame war here, but I hope that the new EHF fees they are imposing on computer products in Canada are just the beginning. There should be laws that protect people's rights to use their technology. If I can get a ticket for speeding, why not for spamming ? :)

Share this post


Link to post
Share on other sites
[quote[Do you know how this problem will be handled in the future then?[/quote]

It's already handled just fine, through NAT punch-through and public matchmaking services, and putting "real" servers in data centers with public IPs (or behind reverse NAT). The idea that consumers can put useful "servers" in their closet for the greater Internet to use without help from some more central dictionary isn't all that viable IMO.

Quote:
Does the IPv6 protocol address this somehow?


With IPv6, there's enough IP addresses so that NAT won't be needed, so firewalling becomes a responsibility of the host, not the router/gateway.
Of course, they designed the IPv6 address space totally without any regard for mobile IPs, and mobile IP is growing at 10x the rate of stationary IP, so whether that will actually ever solve anything is a different question :-)

AFAICT, IPv4 with NAT and central match-makers are here to stay for some time.

Share this post


Link to post
Share on other sites

This topic is 2665 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this