Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux Join Bug #1

Closed
GoogleCodeExporter opened this issue Mar 16, 2015 · 14 comments
Closed

Linux Join Bug #1

GoogleCodeExporter opened this issue Mar 16, 2015 · 14 comments

Comments

@GoogleCodeExporter
Copy link

This is the annoying bug that prevented the early release of Sylverant. 
Basically, what happens is 
that when a player tries to join a game on a ship server hosted on Linux, the 
game's leader will 
essentially crash, and the player joining will partially join the game (they'll 
be staring at the column 
in the middle of the hunter's guild).

What I think is happening is that Linux' handling of the receive window for TCP 
packets essentially 
tells the party leader that it can't send the synchronization packet to the 
other client, and thus the 
freeze. I however have no idea how to change the receive window manually, and 
all that I could 
think of to try doesn't seem to work.

Original issue reported on code.google.com by bluecrab on 31 Oct 2009 at 4:12

@GoogleCodeExporter
Copy link
Author

[deleted comment]

3 similar comments
@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

Where would be a good place to start at debugging this?  Also what have you 
attempted so far and with what luck?  I'd be interested in seeing what could be 
done to help solve this issue.
Thanks

Original comment by nemesys...@gmail.com on 17 Feb 2012 at 5:07

@GoogleCodeExporter
Copy link
Author

The problem appears to be Linux's handling of the TCP receive window size. 
Essentially, Linux steps up the size gradually from a rather small starting 
point as the other side sends data. For completely two completely compliant TCP 
implementations, this would not be a problem. The sender should just send data 
up to the size of the receive window on the Linux machine, and wait for the 
Linux machine to tell it that it is ok to send more data (Linux would also 
increase the receive window at this point too, in general).

However, the implementation of TCP/IP that Sega used (at least in the Dreamcast 
versions and quite possibly also on the Gamecube versions) will not send any 
data until the receive window is large enough to send everything that it wants 
to send. I believe that at the point when the Dreamcast client was trying to 
send a synchronization packet to the other client that was joining, the Linux 
receive window was somewhere on the order of 150 bytes or something else 
ridiculously small. The synchronization packets are quite large, and thus the 
Dreamcast simply sat there waiting for the receive window to increase, which 
would never happen.

TL;DR, the bug is actually in the game itself and there's really nothing we can 
do about Linux's handling of the receive window, short of patching the kernel 
itself to remove this stepping function. Since requiring a patched kernel is a 
bit of an extreme measure for running one program, its unlikely that this will 
ever get fixed.

It would also be possible to use a proxy (hosted on an OS that doesn't exhibit 
this behavior, like FreeBSD or even Windows with Cygwin) to act as a buffer 
between the two sides, but that is a rather annoying kludge as well, and 
requires an extra server. If you're going to have a server running FreeBSD to 
act as a buffer, you might as well run Sylverant on FreeBSD to start with 
(since that's how I handle things).

Original comment by bluecrab on 17 Feb 2012 at 5:18

@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

I understand your logic. That is enough information to get it working for me at 
least because I compile my own kernel.  Though I was thinking of maybe a 
userspace program such as; 
http://linux.about.com/od/commands/l/blcmdl7_tcp.htm, specifically the third 
paragraph (ie.. SO_SNDBUF and SO_RCVBUF, also tcp_rmem further down).  Though 
not sure of the size of the Sega packet.  Good to know FreeBSD is what you use 
though, I may just use that as my personal option.

Original comment by nemesys...@gmail.com on 17 Feb 2012 at 6:34

@GoogleCodeExporter
Copy link
Author

Unfortunately, I tried every combination of things with setsockopt and the 
various sysctls that I could figure out when I initially discovered the issue. 
No combination I tried seemed to work.

Original comment by bluecrab on 17 Feb 2012 at 6:38

@GoogleCodeExporter
Copy link
Author

Not sure if it's relevant to this discussion, but I've just set up Sylverant 
here and I've not seen this bug; but, I don't have any DC/GC clients.

My server is running under Linux 3.8.0 and the clients are PSOPC running under 
Wine on both MacOSX 10.8.3 and Linux.

I actually *do* still have a working Dreamcast along with a BBA and PSOv2.  If 
you think this bug exclusive to the DC, I'll hook it all up and try it.  If it 
doesn't work, I can debug it.

bluecrab, if you have decent instructions for getting it going on the Dreamcast 
(patching it to point at my own server), I'd appreciate it if you'd email me 
that.  Also... I'd really like some pointers as to what I should supply for the 
v2maps and how they should be named :)

Original comment by wah...@gmail.com on 7 Apr 2013 at 10:52

@GoogleCodeExporter
Copy link
Author

The only version of PSO that I know for certain that this affects is PSOv1 for 
the Dreamcast. I'd suspect it probably affects every Dreamcast version, and 
possibly the Gamecube versions as well. I wouldn't expect it to affect PSOPC or 
Blue Burst.

--- The rest of this is unrelated to the bug at hand here, but is answering the 
rest of the previous poster's questions ---

As for pointing the game at a different server, the easiest thing to do (if you 
have a version that doesn't have the Hunter's License server check -- namely, 
USv1, EUv1, or EUv2) is to just set up a DNS server on your local network to 
redirect the game server to your server itself. I used to use my router's 
built-in dnsmasq setup to do this on my local network. Make sure to set your 
Dreamcast's DNS setting to point at the server on your local network too.

If you're working with a copy of the game that required a Hunter's License 
(JPv1, JPv2, USv2), then you have to patch out the HL check, then you can use 
the DNS trick mentioned above. There are CodeBreaker codes on the main 
Sylverant website to do that.

Of course, the most complete method is to use something like my PSO Patcher 
Disc. Although, that is a bit of overkill for setting up a server just for 
testing purposes for yourself.

As for v2maps, you need two files for each map mXYZ.dat and mXYZ_o.dat. X is 
the area number (one hex digit 0-E), Y is the map number (0-2), Z is the 
variation of the map (0-5). If you have a copy of PSOPC installed, you can find 
the files you'll need in the Media/PSO/SET directory from wherever the game is 
installed. Note that my naming is not the same as what the game uses, so you do 
have to rename the maps. Sega's maps have a rather annoying naming scheme which 
I frankly didn't want to deal with in the code. Here's some examples of how to 
rename things:
map_city00_00e.dat -> m000.dat
map_city00_00o.dat -> m000_o.dat
map_forest01_00e.dat -> m100.dat
map_forest01_00o.dat -> m100_o.dat
map_forest02_04e.dat -> m204.dat
map_cave01_02_01e.dat -> m321.dat
map_cave02_00_01e.dat -> m401.dat
map_boss04e.dat -> mE000.dat
... and so on.

As for what area numbers correspond to what in my scheme, 0 = city, 1 = 
forest01, 2 = forest02, 3 = cave01, 4 = cave02, 5 = cave03, 6 = machine01, 7 = 
machine02, 8 = ancient01, 9 = ancient02, A = ancient03, B = boss01, C = boss02, 
D = boss03, E = boss04.

Note that not all area-map-variation combinations are valid. The only area that 
has any variations up to 5 is forest01. Also, forest01, forest02, city, and the 
boss areas don't have any separate maps, so that digit will always be 0. 
Basically, if there's something missing in the scheme in that map directory, 
Sylverant isn't expecting it to be there when it loads up the maps. ;-)

Original comment by bluecrab on 8 Apr 2013 at 3:59

@GoogleCodeExporter
Copy link
Author

And... I made a typo there... It should be mE00.dat, not mE000.dat.

Original comment by bluecrab on 8 Apr 2013 at 4:09

@GoogleCodeExporter
Copy link
Author

Thank you very much for the details.  I will set up my DC next week(end, 
probably) to look at the Linux issue further.

Original comment by wah...@gmail.com on 11 Apr 2013 at 9:02

@GoogleCodeExporter
Copy link
Author

Not sure when or how anything here changed, but it appears this might not be a 
problem anymore. I'm able to successfully run ship_server on a Raspberry Pi 
with kernel 3.12.28 without running into this bug.

So for now, I'm closing this...

Original comment by bluecrab on 16 Dec 2014 at 8:10

  • Changed state: Verified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant