Changes in Networking (with patch)

Changes in Networking (with patch)

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Auswaschbar
Spring Developer
Posts: 1254
Joined: 24 Jun 2007, 08:34

Changes in Networking (with patch)

Post by Auswaschbar »

Hello,

I was bored so I made some changes in the networking code of spring. I tried to send this in the mailing list but its too big and got rejected, so I will post it here:

Here's what I have done in a short form:
- CNet is now independent from CNetProtocol
- moved map name, mod name and script name to CNetProtocol, removed functions from CNet and made the game use the already existing functions from CNetProtocol
- struct connection got its own file, was made a class CConnection and got some usefull functions (which are removed from CNet)
- CLocalConnection is a subclass and represents the connection between server / client in one instance of spring, there's no difference in usage between local and remote connections
- simplified usage of CNet / CNetProtocol from outside (in CGame, CGameServer)
- NETMSG_HELLO removed from NETMSG, moved inside CConnection, and this type of messages are now handled in CConnection (so CGame, CGameServer and CPreGame doesn't have to care)


I haven't changed the protocol itself (until now), so everything should work as before

Things I have already tested:
Compiling on Linux
Single Player (random enemies)
Multiplayer (running 2 Instances of spring on the same pc, so 'real' multiplayer should work as well)

Things that still need testing:
Compiling on other OSes
Demo recording / playback

The patch is here:
http://freenet-homepage.de/auswaschbar/network.diff
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

You have to wait for the forum to give you your link wings. Anyway, welcome to the community.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

ehh.. It's always good to see people contributing, however tobi has done quite some work already on replacing the netcode (see http://spring.clan-sy.com/fisheye/brows ... es/netcode), so it is questionable whether this patch can be used :(
Maybe you can continue on the branch?
User avatar
Tim Blokdijk
Posts: 1242
Joined: 29 May 2005, 11:18

Post by Tim Blokdijk »

Oohh, and we need net code improvements so badly.. and then we get people doing double work on it. Please pick this up with Tobi! I'm sure you can find a way to work out/on this together. :-)

But still great that you decided to dig into the codebase to improve the netcode!
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Tobis new netcode wont eb in the enxt release so untill then maybe this patch can be applied?
Auswaschbar
Spring Developer
Posts: 1254
Joined: 24 Jun 2007, 08:34

Post by Auswaschbar »

I have a general question:
Why does spring use UDP :roll: ? Since spring needs reliable and in-order packages wouldn't it be usefull to use TCP?
As far as I understand, spring implements:
1. acknowledgement of recieved packets
2. resent of unacknowledged packets
3. head-of-line-blocking
4. packet ordering
This is everything TCP does, implemented on UDP.

Doesn't this mean:
1. doubled header size (both UDP and spring-protocol)
2. more bugs than TCP
3. same performance as TCP (or even worse)

Feel free to flame me if Im telling stupid things, but I think it's worth a discussion...
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Post by imbaczek »

One reason I can think of is firewall hole punching, that wouldn't work with TCP. (Or am I wrong?)
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

TCP would make NAT much easier iirc.

And any half decent firewall handles both udp and tcp.

btw holepunching is for routers+NAT not firewalls. Indeed TCP would make holepunching not work because holepunching would no longer be needed.
User avatar
Licho
Zero-K Developer
Posts: 3803
Joined: 19 May 2006, 19:13

Post by Licho »

All games where you need low latency are using UDP.
All action games are using UDP.

With UDP you have lowest possible latancy and single packet drop doesnt decrease your bandwidth (as TCP does when it detects delays or packet loss).

Simply put, with UDP you have more control over resources and can achieve lowest possible latancy without slowdowns and variable transfer rate of TCP.

Regarding TCP and holepunching AF, you have it comletely wrong :)
Hole punching is basically impossible with TCP unless you have root priviliges and can access raw socket to send pakcet manually.

Hole punching is made for people with closed ports (no port forwarding), it allows them to host without changing settings!
No commercial game allows that AFAIK! For all of them you have to open/forward port.

Hole punching works by sending UDP packets from host to client thus fooling NAT into thinking that its outbound connection and when real UDP packets arrive from client to host it lets them through.

This way both client and host can be behind NAT/firewall with no open port and host hole punches way for client packets to come in.

For TCP hosting to work host would be required to have port opened/forward (no hole punching possible, because there is no easy way to fool NAT in the case of TCP).
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

Licho, UDP having full bandwidth with packet loss won't help Spring since Spring cannot survive a dropped packet (try issuing a build order on 100s of buildings and see the connection loss, that's from ONE packet getting dropped). Spring needs reliability more than speed.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Licho, holepunchign works bys ending UDP packets to a UDP server at regular intervals so that the router keeps an open path on that port. As soon as spring starts the lobby stops sending packets and resumes once spring closes.

Its my understanding that TCP would defeat this otherwise browsers wouldnt be able to use 2 way communication, and we'd need port forwarding to connect to the lobby.

And no, spring implements delayed packet and packet lost resend stuff, so switching to TCP wouldnt give us anything we dont already have functionally from that perspective, it would just make NAT easier, and reduce the amount of data sent, aswell as being more reliable bugwise.

In an fps it might not make a difference if 1 in a thousand packets arent recieved, but in spring that means a desync or a crash.
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Post by imbaczek »

AF: hole punching doesn't work like that. It works, because UDP is a connectionless protocol and firewalls can't be as strict as they are with TCP. TCP does not allow two NATed hosts to connect to each other without a third party in the middle doing two-way forwarding. UDP allows you to do that by the server tricking the firewall into thinking it is a client when it's not.
User avatar
Licho
Zero-K Developer
Posts: 3803
Joined: 19 May 2006, 19:13

Post by Licho »

AF you are just completely wrong on UDP/TCP NAT holepunching stuff..
Please read more about before posting nonsense.

The problem with both UDP and TCP is that host behind NAT/firewall wont accept incoming connection unless port is forwarded/opened!

But if hosts send some data to the client first, NAT/firewall then forwards/allows data coming back from that client to host.


Hole punching works by HOST sending fake packets to CLIENT to trick NAT into thinking its outgoing and not incoming connection! Thos fake packets rarely arrive to the client (if the client is behind nat/firewall, most are). When real packets come from client to host it then accepts/forwards them to right place.

You cannot do that easilly with TCP. If you initiate conneciton from client to host, NAT/firewall will simply refuse that.
And you cannot do the hole punching stuff with tcp from HOST to CLIENT because that would require client to have opened ports. You woudln't be able to establish conneciton in either direction with both hosts behind NAT.

Thats why for example hamachi or skype are using UDP and not TCP.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

What I said on holepunching wasnt taken from an imaginary well in looloo land it was taken from betalords documentation on how holepunching works and is implemented in tasclient.

tasclient sends udp packet to the server. This opens a channel through the router forwarding all packets from client to server.

The server looks at the port it was sent on to determine where everyone else should send their packets for that client and sends it out via lobby protocol.

Because this 'channel' times out, and the timeout varies widely between different routers and modems, the lobby repeatedly sends the packet at set intervals.

When spring starts this process stops. If it were to continue then spring would be unable to bind its socket and send its own UDP data. Springs own traffic will keep the 'channel' open during this process.

Once spring has ended the lobby resumes regular interval UDP packet sending.

TCP could help though. Here is an example
Client A is behind a router or some other form of NAT.
B is a server directly connected to the internet.
A connects directly to B using UDP
B attempts todo the same to respond
Router recieves UDP packets directed at itself and finds no use for them and theyre discarded. Holepunching or forwarding required.
A gets count down of doom
A behind router connects to B using TCP.
B accepts connection and game continues.
That is what I meant by TCP making holepunching obsolete. However you've forgotten that scenario and jumped to the worst case possible scenario where B is the server and B is behind a router. In which case you're correct because then you have the original problem. For which the solutions are UDP holepunching, UPnP, or TCP/UDP port forwarding.

I am not delusional, and I do know what I am talking about. I'm not some 10yr old AI programmer who got out of bed one morning and declared "Eureka! I know all there is to know about networking!! HAHA!!!", although that would have been nice.

With tobis new netcode both TCP or UDP options would be possible. This patch adds that too by seperating ti out into a CConnection style class.
Auswaschbar wrote:As far as I understand, spring implements:
1. acknowledgement of recieved packets
2. resent of unacknowledged packets
3. head-of-line-blocking
4. packet ordering
This is everything TCP does, implemented on UDP.

Doesn't this mean:
1. doubled header size (both UDP and spring-protocol)
2. more bugs than TCP
3. same performance as TCP (or even worse)
Auswaschbar
Spring Developer
Posts: 1254
Joined: 24 Jun 2007, 08:34

Post by Auswaschbar »

I've added some statistic functions to CConnection, the result after 6 Minutes of playing Nanoblobls (random enemies)(from server view):

Network statistics for 127.0.0.1
Bytes send: 173593 (Overhead: 66969)
Bytes recieved: 117927 (Overhead: 52807)

This means: 28 % of the traffic is protocol overhead
User avatar
Licho
Zero-K Developer
Posts: 3803
Joined: 19 May 2006, 19:13

Post by Licho »

Your description is more or less correct AF, but you forget one thing! Before game starts, host (tas client on host) sends UDP packet to all clients (or at least it should do it). To fool NAT into thinking that those packets incoming from all those clients are just responses to outgoing connection.

The first step is you described (sending packet to lobby server udp service) is just to determine public port (this serves as actual "hosting" port for other clients), but that's not the hole punching itself. Its not sufficient to make whole hosting behind NAT work.

Whole point of hole punching is to allow to host behind NAT/closed firewall.
With TCP there is no easy way to make that work!
Yeah you can try upnp but thats basically port opening/enabling port forwarding and you can do that for UDP too. But you cannot do hole punching with TCP that way.

With TCP selected as hosting protoco, hosts behind NAT/firewall would be screwed.
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

Could we devise a new method of TCP holepunching?
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

do we need to?
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

jcnossen wrote:do we need to?
Well, if the overhead on UDP is that high, couldn't hurt to ask.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

TCP has more overhead too, 20 bytes instead of 8. And according to licho:
With UDP you have lowest possible latancy and single packet drop doesnt decrease your bandwidth (as TCP does when it detects delays or packet loss).
So TCP really doesn't fix anything or improve anything, except for some code simplification.
Post Reply

Return to “Engine”