The current draft for the new obby protocol plans to use a peer-to-peer-like mechanism for transport via jabber, so every jabber participant talks to other jabber participants directly instead of tunnelung through the publisher. This should reduce bandwidth usage quite a lot but raises quite a few other questions regarding peer-to-peer: Could new users join the obby network via any peer instead of just the publisher? Could the session stay alive when the original publisher leaves? I met Phil yesterday and we discussed these questions, and we even came up with some results. But first of all, what are the problems?
As soon as every peer in the network is allowed to accept new peers, we have to handle the case that two peers join the same network via two different nodes at the same time.
This affects ID generation. Currently, every user is assigned a unique user ID for the session. This is required because the protocol allows multiple users per connection (which is again required for the good old client/server model used by the TCP subsystem, but this option also allows another nice feature (republishing) I want to keep in mind for the future). An incoming request however is user-related rather than connection-related, so it must be clear which user generated it. It is still possible to produce unique IDs as soon as an ID is variable in length. When a peer has to generate a user ID, it just takes its own ID and appends something to it to generate a new one.
We cannot catch name collision. Two users with the same names could join the same network via two different peers at the same time. However, this does not matter at all since we could just allow duplicate names in the session. If we want to distinguish between them UI-wise we could suffix one client-side, maybe sorted by the user ID to keep it the same on all peers (but which would lead to renamings if a new user with the same name joins and gets an ID which is sorted before the ID of the existing user).
-
How to do user authentication? obby 0.4 allows each user to set a password which is stored on the server (respectively publisher) and recognizes users by name. So, if a user with the same name as a user which was in the session some time ago joins, the server looks whether a password has been set, and if the authentication was successful, the old user ID (with all text written by that user) is reassigned to the joining user. This is especially useful when the session has been serialized and should be continued later or when a user has lost the internet connection, perhaps by an automatically disconnection performed by the ISP (which is rather common at least in Germany, but that's another story).
So, let's assume we want to implement a similar feature into the new obby. Since we just said that names could appear twice, we would need another criteria to recognize a user after disconnection. The user ID comes to mind. So each client could store a table assigning a session to the user ID he had. But since the user ID is known to all participants this feature could easily be misused, so some form of authentication would still be required. The only solution I see here is that you tell the peer through which you have joined (or perhaps others that you trust) a password and if you want to be recognized lateron, you have to join through one of these trusted peers. If all of them have left the session, well, bad luck. I you have some suggestions concerning this point feel free to add a comment or drop me a mail.
-
We cannot just assign a vector time index to the new user because this could lead to conflicts as well. The solution would be an association between the user ID and the vector time component. This requires some more data to be stored in the state space and sent through the network.
As a last case, imagine the original publisher has left the session. In the flavour of a real peer-to-peer network the session would just go on as if nothing had happend. The only problem that could arise is that the publisher must not use the session ID that this session had for other sessions, because he cannot be sure that the old session with this ID might still be running somewhere. As sessions are identified by publisher and a session ID this could lead to conflicts. An easy approach would be to just generate a 32 bit random number as the session ID and assuming that we never generated this one before, but I do not like these approaches that only work in 99.999% of all cases and not in 100% (maybe just because I saw it too often that a mage in Wesnoth missed three times...). Having an ID counter somewhere in the user's home directory is not enough as well because another user might publish a session on the same port and with the same ID as another user on the same host (or just use the same jabber account). As above, I am open to any suggestions regarding this point.
Note however that these are just ideas and no final decisions and they only apply to the jabber communication level. All TCP communication is done as Server/Client as before because it is not guaranteed that all TCP participants can get direct connections to each others (think of NATs, different subnets and so on). This also means that Obby currently relies on all jabber users having direct connections (well, direct as in "I just need to send it to the jabber server and the other one will get it eventually").