Author Topic: udp problems behind a router  (Read 3779 times)

ldw-bas

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 2
  • Posts: 32
    • View Profile
udp problems behind a router
« on: February 14, 2014, 10:39:30 AM »
Hi,

I am developing a networked game using TNet. I works pretty nice, but now I have ran into a problem. I wanted to take my game outside of the LAN environment. This works fine with tcp but it doesn't work with udp packages.

Setup:
VPS running TNServer in mono.
Laptop on a home network running the game (one or multiple times)

Checks I did:
VPS is configured correctly, connecting to internet directly without router everything works fine.
Router configuration should be fine, this has been the same for ages and I have played all kind of games over internet of which some must use UDP. I didn't have to do any router configurations for those. So I guess it is a programmatical issue more than a configurational on the router side.
Client does send UDP packages that do arrive on the server.
Server only sends two UDP start package (which I guess is for the lobby)
After I had done a further code inspection it seems the server is denying udp packages because they are send from a different address than the address set on the player. Actually this is just another port, for example the UdpEndPoint for my client player is set to [externalip]:35138 and all message from the client come from [externalip]:59587 .
So my first guess to fix this would be to do the setting of the UdpEndPoint over udp instead of tcp, but I am not sure if this is the way to go or if there is a better solution to this problem.

I hope my description is clear, otherwise I would gladly clarify them.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: udp problems behind a router
« Reply #1 on: February 15, 2014, 02:25:30 AM »
Hmm... the port is passed as a part of Packet.RequestUDP. It's explicitly sent by the client inside GameClient.StartUDP. How does it end up being different?

ldw-bas

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 2
  • Posts: 32
    • View Profile
Re: udp problems behind a router
« Reply #2 on: February 15, 2014, 04:06:24 AM »
My guess is that instead of forwarding my the external port to my local port there is a mapping between ports,  so [internalip]:xxxxx -> [externalip]:yyyyy instead of [internalip]:xxxxx -> [externalip]:xxxxx. Still it would be strange that is sends the externalip with the internal port, maybe something is wrong with detecting addresses in messages by my router. I can try to show how the RequestUDP packages looks in different stages. I'll update you on that when it's done.
Nevermind the RequestUDP only sends the port, and TNET just graps the ip from the tcpendpoint.


Yesterday I did already run a test by replying an udp package to the same address as I received a message from on the server. This message does arrive on my client. So I guess in my case it is possible to do the RequestUDP over udp. I don't know if that would result in some other issues apart from not being sure the RequestUDP ever arrives.

 

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: udp problems behind a router
« Reply #3 on: February 16, 2014, 03:35:14 AM »
StartUDP starts listening to a specific port, which is the port that gets sent with the RequestSetUDP packet. This gets sent over TCP, so I am not sure which port you are using there. Are you using the TCP port?

ldw-bas

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 2
  • Posts: 32
    • View Profile
Re: udp problems behind a router
« Reply #4 on: February 17, 2014, 05:25:54 AM »
Ok, from your question it seems to me that there is a misunderstanding. Everything still works the same with the TNGameServer and TNGameClient, the only changes I have made are debug changes. The issues are the same without those changes. The UDP connection is made by TNAutoJoin so the UDP port is randomly generated.

The opening of the UDP port does work but the port is the port on my local network. The random port that is opened on the client is sent in the content of a TCP message, just like you programmed it. Of course my router has no knowledge of the contents of this message. So it just passes it through. So the server is aware of my clients local udp port. But when I sent a udp packet from my client to the server through this udp port which I opened, the sender address on the server is from a different port. This is probably because my router translates this port, but did not translate the content of this udp message. If I reply to the address this message came from than it arrives on my client on the local port. So it does get translated back.

My conclusion is the only way to inform the server about the right port on the router is to send a udp message from the client to the server and take this sender address to reply to.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: udp problems behind a router
« Reply #5 on: February 17, 2014, 12:35:16 PM »
TNet uses UPnP to open a port on the router, ensuring that the same port on the router will translate to the same local value, so when packets arrive at the opened port they end up getting forwarded to the local computer. It sounds like that's not happening in your case. Well, I'm going to modify the TNGameServer to set the UDP end point from the first UDP packet that arrives from the player and not inside the RequestSetUDP callback.

Edit: On second thought this isn't feasible as there is no way to determine who the packet is from in cases where you have more than one player behind the same public IP. This is why the TCP identification step is necessary -- it says "all messages coming from this IP and this UDP port belong to player X".

Edit #2: I've just added a "udp is usable" flag to the player class that gets set to 'true' only after a UDP packet has arrived from the player. It needs testing though. If you're up for it I can give you the updated version (add me on skype -- arenmook).
« Last Edit: February 17, 2014, 01:39:38 PM by ArenMook »

ldw-bas

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 2
  • Posts: 32
    • View Profile
Re: udp problems behind a router
« Reply #6 on: February 18, 2014, 03:42:26 AM »
Ok, I have looked it up, the TNet examples do not use UPnP on the client side, so I assumed this technique should only be used for the server.

I only have one theoretical issue with the UPnP solution that you suggest, this is a very quick conclusion so maybe I am wrong. But opening the same port on the router as you use locally will cause issues when you are using a fixed port for you game and you want to run multiple instances on a local network using the same router to get on internet. Maybe this is just a general issue, which usually is solving by only having the first game instance having this fixed port. And other having a dynamic one?

You are right about the identification of the player from the udp package, that is not possible in such a way. Another solution could be to first send a udp packet containing a player identification to set up a udp "connection". This probably also requires a reponse packet to ensure the udp packet did arrive.

I have added you on skype, I am curious to the new version.