Updated protocol spec to new V2 version

This commit is contained in:
2025-07-05 23:24:17 +03:00
parent 5f8ab176b6
commit 8f8736d09e
4 changed files with 99 additions and 64 deletions

View File

@@ -60,6 +60,9 @@ const (
PacketAuthenticate
PacketUsersInfo
PacketGetUsers
PacketSetUserData
PacketGetUserData
@@ -94,9 +97,6 @@ const (
PacketBlockUser
PacketBlockInfo
PacketGetUsers
PacketUsersInfo
PacketMax
)
@@ -269,6 +269,19 @@ func (p Packet) DecodedPayload() (Payload, error) {
case PacketError:
payload = &Error{}
case PacketTosInfo:
payload = &TosInfo{}
case PacketAcceptTos:
payload = &AcceptTos{}
case PacketGetNonce:
payload = &GetNonce{}
case PacketNonceInfo:
payload = &NonceInfo{}
case PacketAuthenticate:
payload = &Authenticate{}
case PacketSetUserData:
payload = &SetUserData{}
case PacketGetUserData:
@@ -335,7 +348,8 @@ func (p Packet) DecodedPayload() (Payload, error) {
payload = &UsersInfo{}
default:
assert.Never("unexpected packet.PacketType", "type", p.Type())
assert.Assert(!p.Type().IsSupported(), "supported PackeType wasn't handled", "type", p.Type())
return nil, fmt.Errorf("unsupported PackeType: %v", p.Type().String())
}
err := p.DecodePayloadInto(payload)
return payload, err

View File

@@ -0,0 +1,81 @@
# Eko Protocol V2
## Packet Structure
```
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version |En.| Type | Payload Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload... Payload Length bytes ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
Order of bytes is from left to right, top to bottom.
The first byte is always the version, any bytes after it
depend on the specific value of the version byte.
- Encoding: 0-3, determines the way the payload was encoded
- 0: JSON
- 1: MsgPack
- 2: Reserved for future use
- 3: Reserved for future use
- Type: 0-63, determines the type ("schema"), of the payload
- Payload Length: 0-65531, determines how long the payload is in bytes
- Payload: 0 to 65531 bytes long, depending on the payload size (~64kb)
## Handshake
The first time a connection is established, the following packets are exchanged.
- Server sends a TosInfo (Type 1) with the Terms of Service and Privacy Policy
- Client must respond with an AcceptTos (Type 2) with an agree boolean of true
- If the client sends any other type of packet, or the boolean is false, the server may close the connection
After the handshake, the client may send any unauthenticated packets.
### Authentication
At any time, while authenticated or not, the client may request a nonce (GetNonce, Type 3).
The server then must responsd with NonceInfo (Type 4).
It's recommended for the server to use a cryptographically secure random number generator,
and to rotate the value every minute.
To authenticate, a client must send an Authenticate request (Type 5),
the request must include a public key, and a signature (64 bytes) of the nonce.
The server must then respond in one of the following ways:
- With an Error (Type 0) with any message, indicating failed authentication
- With a UsersInfo (Type 6) indicating success
- Must include exactly one UserID (corresponding to the authenticated user)
Note: if the client takes too long between the nonce request, the nonce may have been rotated
and the client will need to redo these steps.
## Error handling
The server may close a connection only in these cases:
- the client has already closed the connection
- the server has finished processing and sending all reqeusts
- the server experienced an abrupt termination (SIGKILL, powerloss, etc)
- after sending a TosInfo and a receiving any packet except of AcceptTos with a value of true
The server may stop receiving data (and drop any partial requests) at any time (in response to a SIGINT/SIGTERM).
The client may close a connection at any time but data loss may occur.
### Malformed Packets
- unsupported/invalid version: connection can be closed immediately
- unsupported encoding: server must respond with an error type, may use any encoding, client may close the connection
- unknown type: server must respond with an error, client may close the connection
- malformed paylod: server must respond with an error, client may close the connection
For application errors such as a client asking to send a message in a non-existent Frequency,
the server must respond with an error packet.
For internal errors such as database failure, the server must respond, it may choose to
disclose as much information as it wants, or just say "internal server error".

View File

@@ -1,59 +0,0 @@
# Eko Protocol V1
## Packet Structure
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version |En.| Type | Payload Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload... Payload Length bytes ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Order of bytes is from left to right, top to bottom.
The first byte is always the version, any bytes after it
depend on the specific value of the first byte.
- Encoding: 0-3, determines the way the payload was encoded
- 0: JSON
- 1: MsgPack
- 2: Reserved for future use
- 3: Reserved for future use
- Type: 0-63, determines the type ("schema"), of the payload
- Payload Length: 0-65531, determines how long the payload is in bytes
- Payload: 0 to 65531 bytes long, depending on the payload size (~64kb)
## Handshake
The first time a connection is established, the following packets are exchanged.
- Server sends a special 1-byte for version then 32-byte the challenge nonce packet
- Client sends a Challenge Response packet with:
* version (1-byte long)
- the client's ed25519 public key (32-bytes long)
- the client's ed25519 signature for the server-given nonce (64-bytes long)
After the handshake the server may close the connection,
for example due to an invalid signature.
## Error handling
The server may abruptly close a connection in these cases:
- After the initial handshake
- After any response
A server may not close the connection if it received a request, it must first response then close.
The client may abruptly close a connection at any time
### Malformed Packets
- unsupported/invalid version: connection can be closed immediately
- unsupported encoding: server must respond with an error type, may use any encoding, client may close the connection
- unknown type: server must respond with an error, client may close the connection
- malformed paylod: server must respond with an error, client may close the connection
For application errors such as a client asking to send a message in a non-existent Frequency,
the server must respond with an error packet.
For internal errors such as database failure, the server must respond, it may choose to
disclose as much information as it wants, or just say "internal server error".

View File

@@ -324,7 +324,6 @@ func processPacket(ctx context.Context, sess *session.Session, pkt packet.Packet
}
assert.NotNil(response, "response must always be assigned to")
log.Println(sess.Addr(), "sending", response.Type(), "response:", response)
return packet.NewPacket(packet.NewMsgPackEncoder(response))
}