Search Unity

Configurations for networking test

Discussion in 'Multiplayer' started by Matt_RKLS, Jan 23, 2008.

  1. Matt_RKLS

    Matt_RKLS

    Joined:
    Sep 8, 2007
    Posts:
    94
    Hello all,

    I'm setting up a simple "Hello World" type test for Unity networking today on our web server. I have searched the docs to find any potential roadblocks in advance, but I wanted to shoot a quick post to see if anyone has anyone has used the following setup for a successful connection and to see if there are any pointers you may have for me:

    I basically have a static IP that is filtered through a SonicWall 1260 and currently allows HTTP and FTP traffic to the web server. My goal is to take the 3rd Person Networking example and run it as direct connect server on the web server.

    I have read a few posts concerning the UDP protocol as well, will I need to allow UDP traffic to the box? When the demo is launched and calls Network.initializeServer() is it listening for UDP or TCP traffic, or both?

    The web server is running Windows Server 2003 SP2.

    Any insight would be much appreciated :D

    Thanks in advance, Matt
     
  2. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    The only thing I know you need to be careful with: If you're accessing your Webserver via Remote Desktop with the Mac RD-Client, it might behave "unexpectedly" when you start the game. Basically, to me, the RDC on Mac becomes unusable as soon as I open the game on the server (even though I have all cameras and GUI stuff deactivated on the server build).

    However, when you're using the Windows RDC, this is no problem...

    If you have direct access to the machine, you don't need to worry about this at all ;-) If you rely on a Mac Remote Desktop Client for accessing the server, and have no Windows machine at hand, you might run into unpleasent trouble, though...


    AFAIK, Unity networking is completely UDP based, but don't quote me on that. However, I have my firewall set up to block all TCP traffic, and the Game server works without any obvious issues.

    Enjoy!

    Jashan
     
  3. Matt_RKLS

    Matt_RKLS

    Joined:
    Sep 8, 2007
    Posts:
    94
    Hey Jashan,

    I do have local access to the server, so no issues there, but thanks for the heads up! I was able to set up the port access without issue on SonicWall for UDP and connected several of us here at the office to the 3rd Person demo. There were a few noticeable lags in performance, but I imagine that mainly has to do with with the traffic being routed out and back in as well as our somewhat limited up/down bandwidth and no client predictive methods in place yet... all in all, I'll call it a success :) .

    Once we got that working I started on a "Hello World" from scratch and was able to connect with the standard network.connect call, but as soon as I tried to add in the incomingPassword argument I could not connect due to a "RSAPublicKeyMismatch". I double checked the argument and the incomingPassword value on the server app... they were identical. It looked pretty straight forward in the docs, am I missing something?

    Thanks,
    Matt
     
  4. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Cool, congratz!

    Concerning the password, I unfortunately can't help as I haven't played around with this myself... Does using a password mean all the network traffic will be encrypted? I think that would be pretty cool ;-)

    Jashan
     
  5. Matt_RKLS

    Matt_RKLS

    Joined:
    Sep 8, 2007
    Posts:
    94
    Network.incomingPassword
    Scripting > Runtime Classes > Network

    static var incomingPassword : string
    Description
    Set the password for the server (for incoming connections).

    This must be matched in the Network.Connect routine on the clients. Pass "" to specify no password (this is default).

    function ConnectToServer () {
    Network.Connect("127.0.0.1", 25000, "HolyMoly");
    }

    function LaunchServer () {
    Network.incomingPassword = "HolyMoly";
    Network.InitializeServer(32, 25000);
    }

    -- This is all I can find in the scripting reference... I'm assuming there is an internal process that checks the argument sent from the client against the string defined in the member variable on the server. The only other reference I could find to security and encryption was:

    Network.InitializeSecurity
    Scripting > Runtime Classes > Network

    static function InitializeSecurity () : void
    Description
    Initializes security layer.

    You need to call this function on the server before calling Network.InitializeServer. Don't call this function on the client.

    Once your online game reaches a certain popularity people will try to cheat. You will need to account for this both at the game layer and at the network layer. Unity handles the network layer by providing secure connections if you wish to use them.

    Uses AES encryption. Prevents unauthorized reads and blocks replay attacks
    Adds CRCs so that data tampering can be detected.
    Uses randomized, encrypted SYNCookies to prevent unauthorized logins.
    Uses RSA encryption to protect the AES key.
    Most games will want to use secure connections. However, they add up to 15 bytes per packet and take time to compute so you may wish to limit usage to deployed games only.

    function Start ()
    {
    Network.InitializeSecurity();
    Network.InitializeServer(32, 25000);
    }


    -- So it looks like you can encrypt every packet with the expense of a few bytes/per... but I'm not sure if that all is taken care of automatically when you call this method?

    MJ
     
  6. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Hi Matt,

    thanks, that's cool information. I had been thinking a while about message encryption but haven't looked into the details of what Unity provides here, yet.

    I think it's a good start, but not ideal in the long run to only be able to either encrypt everything, or nothing. Reason is exactly the performance-hit we get by encryption.

    In my opinion, the "ideal approach" is to have most stuff that comes in "masses" unencrypted, but do some of the "rare, but important" messages encrypted. That way, someone trying to tamper with the network might think "ah, that's easy", but for "some weird reason" the tampering won't work because the server checks with the encrypted messages. At the same time, the maximum performance and minimum bandwidth is kept...

    Possibly, this could be solved by being able to switch encryption on/off for certain "channels", the most "natural" probably being the "group". More control, however, would be provided by doing it per RPC-call name.

    Implementing it that way would be cool, because it wouldn't require any breaking API changes. It would be simply the addition of one or two new methods. Obviously, these would have to be called before Network.Initialize(), too.

    Could be something like:

    Code (csharp):
    1.  
    2. // true = user defined security
    3. // default would be false, i.e. "everything encrypted"
    4. Network.InitializeSecurity(true);
    5. Network.AddSecureRPC("MySecretRPCMethodName");
    6. Network.AddSecureGroup(23); // 23 is my secret group channel ;-)
    7. Network.InitializeServer(300, 25000);
    8.  
    I would assume the RPC-method names are internally encoded to numbers, aren't they? Having this mode of encryption would obviously require transmitting the method names and groups unencrypted...

    :)

    Jashan
     
  7. Matt_RKLS

    Matt_RKLS

    Joined:
    Sep 8, 2007
    Posts:
    94
    That sounds like good logic on the encryption approach, Jashan :).

    I noticed another area that I need to address when testing the "Hello World" further last night...

    When the server application window is active, I can connect from the remote client with no problem, but when the window is minimized... or I log off the web server the client cannot connect. Does Unity stop listening for incoming connections on the specified ports when it is not the active window?

    If so, does anyone know of a way to convert the server component into a system tray type of application that is always on and listening?

    Cheers :)

    Matt
     
  8. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Hi Matt,

    that is fortunately very easy... at least one part of it: You simply need to do Edit / Project Settings / Player, find "Run In Background" and check it for the server.

    As I'm using the same project for client and server (which I think is probably the most usual case), I have a few checks on that in my code, too:

    Code (csharp):
    1.  
    2. void Update() {
    3.    GameData.Instance.IsNetworkActive = Network.isClient || Network.isServer;
    4.    if (GameData.Instance.IsNetworkActive || GameData.Instance.IsStandaloneServer) {
    5.       Application.runInBackground = true;
    6.    }
    7. }
    8.  
    GameData.Instance.IsStandaloneServer is a "property" (well, call this "Unity property" ;-) ) that I can check on my NetworkManager. I'm using this for all code-path-alternatives. When I do a server build, that's the most important "setting" I have to make.

    I think someone has also created a way of "tuning down" the client when it's not active. I think that's a really good idea, too...

    The second part of this is currently not so cool: You can't log off from your server because that will shut down the game! You can only disconnect (using the Remote Desktop Client). The way Unity games are currently built for Windows, this difference is important to understand:

    When you log off, all applications started in your session will be closed. Not good for Unity game servers, as they currently are only available as applications. When you just "disconnect", however, any applications keep on running. Just make sure no one accidentally logs into your session and then logs off, or reboots the server etc. etc.

    This currently makes Unity game servers hosted on Windows servers a rather fragile thing.

    I've tried putting a Unity game into a service wrapper (Firedaemon), but that just made the Unity game crash. That surprised me because even VMWares seem to run in this wrapper, but on the other hand, VMWare hardly supports directX/openGL which Unity relies upon. Search for "headless" on the forums and you'll find some discussions on this...

    I filed the "crash when running as deamon" as a bug, which was closed... not sure if that was because UT feels that's not relevant (or "by design") or whether it really got fixed... I guess I'll just give it another try ;-)

    Jashan