Archived

This topic is now archived and is closed to further replies.

Doolwind

Getting Clients Port Number through Firewall

Recommended Posts

Doolwind    213
Hi, I''ve written the netcode for my game but I''m having issues getting it to work through a hardware firewall. With port forwarding on my (software) firewall everything works fine, the packets are forwarded to the game PC. The problem is at another site where a D-Link (hardware) firewall/router is set up. Port forwarding is also set up on it but the packets aren''t getting through correctly. Currently I am passing information back and forth on port 5555, but I have heard that this isn''t the best way. Apparently, I should be listening to what port the messages come in from the client and should send messages back to them on the same port. So here is my question....when I call ''recvfrom'' I am filling the SOCKADDR which tells me where the data is coming from. However, each time I call ''recvfrom'' it fills the SOCKADDR with a different port number, even though the client is connecting using port 5555 each time. I tested this on my network and even within the one machine and ''recvfrom'' still gives a different port number each time. Am I doing something wrong with the way I am using ''recvfrom''?? Here is some of the code I am using:
SOCKADDR from;
recvfrom(_recvSock, SocketMessage, _maxMessageSize, 0, &from, &len);
SOCKADDR_IN* inSock = (SOCKADDR_IN*)&from;
unsigned short inPort = inSock->sin_port;  //This port number changes with each time I try connecting

Doolwind --------------------------------------------------------- Who of you by worrying can add a single hour to his life. Matthew 6:27

Share this post


Link to post
Share on other sites
jermz    122
Sounds like you are getting the client''s ephemeral port. When you call sendto() without binding to a particular interface, the host system will choose an unused port to send from. The actual data is being sent to the receiver listening at port 5555. If you want the data to come from a particular port, you need to bind a socket to that address/port ahead of time and use it in the call.

You are right in that the general way is to get the client''s address/port from the packet and send to that as the server. This way you don''t put restrictions on the client''s network use and it also works well for hardware NAT and auto-generated firewall rules. Obviously, as the server you need to listen at a well-known port so the clients can find you.

Share this post


Link to post
Share on other sites
Doolwind    213
Hi,

I''ve changed my code so the server now sends messages back on the port given in the message from the client. However, it is still not working.

When the first message comes in from the client I am checking the ''sin_port'' of it''s ''SOCKADDR_IN'' which gives me the port to use. I am then setting that up as the port to send back on but the message still isn''t getting through.

The problem is on a DSL-504 D-Link hardware ADSL router if that is any help. Also I am using UDP if I wasn''t clear earlier.

If anyone has any other suggestions that would be greatly apprectiated. My next plan is to find someone else to test the game with who doesn''t have a firewall to see if I can narrow down the problem.

Thanks

Doolwind

---------------------------------------------------------
Who of you by worrying can add a single hour to his life.
Matthew 6:27

Share this post


Link to post
Share on other sites
jermz    122
From reading what you wrote, I still get the impression you are a bit confused on the address/port pairs on each end. If you have it down, forgive me, it must be the whackass router/firewall you are using...

OK, so theres two sets of address/port tuples, one for the client and one for the server. The server creates a socket for UDP communication (SOCK_DGRAM) and binds to a well known port (5555 in your case). It then listens on that socket for incoming packets (via recvfrom()).

The client eventually will want to make contact with the server. They create a socket using 0 for the port. This causes the host system to choose an ephemeral port. Then they create a NEW sockaddr_in structure. This one is to be used to send. The original one with the 0 was for creating a socket for their use. This new one indicates the server address to send to. Fill in the address/port (5555) and use this new sockaddr_in in the call to sendto().

When the server stopped to listen for client messages, it passed an emtpy sockaddr_in to recvfrom() so that the OS could fill in the source address. This will list the client''s address/port. Let''s say its 1812 for the port.

Now the client knows this server address (server.somewhere.net:5555) and the server knows the client address (client.somewhereelse.net:1812). Both have a host sockaddr_in that they use to send/recv from and a dest sockaddr_in that they use to send to. As long as you keep the sockets you allocated with the host sockaddr_in active and remember the dest sockaddr_in to send to, you should be fine.

Share this post


Link to post
Share on other sites