|
Dedicated Server Discuss technical issues related to hosting your own servers. |
|
Thread Tools | Display Modes |
#1
|
|||
|
|||
Decoding the protocol
I am looking for some information regarding altitude's communication protocol.
At login, the client uses some udp packets to reach the master server, which are then followed by a tcp handshake with login information, then back to udp. UDP is then used further on to gather the server list, and to ping them for additional information. Last night, I was able to decode the "server name" part of the udp packets the client receives from servers, but it's not exact. The first character of the server name appears to have a different encoding, and the same goes for non-letter chars from what I've seen. This is probably due to the wrong approach, so I'm wondering if anyone here knows something about the protocol, and might help. The ultimate goal is to create a proper server query tool. |
#2
|
|||
|
|||
Don't know anything about the protocol, but why don't you capture the packets sent and received by the builtin server browser?
|
#3
|
|||
|
|||
I captured the packets. They are encoded somehow, I managed to decode the name of the server, so far, except for the first character, so I must be doing something wrong. I was wondering if anyone else did this, or has some related knowledge.
So far, I am only able to build a tool which translates a dns/ip : port into partial server name... |
#4
|
|||
|
|||
Got the initial version working. It updates on demand (on page load), and caches for a couple of seconds.
Has anyone gotten replies / protocol info regarding the master server yet? Here's a demo of what I'm building: http://altitude.mihaiene.com/ Edit: takes 15 seconds to load after long idling, can be reduced to <1s. Last edited by randunel; 08-22-2015 at 02:01 AM. |
#5
|
|||
|
|||
You appear to be listing every server with players twice and empty servers once:
14/14 Official #1 - TBD - maxPing=400 tbd_underpark 14/14 Official #1 - TBD - maxPing=400 tbd_underpark 14/14 Ledow's Football Server #3 (server2.ledow.org.uk) ball_football 14/14 Ledow's Football Server #3 (server2.ledow.org.uk) ball_football 11/14 0xffff's bombs tbd_noname 11/14 0xffff's bombs tbd_noname 9/20 Coop Sandbox qde_coop_arkanoid 9/20 Coop Sandbox qde_coop_arkanoid 3/14 {= Coop Advanced (1de/tbd/ball) =} tbd_coop_icedive_easy 3/14 {= Coop Advanced (1de/tbd/ball) =} tbd_coop_icedive_easy 1/2 !rawr's duels qdm_asteroidsr 1/2 !rawr's duels qdm_asteroidsr 0/60 League US-West#1 lobby_league 0/60 Ranked TBD US-East#2 lobby_tbd 0/60 League US-West#2 lobby_league |
#6
|
|||
|
|||
Interesting, look at the FFA, its not listed twice
23/60 Ranked BALL US-East#3 ball_snow_pb 23/60 Ranked BALL US-East#3 ball_snow_pb 14/14 Ledow's Football Server #4 (server2.ledow.org.uk) ball_football 14/14 Ledow's Football Server #4 (server2.ledow.org.uk) ball_football 4/20 tbd Coop tbd_coop_super_mario_expert 4/20 tbd Coop tbd_coop_super_mario_expert 3/14 0xffff's bombs tbd_fun_arena 3/14 0xffff's bombs tbd_fun_arena 3/14 Ledow's Football Server #2 (server2.ledow.org.uk) ball_football 3/14 Ledow's Football Server #2 (server2.ledow.org.uk) ball_football 2/14 [LTTD]SYD 2 - FFA ffa_cave 1/14 Ledow's Hockey Server #9 (server2.ledow.org.uk) ball_hockey 1/14 Ledow's Hockey Server #9 (server2.ledow.org.uk) ball_hockey 0/60 Ranked BALL Europe#2 |
#7
|
|||
|
|||
I've been working on custom server software for altitude recently, which has involved reverse engineering the protocol. I'll leave this here for anyone searching:
Bit-oriented encoding Altitude's packets use bit-oriented encoding (also called bit packing), so values are rarely aligned to bytes. The first bit in a packet is the least significant bit of the first byte, so if for example you want to encode the value 29 (11101) using 5 bits followed by 54 (110110) in 6 bits, you would have: Code:
least significant bit -> 10111 011011 <-most significant bit Code:
11011101 00000110 https://gitlab.com/xalri/bitstream/b...src/lib.rs#L90 Also see the bit-oriented stream section of http://ithare.com/marshalling-and-encodings/. Ranged values (integers and scaled floats) can be written/read with the fewest bits using simple helper functions. https://gitlab.com/xalri/bitstream/b...rc/lib.rs#L150 Strings Strings are encoded in UTF-8, the first two bytes of a string give it's length in bytes. Strings can include null (but they probably never do), they're not null terminated. https://gitlab.com/xalri/bitstream/b...rc/lib.rs#L163 Packet headers - A simple transport protocol Altitude uses UDP, which has the advantage over TCP of speed, but the disadvantage that there's no guarantee that packets will be delivered or be in the correct order. Some things in altitude need these guarantees, so it uses a simple transport protocol which has optional delivery and order guarantees. Packets are sent with unique IDs, when a client receves a packet it sends an acknowlagement, the server will continue sending the packet untill it gets this acknowlagement, other packets can still be sent at the same time. This is called Go-Back-N ARQ (https://en.wikipedia.org/wiki/Go-Back-N_ARQ). The packet header looks something like this: Code:
guarantee level (2 bits) | routing number (6 bits) | guarantee data (0-53 bits) 0 -> No guarantee 1 -> Guaranteed delivery 2 -> Guaranteed delivery and order The next 6 bits are a routing header, which I'll talk about later. After this is the data needed for the transport protocol (sequencing numbers and sender IDs) which is between 0 and 53 bits long. If the guarantee level is 1 or 2, guarantee data is read. Otherwise, the rest of the packet is the payload. Transport protocol data The guarantee data starts with 2 bytes giving the type of packet it is: 0 -> Open (53) 1 -> Open ack (34) 2 -> Data (18) 3 -> Data ack (18) The values in parentheses are the length of that type of transport protocol data, including the two bits which give the type (so if you wanted to, say, skip this data when parsing a packet, you'd read the two bits for the type, then ignore the number of bits in parentheses minus two). Here's an implementation of reading and writing the guarantee level and data: https://gitlab.com/xalri/altserv/blo...arantee/mod.rs And an implementation of the guarantee system itself: https://gitlab.com/xalri/altserv/blo...tee/manager.rs Routing Header The 6 bit routing header in the packet header is used to decide which parts of the game/server the packet should be passed to: 0 - Friend messages & status 1 - Authentication 2 - Validation 3 - Server list 4 - Server list handler (?) 5 - Versioning 6 - Firewall checker 7 - Server info 8 - Ping (one of many :3) 9 - Game storage (?) 10 - Hardware report 70 - Join request & response 71 - Game messages (events, entity updates) 72 - Map downloading 73 - Pings (yeah, more of them :3) 74 - Multicast IP request & response (to find LAN servers) 75 - Another multicast thing ? Packet payload After the header, there's not much of a defined protocol, different parts of the client/server read and write bits as they please. There's often a lot of state involved in reading packets properly, which is making it difficult to reverse engineer. There is somewhat of a system for the game packets (header 71): Game packets are sent regularly, (about every 20-30ms), even when there is no new information to be sent. Information is split into two types, events and nuons. Events include individual things which happen in the game world: a plane spawning, crashing, using abilities, catching and using powerups, and so on, as well as metadata about the game: players joining, ping updates, game mode updates, etc. These events need to have guaranteed order and delivery, the system for this is different to and a little more complex than the guarantee system in the packet header, it's an instance of selective repeat ARQ (https://en.wikipedia.org/wiki/Selective_Repeat_ARQ): Events are split into sequenced event groups, which the sender keeps for a while. If the receiver gets an event group but it's missing the one before it, the next time the receiver sends a game message to the sender, it will give a list of event groups that it's missing, the original sender will then re-send these event groups (if it still has them cached). Game messages also include updates for all the dynamic entities in the game, planes, projectiles, etc. These are referred to as "nuons" by debug messages in the decompiled (still obfuscated) altitude source code, so I'll use that term (I'm not sure if it refers to the information used to update the entity or the entities themselves, I'll use the former - entities which are updated like this are called nuons). This data needs no guarantees, as only the most recent data is ever relevant. I'll probably write about the implementation of this at some point, for now: https://gitlab.com/xalri/altserv/blo...et/game_msg.rs https://gitlab.com/xalri/altserv/blo...nt/ev_group.rs https://gitlab.com/xalri/altserv/blo...c/event/mod.rs Server Info messages Since this is what this thread's about, I suppose I should quickly go over server info messages (header 7). Server info messages can be either a request or a response. It's assumed that a client will only send a request, and a server will only send a response, so the only way to differentiate between them without knowing who sent it is by it's size. Requests have no extra information, so the packet size is just the size of the header, which is no more than 8 bytes long. Responses contain, in this order: - A single bit with the value 0 * - An unknown 16 bit value (some sort of ID?) - The server's IP address (a bool, if true IPv4 otherwise IPv6, then the values (4 or 16 bytes respectively) - The map name (a string) - The maximum players (8 bits) (only used for display, the client will try to join a full server anyway) - The current players (8 bits) - The server name (a string) - A bool, true if the server requires a password - A bool, false (?) if the server bouncy walls - The minimum level (1-60) - The maximum level (1-60) - A bool, false if demo users can join (no longer applicable?) - The server's altitude version (a string, currently "0.0.374") * The same code is used for other packet types which can have multiple types of data, this code looks at all the possible types of data and uses the minimum amount of data to distinguish between them, server info messages only contain one type of data, information about a server, but it still uses a single bit to say that that's what's in the packet. https://gitlab.com/xalri/altserv/blo...et/info_msg.rs https://gitlab.com/xalri/altserv/blo...server_info.rs I haven't looked into the vapor protocol yet, so querying the server list is a little beyond what I know ^^ Last edited by LewisH; 07-05-2016 at 05:38 PM. Reason: Updated URL |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Query Protocol, Rcon Commands | Sonderfall | Dedicated Server | 4 | 05-29-2010 06:39 PM |