129 lines
4.7 KiB
C
129 lines
4.7 KiB
C
/*
|
|
* Kangaroo Punch MultiPlayer Game Server Mark II
|
|
* Copyright (C) 2020-2021 Scott Duensing
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef PACKET_H
|
|
#define PACKET_H
|
|
|
|
|
|
#include "os.h"
|
|
#include "packets.h"
|
|
|
|
|
|
/*
|
|
* Packet format (without framing):
|
|
*
|
|
* Byte 01: cces ssss - Two control bits, one encryption bit, five sequence bits.
|
|
* Byte 02: pppp pppp - Eight bits, packet type.
|
|
* Byte 03: cccc cccc - Eight bits, channel.
|
|
* Byte 04: dddd dddd \
|
|
* Byte ..: dddd dddd > Packet payload.
|
|
* Byte X0: dddd dddd /
|
|
* Byte X1: cccc cccc - Checksum
|
|
*
|
|
*/
|
|
|
|
|
|
#define PACKET_MAX 1024 // Maximum number of bytes per packet
|
|
#define PACKET_SEQUENCE_MAX 16 // Five bits of data, 32 max.
|
|
|
|
#define PACKET_INPUT_QUEUE_SIZE 4096
|
|
#define PACKET_BUFFER_SIZE (PACKET_MAX * 2 + 2 + 8) // Worst case, every byte is a PACKET_FRAME. Add two for ending frame. Add 8 for worst case header and CRC.
|
|
|
|
#define PACKET_FRAME 0x7e
|
|
|
|
#define PACKET_ENCRYPT_KEY_SIZE 8 // 16 bits each. Provides 16 bytes (128 bits) of keydata.
|
|
|
|
|
|
// This enum must be 4 entries or less.
|
|
typedef enum PacketControlE {
|
|
PACKET_CONTROL_DAT = 0, // Regular data packet.
|
|
PACKET_CONTROL_RTX, // Retransmission packet.
|
|
PACKET_CONTROL_NAK, // Negative acknowledge.
|
|
PACKET_CONTROL_BAD,
|
|
PACKET_CONTROL_COUNT
|
|
} PacketControlT;
|
|
|
|
|
|
typedef struct PacketDecodeDataS {
|
|
// Output
|
|
PacketTypeT packetType; // One of PACKET_TYPE_*
|
|
char *data; // Buffer received. MUST FREE.
|
|
uint16_t length; // Length of buffer.
|
|
uint8_t channel; // Which data channel it arrived on.
|
|
} PacketDecodeDataT;
|
|
|
|
typedef struct PacketEncodeDataS {
|
|
// Input
|
|
PacketControlT control; // One of PACKET_CONTROL_*
|
|
PacketTypeT packetType; // One of PACKET_TYPE_*
|
|
uint8_t channel; // Which data channel to use.
|
|
uint8_t encrypt; // Do we want the packet encrypted?
|
|
// Input & Output
|
|
uint8_t sequence; // For NAK packets, input the sequence number we missed. Other packets returns the sequence of this packet.
|
|
// Output
|
|
char *dataPointer; // Buffer ready to send. DO NOT FREE.
|
|
uint16_t length; // Length of buffer.
|
|
} PacketEncodeDataT;
|
|
|
|
typedef struct PacketHistoryDataS {
|
|
char data[PACKET_BUFFER_SIZE];
|
|
uint16_t length;
|
|
uint8_t sequence;
|
|
} PacketHistoryDataT;
|
|
|
|
typedef struct PacketThreadDataS {
|
|
// Internal state per thread for packet processing.
|
|
uint8_t sequence;
|
|
uint8_t lastRemoteSequence;
|
|
PacketHistoryDataT history[PACKET_SEQUENCE_MAX];
|
|
uint8_t historyPosition;
|
|
char decodeBuffer[PACKET_MAX];
|
|
char encodeBuffer[PACKET_BUFFER_SIZE];
|
|
char decodeQueue[PACKET_INPUT_QUEUE_SIZE];
|
|
uint16_t decodeQueueHead;
|
|
uint16_t decodeQueueTail;
|
|
uint8_t inEscape;
|
|
uint8_t newPacket;
|
|
void *senderData;
|
|
uint16_t dhModulus[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint16_t dhBase[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint16_t dhMySecret[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint16_t dhMyPublic[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint16_t dhTheirPublic[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint16_t dhSharedKey[PACKET_ENCRYPT_KEY_SIZE];
|
|
uint8_t encryptionBuffer[PACKET_MAX];
|
|
void *aesContext;
|
|
} PacketThreadDataT;
|
|
|
|
|
|
typedef void (*packetSender)(char *data, uint32_t length, void *userData);
|
|
|
|
|
|
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, char *input, uint16_t length);
|
|
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
|
|
uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, char *input, uint16_t length);
|
|
void packetEncryptionSetup(PacketThreadDataT *threadData);
|
|
void packetSend(PacketThreadDataT *threadData, PacketEncodeDataT *data);
|
|
void packetSenderRegister(packetSender sender);
|
|
PacketThreadDataT *packetThreadDataCreate(void *senderData);
|
|
void packetThreadDataDestroy(PacketThreadDataT **data);
|
|
|
|
|
|
#endif // PACKET_H
|