Author Topic: Improving Netfix  (Read 5317 times)

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« on: October 29, 2011, 04:15:52 PM »
The new NetFix has been around for 3 years now, but 2 years ago Hooman stopped its development, leaving it in an unfinish, buggy state. Read the history here: http://forum.outpost2.net/index.php?showtopic=4157

The NetFix that Hooman gave us, although it did mostly work, wouldn't allow a few people to join games, would allow hosting only with portforwarding and could crash the game after some time of playing.

I am willing to fix all those bugs.

So far I created a new version of NetFix with 2 bugs (hopefully) removed:
1. it will no longer change ports if it receives packages which don't have the netid of any player - this could be related to the game crashing after a few minutes of playing
2. the host will only answer to the first join request (of 3). This should prevent NetFix from creating incorrect players lists.

The first fix was simple: I added a check whether the peerInfo struct contains the same net id that points to it.

The second fix required me to change the protocol:

I created a new JoinRequest2 struct that contains an extra field "GUID localId". That is only used while joining a game: for all JoinRequests sent as a result of the same button press the same GUID is sent. The host will recognize when a GUID is received twice and discard the second and third.

I will post the dll and its source when its the right time for that.

Now, before I'm spreading the modified NetFix, I'd like to hear some opinions (especially from Hooman). 1. is it ok if I take over development of netfix? 2. will it be included in the new Outpost2 release?

And even more important: It seems that some features, such as the JoinHelpRequest, are currently incomplete. I cannot change them without access to the server. What do we do about this?

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #1 on: October 30, 2011, 06:58:55 AM »
I think either BlackBox or I would want to review any code changes (in source code format) before incorporating an update into the game download package. We both tend to be concerned about security, especially with network related code. We would also probably want to have some idea of the quality of the code. In the case of NetFix, I would almost certainly want to go over the code.

I'm not particularly against other people working on the client code. The source is in Git, so other people can make contributions to the project. I would like to follow those changes though. I would also prefer a model were changes are applied to a common project, rather than generating possibly incompatible or confusing forks. That's not to say I won't tolerate forks or alternative downloads, and I can certainly expect some degree of that to happen while changes are being tested. I would just like some effort put into incorporating those changes back into the original project. In other words, I will understand if you post a binary for other people to download and help you test a change. I would simply hope that you commit the source code for that change back to the project once you have it worked out.


The server code is still not published for all to see. I've thought about doing it a number of times, but there are a few sticking points I've wanted to deal with before doing so. A few select people do have copies of the source though.


Also, I am willing to work on this a little, provided I get good bug reports or clear and detailed feature requests. I think the only actionable bug reports I've gotten in the last 2 years have been the recent ones from TH300. I certainly appreciate the effort too. A good description of what went wrong, along with the log file, and a description of what appears to be strange in the log file is very helpful. A few people have brought up problems before, but I usually only ever heard about it a couple weeks after it actually happened, when the details are just a vague memory, and the log files are long gone. It's a little hard to work with that. I suppose a few people did occasionally send me logs, but I'm afraid the logs I saw didn't indicate to me a clear problem, or at the very least a clear cause. Granted, the log files tend to be somewhat hard to read, even for me.


As for your changes to prevent multiple joins, what about check if a joining player already has an address match in the player list? (Both IP and port, since people behind the same router can have the same IP but will have different ports). That would eliminate the need to add an extra GUID field to the packet.

I'm also wondering where you put the source net ID check. I've long considered a similar sounding check, but possibly in a different place in the code.


Also, could you elaborate on how JoinHelpRequest appears to be incomplete?
 

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #2 on: October 30, 2011, 09:42:50 AM »
I certainly don't want different, incompatible version of NetFix to spread. But if incompatibility is the only reasonable way to fix certain misbehavior, we need to get the new version to people somehow. I don't care if thats done via a new op2 download or one single official NetFix download. It should just happen sooner than later.

I can perfectly understand that you want to review the code of new versions before they are released. So I'll commit the code to the git repository.


Quote
The server code is still not published for all to see. I've thought about doing it a number of times, but there are a few sticking points I've wanted to deal with before doing so. A few select people do have copies of the source though.
An alternative would be that you or someone who has the source makes the necessary changes to it.


Quote
I suppose a few people did occasionally send me logs, but I'm afraid the logs I saw didn't indicate to me a clear problem, or at the very least a clear cause. Granted, the log files tend to be somewhat hard to read, even for me.
In some cases the log files just don't contain the information that is required to track down a problem. That is also due to most packets being generated and processed by op2 and not the netfix code. If something goes wrong that is usually when one player stops receiving packets from another player. And netfix has no code to detect this.


Quote
As for your changes to prevent multiple joins, what about check if a joining player already has an address match in the player list? (Both IP and port, since people behind the same router can have the same IP but will have different ports). That would eliminate the need to add an extra GUID field to the packet.
It can occur (and its in one of the logs I sent to you) that the external port changes while joining a game. You can't even assume that the ip stays the same, since most isps change that after 24 hours. Imo netfix should be able to recover from an ip change at any time.

Quote
I'm also wondering where you put the source net ID check. I've long considered a similar sounding check, but possibly in a different place in the code.
Its in the AddPlayer function which I extended to take the GUID as a new parameter. But I'll possibly move it out of that function to a place a few lines before AddPlayer is called.


Quote
Also, could you elaborate on how JoinHelpRequest appears to be incomplete?
Here is one that I once received:
Code: [Select]
 Source: 0
 Dest  : 0
 Size  : 24
 type  : 1
 checksum: d224111f
 commandType: 10
 payloadData: a 0 0 0 8d 81 f3 2 33 f6 b4 4b 9a 22 c9 5 cc 2a d0 7f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
It contains only the session id, no port.


As we are at it, lets investigate the thing with packets with "incorrect" net ids being received.

Recently I hosted a game and logged all those packets. Here is one (due to a mistake from me all numbers are in hex):
Code: [Select]
Packet from player 0 ((AF:2) 18.f6.12.48:de8c) received on unexpected port (de8c instead of 7919)  [PlayerNetId: 18]
 Source: 18
 Dest  : c0a288
 Size  : 4
 type  : 6d
 checksum: bd64587
 commandType: 246611992
 payloadData: 18 0 b3 e

The one that followed:
Code: [Select]
Packet from player 4 ((AF:2) 63.8c.4c.40:68e) received on unexpected port (68e instead of de8c)  [PlayerNetId: 24]
 Source: 24
 Dest  : c0a288
 Size  : 4
 type  : f8
 checksum: c95d093
 commandType: 259129368
 payloadData: 18 0 72 f

Many more packets of that kind followed and they all have a similar pattern:
  • the source id was one of 0x18, 0x24, 0x2c, 0x2d, 0x32, 0x34, 0x35, 0x37, 0x3f, with 0x24 and 0x2c being by far the most common ones.
  • type was mostly 0xf8, sometimes 0xf5 and only once 0x6d.
  • The payload size was always 4
  • First two bytes of the payload were always 0x18, 0x00
  • Third byte of payload was the same for all packets from the same ip (=player)
  • Fourth byte was growing, starting with 0xe: player 1: e, player 2: f, player 1: f, player 2: f, player 1: f, player 1: 14, player 2: 29, player 2: 2b, and so on.
Since only packages which were recognized as having the wrong source port got recorded, that info is likely incomplete. I find it a reasonable idea, though, that players are sending their current time to the host (I only ever saw the host receive such packets).

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #3 on: October 30, 2011, 07:12:35 PM »
Quote
Quote
I suppose a few people did occasionally send me logs, but I'm afraid the logs I saw didn't indicate to me a clear problem, or at the very least a clear cause. Granted, the log files tend to be somewhat hard to read, even for me.
In some cases the log files just don't contain the information that is required to track down a problem. That is also due to most packets being generated and processed by op2 and not the netfix code. If something goes wrong that is usually when one player stops receiving packets from another player. And netfix has no code to detect this.

True, it doesn't always contain needed debug information in the logs. Although, sometimes I think it does, but the information was overlooked due to readability issues. I would like to increase the logging potential for debug purposes. Another potentially useful tool that would burden users less, would be to have each client send info to the server on game join or game start that can be logged. The server already has the potential to record IP addresses and ports. It can't likely see port changes though without being told. It also probably doesn't know the player net IDs. Those extra values would certain help debugging efforts. Also, by collecting the port information in one place, the game server might be in a better position to determine who has problem routers, and what restrictions they have.

Quote
Quote

As for your changes to prevent multiple joins, what about check if a joining player already has an address match in the player list? (Both IP and port, since people behind the same router can have the same IP but will have different ports). That would eliminate the need to add an extra GUID field to the packet.
It can occur (and its in one of the logs I sent to you) that the external port changes while joining a game. You can't even assume that the ip stays the same, since most isps change that after 24 hours. Imo netfix should be able to recover from an ip change at any time.
It's quite expected that a port change will be required on game join with certain routers. A port change during play might also happen due to a router reboot.

An IP address change during play is very unlikely. When an IP address lease is close to expiring, the device holding it will issue a renew request. It will be re-assigned the same IP address with a new lease time. If it didn't get the old IP address, then you'd expect all your connections to get reset periodically, which doesn't happen in practice, and would likely break a lot of software if it did. The current game server is actually assigned it's IP address through DHCP. The lease time is about 3 days, but the IP hasn't changed in probably a couple of years now. The only time I see it change if after an extended power outage that takes out the whole neighborhood. Even small glitches of a few seconds haven't caused it to change IP address.

Also, in the context of the current problem, this is strictly about game join. If by some miracle someone's IP address changed right as they were joining..., they would have to click "Join" again? Maybe a wait a few seconds for their previous join attempt to time out and get dropped? I don't believe any of the timeouts are longer than 15 seconds, if even that.

The port tracking code does not allow for IP address modifications, only port modifications. That means that currently an IP change during gameplay will disconnect someone permanently. You could update the port tracking code, unrelated to the game join packet, to also track IP address changes, but I would recommend against this. It's of questionable value, and would be a security concern. If the IP could be auto updated that easily during game play, then someone could hijack someone else's session. I think this is of greater concern than the very unlikely possibility of someone's IP address changing during gameplay, which would probably mean their computer got reset anyway.


The packets you posted look corrupt. Where are you logging this? Do the source IP addresses correspond to other players? The "type" value should only ever be 0 or 1, and the "commandType" value should be a reasonably small integer.

Edit: Also, it's very stange that the address field of the JoinHelperPacket is zeroed out. This is set by the game server to match the client requesting the join. If it came through the game server, there should be no way this field is zero.


Is it possible you compiled the code with different struct packing alignments? The proper pragmas should exist in the code to keep it uniform. I assume you didn't do anything to change those?
 
« Last Edit: October 30, 2011, 07:15:46 PM by Hooman »

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #4 on: October 31, 2011, 09:14:41 AM »
Quote
Another potentially useful tool that would burden users less, would be to have each client send info to the server on game join or game start that can be logged. The server already has the potential to record IP addresses and ports. It can't likely see port changes though without being told. It also probably doesn't know the player net IDs. Those extra values would certain help debugging efforts. Also, by collecting the port information in one place, the game server might be in a better position to determine who has problem routers, and what restrictions they have.
Two different points here:

1. you want to send ips and ports to the game server. That may indeed help find problem routers and I think its a good idea.

2. you suggest to log everything. Thats an idea which I totally dislike, because I don't want information stored about the games that I played. If I ever find out that such information is stored, I will certainly play fewer games over the game server. Also, imagine what will happen if people use the host as game server (can be a good idea in some situations, and I did it already).

Instead of logging everything on the game server, the users should receive immediate feedback if the game server detects that something is wrong. Maybe have netfix display an error report which players can copy/paste and give to developers.

Quote
An IP address change during play is very unlikely. When an IP address lease is close to expiring, the device holding it will issue a renew request. It will be re-assigned the same IP address with a new lease time. If it didn't get the old IP address, then you'd expect all your connections to get reset periodically, which doesn't happen in practice, and would likely break a lot of software if it did.
Maybe I am living in a different world. All my connections get reset periodically (unless I switch off my computer during the reset time which I usually do). And, yea, currently I avoid playing games near the reset time.

Quote
Also, in the context of the current problem, this is strictly about game join. If by some miracle someone's IP address changed right as they were joining..., they would have to click "Join" again? Maybe a wait a few seconds for their previous join attempt to time out and get dropped? I don't believe any of the timeouts are longer than 15 seconds, if even that.
Is there a timeout for people who did already complete the join process? I.e. if their port/ip changes after they joined a game, but before its started?

Quote
The port tracking code does not allow for IP address modifications, only port modifications. That means that currently an IP change during gameplay will disconnect someone permanently. You could update the port tracking code, unrelated to the game join packet, to also track IP address changes, but I would recommend against this. It's of questionable value, and would be a security concern. If the IP could be auto updated that easily during game play, then someone could hijack someone else's session. I think this is of greater concern than the very unlikely possibility of someone's IP address changing during gameplay, which would probably mean their computer got reset anyway.
The last assumption is simply wrong. But I understand the security concerns. Still, imo ip changes should not end a game. Instead of just discarding packets from a previously unknown ip, people could be asked whether they want to accept the ip change. Maybe some sort of automatic authentication / reauthentication mechanism could be used (with auth info being newly generated for every game. I don't want to add a system where players would have to log into an account in order to play).


Quote
The packets you posted look corrupt. Where are you logging this? Do the source IP addresses correspond to other players? The "type" value should only ever be 0 or 1, and the "commandType" value should be a reasonably small integer.
I logged them as a host of a 3 player game. I suspect that I also got them as the host of a 5 player game. Logs from other players show that they didn't get those packets. So, they're probably only sent to the host. Furthermore, I never saw such packets in a 2 player game.

I assume, its some way to synchronize time.

Quote
Edit: Also, it's very stange that the address field of the JoinHelperPacket is zeroed out. This is set by the game server to match the client requesting the join. If it came through the game server, there should be no way this field is zero.
NetFix doesn't generate JoinHelpRequests. Outpost2 doesn't generate JoinHelpRequests. Whats left?


Quote
Is it possible you compiled the code with different struct packing alignments? The proper pragmas should exist in the code to keep it uniform. I assume you didn't do anything to change those?
The assumption is correct. I didn't modify the forced exports code at all (except a few includes, maybe). And if alignment was really wrong, other packets would be broken, too.


Edit: Let me elaborate a bit on the ideas that I have about the future of NetFix.

I am currently seeing that people are using Hamachi, even if NetFix works for them. The most prominent argument is probably that people can reconnect to a Hamachi virtual network after they got disconnceted whereas they can't  currently reconnect to a netfix-op2 game after they got disconncted. Hence, if NetFix shall replace Hamachi, it must provide all possible means to reconnect players, also after an ip change.

NetFix shall replace Hamachi, because Hamachi is not under the control of opu and likely a security risk. If, some day, Hamachi is no longer available, people will have no way to play.
« Last Edit: October 31, 2011, 09:26:49 AM by TH300 »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #5 on: November 01, 2011, 03:38:34 AM »
I wouldn't suggest sending everything. I'd prefer to keep the protocol as light as possible in terms of bandwidth requirements. If the information isn't strictly needed to support network operation, then I'd like to keep it out of the protocol. I'd also like to not waste disk space by actually recording available information.

My comment was more a thought that proper logs might help development, as would a slight increase in information, mostly concerning external port mappings, and possibly player network IDs. The later is not strictly needed to implement any useful features, but might be interesting to debug current apparent problems. I don't believe the player net ID is of a particularly sensitive nature. It essentially consists of the generation time (time since Windows was last booted), and the player's index in the player table. Neither is a permanent identifier for a player, and should change for each game played. Essentially I'm suggesting collecting a global view of the connection state to better understand the connection problems (and possibly the mapping of temporary player IDs to connections). What makes current development so difficult is only being able to see the connections from one point of view (which will different from other points of view for the problem cases that need debugging).

To auto-detect certain router issues, you'd need to be aware of certain external port changes. These results would need to be compared from two different external sources. The game server is one possible external source, but another one would be needed for auto-detection. I had previously thought two game servers working together might work for an enhanced mode that can warn of router problems. This would allow those properties to be determined on connect, even before a game is even hosted. However, I would prefer not having to run two game servers on two seperate boxes if possible, and I definately don't want to think about keeping game lists synched between two of them, or modifying one to be a custom non-full game server. Another alternative is somehow using the port information from connecting peers. The current problem is that a peer only knows how it sees other peers. There is no global view of the port mappings, nor is any given peer aware of it's external port mappings to other players. It's also worth noting that such a scheme would only work once players start connecting to each other, after a game has been hosted.

I think the solution I might like the best, is if each peer informed each other what it sees of that person. There would be no global view in this case, but each peer should learn enough about itself to determine if it's behind a problem router. It would require more packets to be exchanged than if the information was collected in a central place, although, the packets would be slightly smaller. It also negates any privacy concerns since a client would only be learning about itself using information already available to other clients. This doesn't create for an easy debugging/development environment though, and if something goes wrong it will require each player to submit whatever logs are generated on their computer to diagnose the problem.


Quote
Is there a timeout for people who did already complete the join process? I.e. if their port/ip changes after they joined a game, but before its started?
I believe so, but I don't quite remember anymore. I think a player who stops responding will get dropped. I vaguely remember this happening while debugging when one client was stopped at a breakpoint.


I would also like to avoid pestering the user with dialog boxes concerning IP changes (and mostly avoid having to write such code). I also don't want to add account login requirements. If anything, maybe share a randomly generated pairwise unique value between peers for this purpose, and do the switchover automatically if the secret is known. You'd want the number to be random to prevent abuse by anyone on the internet. You'd want the pairwise uniqueness property to prevent other players from that game from abusing otherwise shared information.


I'm still perplexed by the packets you say you've recorded. If you find anything else out about them I'd like to know. It looks like a possible bug to me. I don't think they are actually valid packets.


The JoinHelpRequest is not sent by either Outpost 2, nor the NetFix client. It's sent by the NetFix server. The client only sends JoinRequest packets. Essentially, the JoinHelpRequest is a third party join introduction. It was needed to support routers that filter out traffic from hosts it has not sent data to. This would normally be a problem for a game host. In this case, the join request is routed through the game server. This traffic should get through because the host sent data to the game server about the hosted game, and so a reverse mapping now exists in the router's table allowing the game server to send data back to the game host. The game server transforms the JoinRequest packet from the client that wants to connect into a JoinHelpRequest packet so the host knows it's not the game server trying to join, but rather is being informed of some third party that wants to join. To ensure this third party can connect, the host will then send an empty packet to the client trying to connect, thereby creating a reverse mapping in the host's router table. The empty packet will simply be discarded by the connecting client as invalid/not-of-interest. However, subsequent JoinRequest packets (such as those sent after a short timeout) should now make it to the host through the newly formed reverse mapping. Hence, even somewhat problematic routers should be able to host games, with a possible slight delay in initial connections.

Now I did make one simplification in the protocol. Partly out of laziness and wanting to keep the code simple, but also to avoid unnecessary delay. When a client tries to join a game, it sends a packet to both the game server (if an address is set), and to the game host, in that order. Strictly speaking, this is a bit wasteful, and tells the game server more than it needs to know in most cases. The game server only needs to relay the packet for hosts whose routers filter packets from unknown addresses. However, this is no way to know this ahead of time. I suppose you can assume if the first JoinRequest goes unanswered that the join packet was dropped, and this is likely because the host's router filtered the packet, and so try routing through the game server on subsequent attempts, but this introduces more delay when this feature is needed and still might inform the game server more often than needed due to random dropped packets. So, in short, the game server can potentially track which games you've joined, if it so desired. Not strictly needed in all cases, but I did hear about problems less frequently after this was implemented. I don't believe there is a foolproof way of only sending this help request when strictly needed, so instead I've chosen to minimize delay when it is needed.
 

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #6 on: November 01, 2011, 05:43:34 PM »
Quote
I wouldn't suggest sending everything. I'd prefer to keep the protocol as light as possible in terms of bandwidth requirements. If the information isn't strictly needed to support network operation, then I'd like to keep it out of the protocol. I'd also like to not waste disk space by actually recording available information.
Are you referring to my game server logging concerns?

Quote
My comment was more a thought that proper logs might help development, as would a slight increase in information, mostly concerning external port mappings, and possibly player network IDs. The later is not strictly needed to implement any useful features, but might be interesting to debug current apparent problems. I don't believe the player net ID is of a particularly sensitive nature. It essentially consists of the generation time (time since Windows was last booted), and the player's index in the player table. Neither is a permanent identifier for a player, and should change for each game played. Essentially I'm suggesting collecting a global view of the connection state to better understand the connection problems (and possibly the mapping of temporary player IDs to connections). What makes current development so difficult is only being able to see the connections from one point of view (which will different from other points of view for the problem cases that need debugging).
The net id is not critical information in my eyes. IP address (and maybe port) are, though.

Quote
To auto-detect certain router issues, you'd need to be aware of certain external port changes. These results would need to be compared from two different external sources. The game server is one possible external source, but another one would be needed for auto-detection. I had previously thought two game servers working together might work for an enhanced mode that can warn of router problems. This would allow those properties to be determined on connect, even before a game is even hosted. However, I would prefer not having to run two game servers on two seperate boxes if possible, and I definately don't want to think about keeping game lists synched between two of them, or modifying one to be a custom non-full game server. Another alternative is somehow using the port information from connecting peers. The current problem is that a peer only knows how it sees other peers. There is no global view of the port mappings, nor is any given peer aware of it's external port mappings to other players. It's also worth noting that such a scheme would only work once players start connecting to each other, after a game has been hosted.
The global view on all port mappings that you're mentioning is what is needed, in my eyes. It would allow players to detect issues without the help of the game server.

Quote
I think the solution I might like the best, is if each peer informed each other what it sees of that person. There would be no global view in this case, but each peer should learn enough about itself to determine if it's behind a problem router. It would require more packets to be exchanged than if the information was collected in a central place, although, the packets would be slightly smaller. It also negates any privacy concerns since a client would only be learning about itself using information already available to other clients.
Thats also a good suggestion.

Quote
This doesn't create for an easy debugging/development environment though, and if something goes wrong it will require each player to submit whatever logs are generated on their computer to diagnose the problem.
Thats why a global view would be better.

Of course some info wouldn't be in the global view (such as lan ips which are used only inside a home network). (I have been thinking about a way to let people behind the same router play games together with people over the internet. Currently, this will at least fail for me, because I don't seem to receive packets which I send to my external ip. So, lan ips must be used)

And, in order to keep the amount of transferred data minimal, info about ips and ports should only be transferred if those change.

Optionally, only the host could receive data about the global view. It would then be enough for debugging, if the host logs are preserved.


Quote
Quote
Is there a timeout for people who did already complete the join process? I.e. if their port/ip changes after they joined a game, but before its started?
I believe so, but I don't quite remember anymore. I think a player who stops responding will get dropped. I vaguely remember this happening while debugging when one client was stopped at a breakpoint.
If there is a timeout, it effects only the pre game setup window. And that doesn't help us, since we want a timed out player to vanish from the peerInfo array.


Quote
I would also like to avoid pestering the user with dialog boxes concerning IP changes (and mostly avoid having to write such code).
The boxes wouldn't appear too often, so you can't talk about pestering. For the case that someone attempts to hack into a game, there could be an option to ignore subsequent ip changes. If you don't want to code that thing, I'd be willing to do that. But maybe we find an alternative, anyways.

Quote
I also don't want to add account login requirements. If anything, maybe share a randomly generated pairwise unique value between peers for this purpose, and do the switchover automatically if the secret is known. You'd want the number to be random to prevent abuse by anyone on the internet. You'd want the pairwise uniqueness property to prevent other players from that game from abusing otherwise shared information.
Diffie-Hellman key exchange could do that. But in my eyes a public-/private key system would be better suited. RSA with ridiculously small key lengths will probably be good enough. It could then work as follows:

1. player A and player B start a game. Public keys are exchanged.

2. player A's IP changes.

3. player B detects this and asks player A to authenticate.

4. in order to auth' player A encrypts a message given by player B with his private key and sends the encrypted message to player B. Player B decrypts it with A's public key

5. if the original message and the decrypted message match, accept the ip change.


Quote
I'm still perplexed by the packets you say you've recorded. If you find anything else out about them I'd like to know. It looks like a possible bug to me. I don't think they are actually valid packets.
Will do.


Quote
So, in short, the game server can potentially track which games you've joined, if it so desired. Not strictly needed in all cases, but I did hear about problems less frequently after this was implemented. I don't believe there is a foolproof way of only sending this help request when strictly needed, so instead I've chosen to minimize delay when it is needed.
I do agree that the help request should always be sent. Doesn't mean it has to be logged.

But that was not my point on the join help requests. As I said, they currently don't contain the joiners port and ip. That makes it impossible to send anything to the joining client.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #7 on: November 03, 2011, 01:35:34 AM »
Quote
Are you referring to my game server logging concerns?
Basically yes.

Quote
The net id is not critical information in my eyes. IP address (and maybe port) are, though.
You're quite right. But you've also posted results that suggest there is a problem with the player net IDs. Hence, debug information concerning them would be of immediate use to solving this particular problem. There is no long term use to keep track of that though, and I would prefer not needing to pass it around once the problem is solved, or ever if the bug is tracked down first. The IP and port information would be of lasting value to the protocol though for router property detection.

Quote
The global view on all port mappings that you're mentioning is what is needed, in my eyes. It would allow players to detect issues without the help of the game server.
I like how you ended that "without the help of the game server". That is a particularly relevant comment, since the NetFix is designed to be usable without a functioning game server. Just enter the IP of the host you want to join, like the usual TCP/IP game setup. In that case, using peers to detect router properties, without needing a game server would be of value.

Do you think router problems should be announced to:
1) only the person with the problem router
2) the person with the problem router and the game host
3) all people who were trying to start the game

Currently I'm leaning towards a solution that would make only #1 possible. A slight modification should make either #1 or #2 possible. Does anyone else have any thoughts on this? Is this a privacy concern for people?


As for the connection info gathering, it would only be external addresses. There is no relevance to transmitting internal addresses. I would also consider that to be disclosing potentially sensitive LAN security information. This shouldn't compromise a LAN with proper security, but I'm concerned that many people won't have proper security measures in place, so I'd prefer not to end up leaking something like this just in case.

Being able to send and receive packets internally to the LAN using your external IP is controlled by a router property which I believe was known as "hairpinning". Most routers these days seem to support it, but it was a property that came up as a potential problem. If you have a router that doesn't support this, than you can likely only have one person behind the router play against people outside of your network.

You can potentially get around the lack of hairpinning limitation by routing all messages through one player, but that creates complications if that player is killed earlier or dropped from the game. This is an issue I'd rather not deal with at present, but one I like to keep in the back of my mind.


Info about IPs and ports would always have to be sent because nobody but the routers would know about the change. The only way to detect a port change, is by being told by someone else what your external port appeared to be to them. You can know what port you sent it on, but you can't know what port they received it from, since the router can translate it.


Quote
If there is a timeout, it effects only the pre game setup window. And that doesn't help us, since we want a timed out player to vanish from the peerInfo array.
I'm not too sure what you're getting at here. I believe they are dropped from the peerInfo array if they timeout during game setup. After game start, it's handled by the drop player dialog.


As for the IP change tracking, I was thinking just a random 32-bit int would suffice. I figure for what is being secured, something like Diffie-Hellman is overkill. The rest of the protocol isn't secured, so there's not much point in securing this part. If they really wanted to cause trouble, and had the ability to intercept packets, there are many worse ways they could intervene.


The JoinHelpRequest packet stuff seems odd to me. I'm wondering if perhaps security software is stripping out those values or something? I remember testing and getting good values there. But, perhaps I'm overlooking some case.

 

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #8 on: November 04, 2011, 03:24:49 AM »
I've done a bit of digging, and I suspect those game packets with weird field values are being sent from the Outpost 2 multiplayer pre-game setup window. This is actual Outpost 2 code, and not NetFix code. I believe this to be the case as I've added logging of packets sent from NetFix, and it doesn't account for all of the traffic. The game window needs to stay up-to-date with which players have joined, and what the color and handicap settings are. This isn't part of the custom NetFix protocol. It's just standard traffic passed over the new network layer code. Took me a while to remember how this worked though. =(

I've also played around with sourcePlayerNetID checking. I've added debug messages if the sourcePlayerNetID is not 0, and it corresponds to an entry in the peerInfo array which is also not 0, and doesn't match. During initial game join, you can expect the client to not know the host's player id, so you want to avoid generating an error message in this case.

I also noticed what appears to be an oddity in the code for game joining, but my attempt to fix it has broken game join. It looks like source and dest player net IDs are swapped. Maybe it was correct after all, but I feel it needs further study.
 

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #9 on: November 07, 2011, 01:47:24 AM »
I've played with the code a bit more. The oddity that I noticed does appear to be swapped source and dest player net ID values. The destPlayerNetID value is ignored. The sourcePlayerNetID causes the join to hang if it's non-zero. I'm not sure why at the moment. The code was previously setting the source to 0, and the dest to the host's ID, but the packet was generated by the host and sent to the joining client. I've changed the dest to the new player's net ID without problem. Setting the host net ID causes the hang. The join packet is received and processed successfully, but some later code is causing it to fail. The reason is likely buried in the code behind the pre-game setup screen. I have yet to track down the cause, but meanwhile, I'll leave the host ID set to 0, as this appears to work.


I found the cause of the strange source net IDs. It seems the original OP2 code was setting this value in the network layer after the game built the packet and passed it on to the network layer to send it. The game never actually checked or used this value though. The NetFix code just sort of ignored it. Hence why you get garbage values when you tried to log it. I've added a line to set this value before sending packets and everything still works. This should cleanup logging of messages, and make the port tracking code behave less erratically.
 

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #10 on: November 08, 2011, 12:38:12 PM »
Quote
Do you think router problems should be announced to:
1) only the person with the problem router
2) the person with the problem router and the game host
3) all people who were trying to start the game

Currently I'm leaning towards a solution that would make only #1 possible. A slight modification should make either #1 or #2 possible. Does anyone else have any thoughts on this? Is this a privacy concern for people?
#2 would definitely be nice, since it takes away the need to explain to the "problem player" how to get the info. #3 would be nicer, but not needed, since most of the time people are hosting who know how stuff works.


Now, when you're talking about swapped net ids, you should tell which packets you're talking about.

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Improving Netfix
« Reply #11 on: November 08, 2011, 12:45:04 PM »
I'm glad you two understand all this, because I've read through this thread several times and I'm still lost, heh
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #12 on: November 08, 2011, 03:53:10 PM »
Its unlikely that you'll understand it without looking at the NetFix source code. Even I don't understand everything, because I don't know how certain stuff is handled in op2 (which packets it sends, which packets it processes). NetFix is just part of the system. One other part is the pre game setup dialog which is a big black box for me.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #13 on: November 09, 2011, 12:27:06 AM »
It's a bit of a black box for me too. I suppose I did try to analyse and comment some of it, but mostly I just worked around that part to keep the scope of the project more reasonable.


As for the packets with the swapped net ID values,  ... I was just looking at it now to try and answer your question properly and I just noticed something very important. The packet being constructed isn't being sent from the host to the client. It's being constructed on the host to return to the calling code as if it was received over the network. I had forgotten about this faked packet. I added it to deal with some requirement of the game engine to receive such a packet, even though the NetFix protocol had been designed to work a bit differently. That would explain why the source and dest net ID fields appeared to be backwards. I guess it was right after all.

It might still be a sign of a poor design decision though. There are a few things I probably would have changed in hindsight, but I suppose that's pretty common for software projects. I think the biggest thing I would have wanted to change is the port binding code. I figure maybe just try to bind to the host port right away, but only treat it as a warning, rather than a failure, if it can't bind. If it can't bind explicitly, then you should get implicit binding, which is the current behavior. That could perhaps lessen the need for people to play with the ini file if they have a problem router. They'd just need to setup port forwarding on the router. Right now there is some trickery when switching from joining games to hosting games that isn't really needed.
 

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #14 on: November 15, 2011, 02:43:37 AM »
I'm starting to stall on this due to lack of time. Upon reviewing the changes I've been making and testing, there is only really one significant line.

Near the start of OPUNetTransportLayer::Send, I added the following code just before line 623 (of commit from 2010-7-26):
Code: [Select]
	// Set the source player net ID
packet->header.sourcePlayerNetID = playerNetID;

This may keep the port tracking code from behaving erratically. It should also help clean up some of the logging concerning bad source net IDs.


The rest of my current changes are mostly just increased logging or comment additions.


I'd commit this, but TortoiseGit has been behaving strangely and I haven't had time to sort it out yet. I'm thinking I might just end up using a command line client from Linux. Might have to refamiliarise myself with it though. I've never really used git beyond going through a simple tutorial.
 

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #15 on: November 15, 2011, 09:49:42 AM »
I'm also having a lack of time.

Nontheless, I'm going to write up a concept of how I want NetFix extended and how I think that can be achieved. I'd then appreciate your review.

As for git, I asked BlackBox to give me write permissions for the NetFix repository, but he didn't even send an answer, yet. But the code that I wrote does anyway not change too much and most of it is probably obsolete with the change that you made.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Improving Netfix
« Reply #16 on: December 08, 2011, 12:24:56 AM »
Have you made any progress on anything recently?

Has anyone used the new version I posted a couple weeks ago? Does it behave better? Is it the same? Has anyone who'se had problems with NetFix in the past tried the newer version?
 

Offline TH300

  • Hero Member
  • *****
  • Posts: 1404
    • http://op3game.net
Improving Netfix
« Reply #17 on: December 08, 2011, 05:18:03 PM »
No progress. Right now I have other stuff to worry about.

I will try the current NetFix when I get the time to actually play. But when that time has come, I'll certainly urge others to test with me.

I won't forget about it. Thats for sure.