Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Unity Multiplayer Is there a built-in authentication system in UNet?

Discussion in 'Connected Games' started by Creepgin, Jul 24, 2015.

  1. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    85
    Given an IP and a port number, it seems any client can connect to the server.
    1. Is there any built-in way of doing auth in UNet right now? e.g. connect using a password.
    2. If not, is it planned for the future?
    I don't see it as built-in right now, and I'm implementing a simple auth using just custom messages. But I still wanna make sure in case I missed something.
     
  2. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    We decided do not implement this, because authentication requirements are different for different customers and it is very difficult to satisfy to everybody. Probably we are wrong and we need to add some sort of message to Connect() function.
    So client will do Connect(...., buf, buffSize); where it can send arbitrary data inside buf[].
    Server will receive connect event and this message and use (for example) this message for authentication?

    So, if it will be useful we can add this
     
  3. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    85
    Agreed! I think Connect(...., buf, buffSize); is generic enough to handle a lot of cases. And most people may just want a out-of-box simple password auth.
     
  4. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    794
    I like the idea as well. Preferably also add an overload in the highlevel api to take in a NetworkReader/Writer as the parameter.
     
  5. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    ok i added this feature to to-do list
     
  6. XaeroDegreaz

    XaeroDegreaz

    Joined:
    Feb 6, 2010
    Posts:
    12
    Has there been any movement on this? It seems kind of silly there is no simple authentication implementation available in the new API. It seems we have to roll our own authentication mechanism somehow by using network messages -- every time a user sends a message to the server we have to validate that they have already or something.
     
  7. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    yes, please. The Idea with Connect Message is very useful. Because in my system, I supposed to connect to the server, and then send a login message, and if login and pass wrong I must to disconnect this client. It's not very accurate.
     
  8. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @Wobes how urgent is it? (looks like i can support it before July if you need it faster it will require inserted in the one of the patch ...)
     
    wobes likes this.
  9. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Wow, thanks for asking. Well, it seems to be amazing feature with Connect and buff[] array, It kind a urgent but, as you wish :) Also if we could override our OnServerConnect not only with NetworkConnection parameter - will be really helpful for NetworkManager, example:
    Code (CSharp):
    1. public override void OnServerConnect(NetworkConnection conn, byte[] buf or string[] buf)
    2. {
    3.  
    4. //If buf is empty - it means that there is no data received from the client
    5. //so we can disonnect it - NetworkServer.Disconnect(conn);
    6.  
    7. //If buf contains something - it means that there is some data received from the client
    8. //so we can deserialize array of data and get some login information;
    9. //Could be serialized JSON string of login class; which contains Login and Password or anything.
    10.  
    11. //or if we don't need to use buf feature just do a normal connect procedure.
    12.  
    13. }
    But correct me if I'm wrong, LLAPI and HLAPI use the same connect procedure?
     
    Last edited: Apr 21, 2017
  10. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    Cannot promise the second one, but will try
     
    wobes likes this.
  11. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Thanks a lot!
     
  12. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Hi there, any news about that feature?
     
  13. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @Wobes :( so far no 2017.1 has been already closed for features, and only bug fixing allowed. I will try to push this with path or will leave this till 2017.2
     
    wobes likes this.
  14. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    thanks for a quick reply, I appreciate your participation in that question! ;)
     
    TwoTen likes this.
  15. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Hi there, may I ask you a question even if it's not applicable to Authentication system? I'd really like to know your opinion about that.
     
  16. TomPo

    TomPo

    Joined:
    Nov 30, 2013
    Posts:
    56
    Hi, this is still not possible to implement some authentication during connection process?
    Right now looks like everyone can connect to the server if they know IP and the Port and later server have to ask (in OnServerConnect()) please give me login and password or I will disconnect you.
    How it's even possible in 2017 ? Is like what ?
    byte[]/string[] should be inside NetworkTransport.Connect() function it's easy and so obvious, isn't it ?
    Or maybe there is some other way implemented? It must be. How it can't be in XXI century?
    Looks like 99% of the time server will be connecting and disconnecting bots or other spammers.
    And it would be so easy to add IPs to the black list if buffer is empty (means request came outside Unity client) with some checking implementation on the client side to prevent sending empty buffers.
     
    Last edited: Jun 1, 2017
  17. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Not trying to be a c***. But you are kindoff implying that this is a 5 minute task that there is no reason to leave out. Not arguing against you, nor am I with you. But the Network Library is open source and you can always implement it yourself if you personally need it.
     
    daniyiyi and wobes like this.
  18. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @Wobes I would say, so far you can use web identification, and then after connect send authentication message something like this. ETA for authentication is still not clear...

    @TomPo what kind of authentication do y need?
    -strong certificate based
    -week password based
    -who will check these passwords?
    -do we need to support data base for users?
    -where this data base should be hosted and who will do this?
    -will it help to prevent ddos attacks?
    -do we need to support authorization on top of this?
    -what grants for user we should support for authorization system
    -one more things what security library we should use if ssl patented?
    -another question, what lib we should use for udp traffic?
    -do we need to crypt all traffic?
    -should user to be able to config this?

    :(
     
    TwoTen and wobes like this.
  19. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Right now I am personally passing a byte[] to the server after connect. This is the ticket. Then after that it gets verified and if it's not correct the server disconnects them. Something like that but with more native integration and some form of encryption would be fantastic.
     
    wobes likes this.
  20. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Same thing.
     
  21. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @TwoTen @Wobes - yes it makes sense, by adding buffer to connect() call. Will be this enough? Could i leave buffer encryption to user?
     
  22. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Yes sure. But there should also be a way for the server to actually reply to the buffer before the connection is accepted. But built in encryption would be nice, but it would be fine without for me personally.

    But built in encryption would be very nice as this can be complicated to deal with for many developers and it's easy to mess up.
     
    Last edited: Jun 26, 2017
  23. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Could we just have virtual method to override if received buffer isn't empty?
     
  24. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @Wobes yes, I think that i need to create something like middle layer on top of llapi, with different callbacks... nothing fancy but public accessible set of classes which simplifying working with llapi and can be easily changed by user

    @TwoTen not sure about encryption, we still need to deliver symmetric keys (to decrypt) another problem is NDA (like android or ps4) platforms (SSL patents...)...
    Anyway under the hood it would be like
    OnPassowrd(data)
    {
    if(Check(data) == true;
    OnConnect()
    else
    Disconnect(badPassword);
    }
    something like this
     
    wobes likes this.
  25. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Would this work with HLAPI? That's what our game currently uses.
     
  26. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    418
    Amazing, thanks.
     
  27. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @TwoTen - I don't think so, but hlapi is open sourced, i guess you can change them, actually u will need to change only OnConnect function to allow buff as parameter, and then call disconnect from OnConnect if password failed
     
    TwoTen likes this.
  28. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Updates on this?
     
  29. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    remember, not yet current version has been already locked. Woll try to implement on the next week, but I'm not sure when it will be accessible for customers :(
     
  30. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Alright, my project has been migrated to the LLAPI. And it's kindoff a musthave before we go for release.
    As for encryption? Is there some native support from you guys? Certificates / SSL? Would be lovley to not have to deal with yourself
     
  31. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    we just cannot :( openssl is under nda and apple store and android play store will reject your project. I consider another library right now, but not sure that will be approved due legal problems too :( as it the same algorithm. I heard that AES is not protected but not sure. And after all, I afraid I cannot implement this quickly. What do you need? Probably we can find another way how we can get some sort security?
     
  32. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    Well. AES would not REALLY secure. Atleast not alone. But what do you mean with NDA. NDA usually refers to Non Disclosure Agreement which is not really related.
    But we just need a way to send the connect buffer securely. With Assymetric keys.
    And is it not a posibility for you guys to simply not support encryption on x platforms?

    And for me personally. I am not really in a hurry. But I would love to get it within a month if that's possible.
    And if this is not posible. I will probably be the one who has to research the Certificate / SSL stuff and we have to make a workaround. Basically verify after connect.

    Just to clarify:
    What we need is like a new Channel which is like ReliableEncrypted. Where what you send there is secure.
     
    Last edited: Jul 26, 2017
  33. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    I meant NDA platforms like PS4... The problem with OpanSSL is LGPL license. Another problem is to marry openSSL and udp.. But it is different story. Ok, i understood you, will check what I can do here. BTW, right now you can use websocket communication just for secure traffic. API is the same, p2p has been supported and ssl supported as well. What do you think?
     
  34. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    So technically I can start listening for WebSocket aswell as normal socket. And only handle authentication on that? It's going to be a dirty workaround, but it will probably be enough for the alpha testing stage of our game.
     
  35. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @TwoTen, could you please formulate your feature request? The deal is I (now) just do not have enough time to properly design this feature and just need help to reduce my work :) (what enough for alpha what should be done in the near future)? + With featyre request ETA will be more clear
     
  36. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    What would be great is this:
    When you connect using the LLAPI. You can optionally put a byte[] in. On the Connect event on the server. You can get this in the connect event as the byte[] thats used for data.

    And then, we can act upon this data. And we can then decline or accept the connection request. So I guess in the Config there would be a bool "autoAccept". Which defaults to true. If thats the case. It just adds their connection and we can communicate. But if we set it to false. We manually have to accept or decline their connection. So we can force them to send a valid steam ticket for example before their connection will ever get accepted.

    That's the easiest way I can see it being designed. That way, you dont need to use this. And it wont break ANYTHING. So if the autoAccept bool is not touched. It will work just like before. But if you manually set it to true, you have to accept or decline each connection. (Cause I know you lads are all about the not breaking things etc ;) )That would also solve SOME of the issues about the single queue being filled up. (aslong as your game isn't free). Cause then you can just check if they have bought the game. And if they haven't. They never get added. And if they have the game, and gets accepted. If they then fill the queue. We can just disconnect them and put them on a blacklist. Next time they connect. We can check if their account is on that blacklist. And if it is, we never add them. For simple games, this could even be a password that you just Unicode encode and check if it's correct.

    And a bit offtopic:
    I REALLY do appreciate that you are in here at the Networking section activley listening. It REALLY helps and it's suuuper nice of you. Thanks alot for that.
     
    Last edited: Aug 1, 2017
  37. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
    Having the ability to pass custom bytes in a Connect request would be great, but its also very important that the authentication process doesnt work as described
    This is bad...
    Code (CSharp):
    1. OnConnect(int connectionID, byte[] data, int size)
    2. {
    3.     if(Check(data, size) == true);
    4.         OnConnect()
    5.     else
    6.         Disconnect(badPassword);
    7. }
    That is bad because it is implying the connection was already mad successfully, and now that we have checked whatever we wanted to check and decide its bad, we now have to disconnect them.

    It should instead be something like this..
    Code (CSharp):
    1. OnConnectRequest(int connectionID, byte[] data, int size)
    2. {
    3.     if(Check(data, size) == true);
    4.         NetworkTransport.AcceptConnectionRequest(connectionID, /*maybe also be able to pass byte data here*/)
    5.     else
    6.         //Do nothing. The connection was never made, no packets were sent out, other side doesnt even know if we really exist.
    7. }
    If the process isnt something like how I described above, then there is no point in this thread. We can already just connect, after connection send some message with a password or some other data we want to check, and if data is bad we disconnect. What difference would it really be if we pass the data in the connect method or just after the connect message? I think everyone here wants it so that we can pass byte data in the connect message to be able to check if we want to make a connection before the connection is actually made, so that we can actively ignore the connection request, leaving the other side receiving absolutely 0 packets from us. It goes from being a "Connect" method, to a "ConnectRequest" method.
    Maybe there can be a "RefuseConnectRequest(connectionID, byte data)" where we send a unreliable refuse message to the other connection, and a "IgnoreConnectRequest(connectionID)" method where we just silently ignore the connection request, acting like it never happened and sending no packets back to the other connection.

    I can make this a feature request if desired.
     
    Last edited: Aug 1, 2017
    TwoTen likes this.
  38. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,001
    ^^. Correct. And I guess the Client can then have the ConnectionTimeout to know if it got accepted or not.
     
  39. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
  40. mafff

    mafff

    Joined:
    Jan 16, 2015
    Posts:
    8
    In the current state, the NetworkTransport class is completely inadequate. With my PC at hand and only knowing the IP and port of a server using UNET, I could easily send thousands of connection requests per second and cause the server to immediately reach the maximum number of connections. Legit connections would then be refused because there is absolutely no way of telling legit and non legit connections apart.

    We need an overload of NetworkTransport.Connect that allows the client to send authentication data to the server, and a callback on the server to accept or reject the connection after verifying the authentication data. Before the connection is verified by the callback, it shouldn't count into the limit on the number of connections, so other connections can be processed at the same time, and bogus connections can't block legit ones. I think this is the same solution suggested by @HiddenMonk, with whom I 100% agree.

    Right now using UNET for a dedicated server means exposing your game to very easy denial-of-service attacks. I think this is a very important security issue and the UNET team should solve it quickly.
     
    TwoTen and HiddenMonk like this.
  41. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
    The problem is, there will always need to be some kind of collection that stores these pending connection requests, and we would want to limit how many can be pending at once for memory reasons and such, so this wont really fix a dos/ddos like attack.

    You also cant really just limit how many times a single ip address can send a connect request since some places in the world have a single ip address that is used for many people. Though, maybe you can get away with a maxAllowedPendingConnectionRequestsFromSameIpAddress so that you can choose to store X amount of pending connection requests, from a single ip address regardless of its port, at a time. It would probably be rare that more than 100 people on the same Ip address try to connect to you at the same time anyways.

    Regardless, we need some kind of chance to accept/refuse/ignore connection requests, and not just blindly let someone connect to us and then figure out they shouldnt have...
     
    Last edited: Oct 27, 2017
    wobes likes this.
  42. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    guys, i'm working on this :) Not very easy, most probably I will first publish suggested solution here on forum, for discussion...
     
    TwoTen, mafff and HiddenMonk like this.
  43. mafff

    mafff

    Joined:
    Jan 16, 2015
    Posts:
    8
    With the current implementation of the NetworkTransport, an attacker can just send a few bogus requests that will fill all the available connection slots, and no one will be able to join the game anymore. With zero effort they can achieve 100% disruption.

    On the other hand, if the NetworkTransport validates the connections and filters out the bogus ones, the scenario of an attack is completely different. Now they need a serious DOS attack to even slow down the server.

    The only thing that can be done is to minimise the resources that a connection can use before it is authenticated. A serious DDOS would cause problems no matter what, but this goes beyond the scope of this thread.
     
    aabramychev likes this.
  44. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
    This might all depend on your game as well as how you are willing to filter it.
    For example, currently the networktransport would allow anyone who didnt pay for your game to connect to a player and fill up their connection slots. An authentication can fix this, or make it less desirable to do since theyll need to buy many copies.
    However, with a free to play game, an authentication might not do much good in preventing a single computer from spamming connection requests and filling up the connection slots, and you cant just limit a single connection per ip address since a single ip could be used for multiple people (countries/appartments/dorms/homes), unless if your willing to sacrifice those people.
    In other words, it all depends on the type of game (fps/mmo/etc) and how youll filter out bogus connections. I am not sure how to properly do that in a free to play scenario since they can just keep making new accounts, but at least theyll need to make many accounts as opposed to how it is now where they just need to send a few crafty packets.
    I think one way I saw a free to play mmo handle this was it had a captcha that needed to be filled out alongside your account info when trying to log into the game server.
    However, take the free to play game team fortress 2, there were times where I was playing in a valve official server of 12 vs 12 and either my team or the enemy team had like 6 bots that were hacking, presumably controlled by the same person. You couldnt even kick them since the vote kick needed majority vote from the team the bots were on and the bots were the majority.

    I guess what I am saying is, an authentication system wont really stop players from connecting many times, but it can help slow it down compared to how the networktransport is now, especially in a pay to play game compared to free to play.
     
  45. mafff

    mafff

    Joined:
    Jan 16, 2015
    Posts:
    8
    @HiddenMonk I think you're suggesting that the additional authentication data would make a DOS attack even more effective because of the increased packet size?

    I don't think that's the case. NetworkTransport uses UDP under the hood (or WebSockets, but it doesn't really make a difference). Before a UDP datagram makes its way up to the Unity transport layer, it will first be processed by the network card and then by the OS. Both will blindly accept all UDP datagrams until there are enough resource to do so. An attacker would send full-sized datagrams to waste as many resources as possible on the target machine. It doesn't matter if the servers requires authentication or not.

    If an attacker is able to reach your server, there isn’t much you can do against a multi-Gbit/s attack. Those types of attacks need to be blocked at the edge, well before it gets to the Unity transport layer.

    I agree that an authentication doesn't help against DOS attacks, but that's not the point. There are no disadvantages in implementing an authentication callback in the NetworkTransport. Contrarily, there is much to be gained in terms of security.
     
  46. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
    No, I was mainly just saying how having an authentication system wont necessarily prevent players from filling your server with bogus connections. It all depends on how you do the filtering I guess.

    I agree as well ^^, we need an authentication system. If you thought I was saying otherwise then I am sorry for not being clear.
     
    Last edited: Oct 28, 2017
  47. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @maff there are two problem with callback (1) not sure that the idea to call c# layer from worker thread will be approved (will know on the next week) and second callback should be fast, as it will block io thread.

    I see the following scenario:
    *. User send first request
    *. io thread call callback which return true or false, false - packet will dropped
    *. as user sends up to ConnectAttempt requests with ConnectTimeout period, so authenticated code will have ConnectAttempt*ConnectTimeout to define if that connect request correct or not. This actually means that the first connect request most probably will be dropped, while second probably will successful.

    So far, no security on transport layer, just authentication token in connect request. Security is separate problem, should I implement it on channel level (messages) connection level or host level?
     
  48. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    968
    Is it not possible that we can just poll the NetworkTransport for any pending connection requests and accept/refuse/ignore when desired so that we dont have to lock up any threads.
    This way we can poll inside the main thread for connection requests just like how we poll for connection messages with NetworkTransport.Receive. I dont think speed should be a problem so long as we set ConnectTimeout to something lenient like 5 seconds.
    Maybe we can even create a new thread and poll from there so its faster, or is it kinda hardcoded that all Unity API absolutely cannot be called from outside the main thread?
    What about the upcoming c# jobs system unity is working on?
    Of course this all means you would have to store the connection requests in a collection as opposed to instantly getting a response as the connection request is received.

    Can it return an enum Accept/Refuse/Ignore, where Accept it does its thing, Refuse it will try to send a message we create back telling it was refused and why (kinda like how when you disconnect it tries to send a message that you disconnected but it doesnt really care if the other side got it), and then Ignore will just drop the packet and send nothing.

    That should be fine and depends a lot on the ConnectTimeout which I dont see why it cant be set to something like 5 seconds.

    By security do you mean encryption and such like what the old Network.InitializeSecurity did? If so, then I assume it would be best to have the security be on a channel level so you have the ability to have some encrypted channels for security that are slower and use more bytes, and fast normal non-encrypted channels used for normal game stuff.


    Overall, I am no expert so I dont really know what I am talking about =)
     
  49. mafff

    mafff

    Joined:
    Jan 16, 2015
    Posts:
    8
    In my specific case a solution like that would be perfectly fine, but as a general purpose solution I don't think it's ideal. Some applications might need to query a database before knowing if the authentication token is valid, so the validation needs to be handled asynchronously.

    Instead of using the return value of the callback to decide, why not have it return void and let the application inform the transport layer as soon as it has validated the auth token? To do that we need a new API like @HiddenMonk suggested in an earlier post:

    To summarise I think we need the following new APIs:

    1) NetworkTransport.SetAuthenticationCallback(int hostId, System.Action<int, int, NetworkReader> callback)
    hostId is the id of the host that needs authentication.
    callback takes three paramters: the host id, the connection id and a NetworkReader to retrieve the auth token.

    2) An overload of NetworkTransport.Connect and similar that also takes a NetworkWriter, to send the authentication data.

    3) An overload of NetworkManager.StartClient that also takes a NetworkWriter to pass to the overloaded NetworkTransport.Connect.

    4) NetworkTransport.AcceptConnection(int hostId, int connId)
    It's important that a connection is internally put in some kind of 'pending' state until this method is called. The HLAPI should know nothing about a pending connection, and it should not count into the limit set by HostTopology.MaxDefaultConnections.

    5) NetworkTransport.RefuseConnection(int hostId, int connId, [NetworkWriter writer])
    The third parameter is optional, and is only needed if the server wants to send some data back to the client. Otherwise, all resources associated to this connection should be freed.

    Of course, if the application doesn't set a callback using SetAuthenticationCallback everything should work as it does now, i.e. the connection is automatically accepted. This means these changes to the API would maintain full backward compatibility.

    Personally I don't think this is necessary. Once the application is notified about an incoming connection, it should be the application's responsibility to either accept it or refuse it in a timely manner.

    Finally there is the question whether to call the callback from a worker thread. I would be perfectly happy with it being called from a different thread, and I think it would be the same for most developers. Just state clearly in the documentation that the callback is called outside the main thread, and let us handle the synchronisation ourselves :). If we can write a networked game, we can also handle thread safety.

    If you have problems getting this accepted, then there is an easy solution. Instead of having the transport layer invoking the callback, move that logic to the HLAPI in the NetworkServer class. NetworkServer is based on NetworkServerSimple that constantly polls the transport layers by calling NetworkTransport.ReceiveFromHost from the main thread. Right now there is an event called NetworkEventType.ConnectEvent. You can add an additional event called ConnectRequestEvent that is returned by the transport layer when a new connection is initiated. When the NetworkServer receives this event, it will either call the auth callback if it was set, or will directly call NetworkTransport.AcceptConnection if no callback was set. Only after the connection was accepted the transport layer will emit the NetworkEventType.ConnectEvent event. This is the pseudo code of what I mean:

    Code (CSharp):
    1. networkEvent = NetworkTransport.ReceiveFromHost(/* params */);
    2.  
    3. switch (networkEvent)
    4. {
    5.     case NetworkEventType.ConnectRequestEvent:
    6.     {
    7.         if(callback != null)
    8.         {
    9.             callback(/* params */);
    10.         }
    11.         else
    12.         {
    13.             NetworkTransport.AcceptConnection(/* params */);
    14.         }
    15.         break;
    16.     }
    17.  
    18.     case NetworkEventType.ConnectEvent:
    19.     {
    20.         HandleConnect(connectionId, error);
    21.         break;
    22.     }
    23.  
    24.     // more code there
    25. }
    To maintain backward compatibility, you could add a new API that enables this feature of the transport layer:

    NetworkTransport.useConnectionAuthentication: if set to true, the transport layer will use the NetworkEventType.ConnectRequestEvent to let the application handle the authentication. If set to false the transport layer will return directly the NetworkEventType.ConnectEvent as it does now.

    I think the priority right now should be the authentication feature, but of course encryption would be welcome and I would certainly enable it in production. Channel level encryption would be preferable because it's more granular and gives more control to the developer.
     
    Last edited: Oct 30, 2017
  50. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    545
    @mafff @HiddenMonk

    yes it is probably make sense. The deal is, implementation via poll will require much more time :( I will (most probably) do something like this but not now, probably with more stable disconnect and graceful host removing. Callback (if it will be approved) can be implement much faster (I mean weeks before experimental build).

    Threads: nothing prevent call network layer from thread, it is almost :) thread safe (when i talk almost I mean that if you will receive message more than buffer which you represent, the next call can contain other message if another thread has been already utilize this, + thread safety like this has been supported on windows, linux, and mac os platform only, no big issue to support this on other platforms but so far nobody asked me about this)