mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-21 05:53:12 -07:00
Implement GMAC for Takion Control Data
This commit is contained in:
parent
a4fd9a49e8
commit
02eab4efc8
4 changed files with 207 additions and 57 deletions
|
@ -80,13 +80,23 @@ typedef struct chiaki_takion_connect_info_t
|
||||||
void *data_cb_user;
|
void *data_cb_user;
|
||||||
ChiakiTakionAVCallback av_cb;
|
ChiakiTakionAVCallback av_cb;
|
||||||
void *av_cb_user;
|
void *av_cb_user;
|
||||||
|
bool enable_crypt;
|
||||||
} ChiakiTakionConnectInfo;
|
} ChiakiTakionConnectInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum chiaki_takion_crypt_mode_t {
|
||||||
|
CHIAKI_TAKION_CRYPT_MODE_NO_CRYPT, // encryption disabled completely, for Senkusha
|
||||||
|
CHIAKI_TAKION_CRYPT_MODE_PRE_CRYPT, // encryption required, but not yet initialized (during handshake)
|
||||||
|
CHIAKI_TAKION_CRYPT_MODE_CRYPT // encryption required
|
||||||
|
} ChiakiTakionCryptMode;
|
||||||
|
|
||||||
|
|
||||||
typedef struct chiaki_takion_t
|
typedef struct chiaki_takion_t
|
||||||
{
|
{
|
||||||
ChiakiLog *log;
|
ChiakiLog *log;
|
||||||
|
|
||||||
|
ChiakiTakionCryptMode crypt_mode;
|
||||||
|
|
||||||
ChiakiGKCrypt *gkcrypt_local; // if NULL (default), no gmac is calculated and nothing is encrypted
|
ChiakiGKCrypt *gkcrypt_local; // if NULL (default), no gmac is calculated and nothing is encrypted
|
||||||
size_t key_pos_local;
|
size_t key_pos_local;
|
||||||
ChiakiMutex gkcrypt_local_mutex;
|
ChiakiMutex gkcrypt_local_mutex;
|
||||||
|
@ -111,15 +121,45 @@ typedef struct chiaki_takion_t
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info);
|
||||||
CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion);
|
CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion);
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size);
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint32_t key_pos, uint8_t *gmac, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size);
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet);
|
|
||||||
|
|
||||||
static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) {
|
static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) {
|
||||||
takion->gkcrypt_local = gkcrypt_local;
|
takion->gkcrypt_local = gkcrypt_local;
|
||||||
takion->gkcrypt_remote = gkcrypt_remote;
|
takion->gkcrypt_remote = gkcrypt_remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new key pos and advance by data_size.
|
||||||
|
*
|
||||||
|
* Thread-safe while Takion is running.
|
||||||
|
* @param key_pos pointer to write the new key pos to. will be 0 if encryption is disabled. Contents undefined on failure.
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, size_t *key_pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a datagram directly on the socket.
|
||||||
|
*
|
||||||
|
* Thread-safe while Takion is running.
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the MAC for the packet depending on the type derived from the first byte in buf,
|
||||||
|
* assign MAC inside buf at the respective position and send the packet.
|
||||||
|
*
|
||||||
|
* If encryption is disabled, the MAC will be set to 0.
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-safe while Takion is running.
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-safe while Takion is running.
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet);
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t base_type, uint8_t *buf, size_t buf_size);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t base_type, uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -177,7 +177,7 @@ static ChiakiErrorCode senkusha_send_big(Senkusha *senkusha)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = stream.bytes_written;
|
buf_size = stream.bytes_written;
|
||||||
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 0, NULL, 1, 1, buf, buf_size);
|
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 1, 1, buf, buf_size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ static ChiakiErrorCode senkusha_send_disconnect(Senkusha *senkusha)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = stream.bytes_written;
|
buf_size = stream.bytes_written;
|
||||||
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 0, NULL, 1, 1, buf, buf_size);
|
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 1, 1, buf, buf_size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,6 +252,9 @@ static void stream_connection_takion_data(ChiakiTakionMessageDataType data_type,
|
||||||
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_ERROR, buf, buf_size);
|
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_ERROR, buf, buf_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGD(stream_connection->log, "StreamConnection received data\n");
|
||||||
|
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_DEBUG, buf, buf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
||||||
|
@ -525,7 +528,7 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = stream.bytes_written;
|
buf_size = stream.bytes_written;
|
||||||
err = chiaki_takion_send_message_data(&stream_connection->takion, 0, 0, 1, 1, buf, buf_size);
|
err = chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +551,7 @@ static ChiakiErrorCode stream_connection_send_streaminfo_ack(ChiakiStreamConnect
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = stream.bytes_written;
|
buf_size = stream.bytes_written;
|
||||||
return chiaki_takion_send_message_data(&stream_connection->takion, 0, NULL, 1, 9, buf, buf_size);
|
return chiaki_takion_send_message_data(&stream_connection->takion, 1, 9, buf, buf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection)
|
static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection)
|
||||||
|
@ -573,7 +576,7 @@ static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = stream.bytes_written;
|
buf_size = stream.bytes_written;
|
||||||
ChiakiErrorCode err = chiaki_takion_send_message_data(&stream_connection->takion, 0, 0 /* TODO: gmac? */,1, 1, buf, buf_size);
|
ChiakiErrorCode err = chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -632,19 +635,5 @@ static ChiakiErrorCode stream_connection_send_heartbeat(ChiakiStreamConnection *
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t buf_size = stream.bytes_written;
|
return chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, stream.bytes_written);
|
||||||
uint8_t gmac[CHIAKI_GKCRYPT_GMAC_SIZE];
|
|
||||||
uint32_t key_pos;
|
|
||||||
|
|
||||||
ChiakiErrorCode err = chiaki_mutex_lock(&stream_connection->takion.gkcrypt_local_mutex);
|
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
|
||||||
return err;
|
|
||||||
key_pos = stream_connection->takion.key_pos_local;
|
|
||||||
err = chiaki_gkcrypt_gmac(stream_connection->takion.gkcrypt_local, key_pos, buf, buf_size, gmac);
|
|
||||||
stream_connection->takion.key_pos_local += buf_size;
|
|
||||||
chiaki_mutex_unlock(&stream_connection->takion.gkcrypt_local_mutex);
|
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return chiaki_takion_send_message_data(&stream_connection->takion, key_pos, gmac, 1, 1, buf, buf_size);
|
|
||||||
}
|
}
|
187
lib/src/takion.c
187
lib/src/takion.c
|
@ -27,14 +27,59 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base type of Takion packets. Lower nibble of the first byte in datagrams.
|
||||||
|
*/
|
||||||
typedef enum takion_packet_type_t {
|
typedef enum takion_packet_type_t {
|
||||||
TAKION_PACKET_TYPE_MESSAGE = 0,
|
TAKION_PACKET_TYPE_CONTROL = 0,
|
||||||
|
TAKION_PACKET_TYPE_FEEDBACK_HISTORY = 1,
|
||||||
TAKION_PACKET_TYPE_VIDEO = 2,
|
TAKION_PACKET_TYPE_VIDEO = 2,
|
||||||
TAKION_PACKET_TYPE_AUDIO = 3,
|
TAKION_PACKET_TYPE_AUDIO = 3,
|
||||||
|
TAKION_PACKET_TYPE_HANDSHAKE = 4,
|
||||||
|
TAKION_PACKET_TYPE_CONGESTION = 5,
|
||||||
|
TAKION_PACKET_TYPE_FEEDBACK_STATE = 6,
|
||||||
|
TAKION_PACKET_TYPE_RUMBLE_EVENT = 7,
|
||||||
|
TAKION_PACKET_TYPE_CLIENT_INFO = 8,
|
||||||
|
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9
|
||||||
} TakionPacketType;
|
} TakionPacketType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The offset of the mac of size CHIAKI_GKCRYPT_GMAC_SIZE inside a packet of type or -1 if unknown.
|
||||||
|
*/
|
||||||
|
ssize_t takion_packet_type_mac_offset(TakionPacketType type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case TAKION_PACKET_TYPE_CONTROL:
|
||||||
|
return 5;
|
||||||
|
case TAKION_PACKET_TYPE_VIDEO:
|
||||||
|
case TAKION_PACKET_TYPE_AUDIO:
|
||||||
|
return 0xa;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The offset of the 4-byte key_pos inside a packet of type or -1 if unknown.
|
||||||
|
*/
|
||||||
|
ssize_t takion_packet_type_key_pos_offset(TakionPacketType type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case TAKION_PACKET_TYPE_CONTROL:
|
||||||
|
return 0x9;
|
||||||
|
case TAKION_PACKET_TYPE_VIDEO:
|
||||||
|
case TAKION_PACKET_TYPE_AUDIO:
|
||||||
|
return 0xe;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint32_t TakionPacketKeyPos;
|
||||||
|
|
||||||
|
|
||||||
// TODO: find out what these are
|
// TODO: find out what these are
|
||||||
#define TAKION_LOCAL_SOMETHING 0x19000
|
#define TAKION_LOCAL_SOMETHING 0x19000
|
||||||
|
@ -94,7 +139,7 @@ static void takion_handle_packet_message(ChiakiTakion *takion, uint8_t *buf, siz
|
||||||
static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
|
static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
|
||||||
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
|
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
|
||||||
static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, TakionMessage *msg);
|
static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, TakionMessage *msg);
|
||||||
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint8_t *mac, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size);
|
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size);
|
||||||
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload);
|
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload);
|
||||||
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie);
|
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie);
|
||||||
static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, struct timeval *timeout);
|
static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, struct timeval *timeout);
|
||||||
|
@ -126,6 +171,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
|
||||||
takion->recv_timeout.tv_usec = 0;
|
takion->recv_timeout.tv_usec = 0;
|
||||||
takion->send_retries = 5;
|
takion->send_retries = 5;
|
||||||
|
|
||||||
|
takion->crypt_mode = info->enable_crypt ? CHIAKI_TAKION_CRYPT_MODE_PRE_CRYPT : CHIAKI_TAKION_CRYPT_MODE_NO_CRYPT;
|
||||||
|
|
||||||
CHIAKI_LOGI(takion->log, "Takion connecting\n");
|
CHIAKI_LOGI(takion->log, "Takion connecting\n");
|
||||||
|
|
||||||
ChiakiErrorCode err = chiaki_stop_pipe_init(&takion->stop_pipe);
|
ChiakiErrorCode err = chiaki_stop_pipe_init(&takion->stop_pipe);
|
||||||
|
@ -258,28 +305,99 @@ CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion)
|
||||||
chiaki_stop_pipe_fini(&takion->stop_pipe);
|
chiaki_stop_pipe_fini(&takion->stop_pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, size_t *key_pos)
|
||||||
{
|
{
|
||||||
//CHIAKI_LOGD(takion->log, "Takion send:\n");
|
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
|
||||||
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, buf_size);
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if(takion->gkcrypt_local)
|
||||||
|
{
|
||||||
|
size_t cur = takion->key_pos_local;
|
||||||
|
if(SIZE_MAX - cur < data_size)
|
||||||
|
{
|
||||||
|
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
|
||||||
|
return CHIAKI_ERR_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
*key_pos = cur;
|
||||||
|
takion->key_pos_local = cur + data_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*key_pos = 0;
|
||||||
|
|
||||||
|
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const uint8_t *buf, size_t buf_size)
|
||||||
|
{
|
||||||
ssize_t r = send(takion->sock, buf, buf_size, 0);
|
ssize_t r = send(takion->sock, buf, buf_size, 0);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
return CHIAKI_ERR_NETWORK;
|
return CHIAKI_ERR_NETWORK;
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint32_t key_pos, uint8_t *gmac, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
|
||||||
|
{
|
||||||
|
if(buf_size < 1)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(takion->log, "Takion send buf too small\n");
|
||||||
|
return CHIAKI_ERR_BUF_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TakionPacketType base_type = buf[0] & 0xf;
|
||||||
|
ssize_t mac_offset = takion_packet_type_mac_offset(base_type);
|
||||||
|
ssize_t key_pos_offset = takion_packet_type_key_pos_offset(base_type);
|
||||||
|
if(mac_offset < 0 || key_pos_offset < 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(takion->log, "Invalid Takion packet type for mac and key pos offset\n");
|
||||||
|
return CHIAKI_ERR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buf_size < mac_offset + CHIAKI_GKCRYPT_GMAC_SIZE || buf_size < key_pos_offset + sizeof(TakionPacketKeyPos))
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(takion->log, "Takion send buf too small for mac and key pos\n");
|
||||||
|
return CHIAKI_ERR_BUF_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
memset(buf + mac_offset, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
|
||||||
|
|
||||||
|
if(takion->gkcrypt_local)
|
||||||
|
{
|
||||||
|
TakionPacketKeyPos key_pos = htonl(*((TakionPacketKeyPos *)(buf + key_pos_offset)));
|
||||||
|
chiaki_gkcrypt_gmac(takion->gkcrypt_local, key_pos, buf, buf_size, buf + mac_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
|
||||||
|
|
||||||
|
CHIAKI_LOGD(takion->log, "Takion sending:\n");
|
||||||
|
chiaki_log_hexdump_raw(takion->log, CHIAKI_LOG_DEBUG, buf, buf_size);
|
||||||
|
|
||||||
|
return chiaki_takion_send_raw(takion, buf, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
// TODO: can we make this more memory-efficient?
|
// TODO: can we make this more memory-efficient?
|
||||||
// TODO: split packet if necessary?
|
// TODO: split packet if necessary?
|
||||||
|
|
||||||
|
size_t key_pos;
|
||||||
|
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, buf_size, &key_pos);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
size_t packet_size = 1 + MESSAGE_HEADER_SIZE + 9 + buf_size;
|
size_t packet_size = 1 + MESSAGE_HEADER_SIZE + 9 + buf_size;
|
||||||
uint8_t *packet_buf = malloc(packet_size);
|
uint8_t *packet_buf = malloc(packet_size);
|
||||||
if(!packet_buf)
|
if(!packet_buf)
|
||||||
return CHIAKI_ERR_MEMORY;
|
return CHIAKI_ERR_MEMORY;
|
||||||
packet_buf[0] = TAKION_PACKET_TYPE_MESSAGE;
|
packet_buf[0] = TAKION_PACKET_TYPE_CONTROL;
|
||||||
takion_write_message_header(packet_buf + 1, takion->tag_remote, gmac, key_pos, TAKION_MESSAGE_TYPE_A_DATA, type_b, 9 + buf_size);
|
|
||||||
|
takion_write_message_header(packet_buf + 1, takion->tag_remote, key_pos, TAKION_MESSAGE_TYPE_A_DATA, type_b, 9 + buf_size);
|
||||||
|
|
||||||
uint8_t *msg_payload = packet_buf + 1 + MESSAGE_HEADER_SIZE;
|
uint8_t *msg_payload = packet_buf + 1 + MESSAGE_HEADER_SIZE;
|
||||||
*((uint32_t *)(msg_payload + 0)) = htonl(takion->seq_num_local++);
|
*((uint32_t *)(msg_payload + 0)) = htonl(takion->seq_num_local++);
|
||||||
|
@ -289,16 +407,22 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *taki
|
||||||
memcpy(msg_payload + 9, buf, buf_size);
|
memcpy(msg_payload + 9, buf, buf_size);
|
||||||
|
|
||||||
// TODO: instead of just sending and forgetting about it, make sure to receive data ack, resend if necessary, etc.
|
// TODO: instead of just sending and forgetting about it, make sure to receive data ack, resend if necessary, etc.
|
||||||
ChiakiErrorCode err = chiaki_takion_send_raw(takion, packet_buf, packet_size);
|
err = chiaki_takion_send(takion, packet_buf, packet_size);
|
||||||
free(packet_buf);
|
free(packet_buf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion, uint32_t key_pos, uint8_t type_b, uint16_t channel, uint32_t seq_num)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint32_t seq_num)
|
||||||
{
|
{
|
||||||
uint8_t buf[1 + MESSAGE_HEADER_SIZE + 0xc];
|
uint8_t buf[1 + MESSAGE_HEADER_SIZE + 0xc];
|
||||||
buf[0] = TAKION_PACKET_TYPE_MESSAGE;
|
buf[0] = TAKION_PACKET_TYPE_CONTROL;
|
||||||
takion_write_message_header(buf + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_DATA_ACK, 0, 0xc);
|
|
||||||
|
size_t key_pos;
|
||||||
|
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, sizeof(buf), &key_pos);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
takion_write_message_header(buf + 1, takion->tag_remote, key_pos, TAKION_MESSAGE_TYPE_A_DATA_ACK, type_b, 0xc);
|
||||||
|
|
||||||
uint8_t *data_ack = buf + 1 + MESSAGE_HEADER_SIZE;
|
uint8_t *data_ack = buf + 1 + MESSAGE_HEADER_SIZE;
|
||||||
*((uint32_t *)(data_ack + 0)) = htonl(seq_num);
|
*((uint32_t *)(data_ack + 0)) = htonl(seq_num);
|
||||||
|
@ -306,14 +430,14 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *
|
||||||
*((uint16_t *)(data_ack + 8)) = 0;
|
*((uint16_t *)(data_ack + 8)) = 0;
|
||||||
*((uint16_t *)(data_ack + 0xa)) = 0;
|
*((uint16_t *)(data_ack + 0xa)) = 0;
|
||||||
|
|
||||||
return chiaki_takion_send_raw(takion, buf, sizeof(buf));
|
return chiaki_takion_send(takion, buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet)
|
||||||
{
|
{
|
||||||
uint8_t buf[0xf];
|
uint8_t buf[0xf];
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
buf[0] = 5;
|
buf[0] = TAKION_PACKET_TYPE_CONGESTION;
|
||||||
*((uint16_t *)(buf + 1)) = htons(packet->word_0);
|
*((uint16_t *)(buf + 1)) = htons(packet->word_0);
|
||||||
*((uint16_t *)(buf + 3)) = htons(packet->word_1);
|
*((uint16_t *)(buf + 3)) = htons(packet->word_1);
|
||||||
*((uint16_t *)(buf + 5)) = htons(packet->word_2);
|
*((uint16_t *)(buf + 5)) = htons(packet->word_2);
|
||||||
|
@ -393,7 +517,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
|
||||||
size_t key_pos_offset;
|
size_t key_pos_offset;
|
||||||
switch(base_type)
|
switch(base_type)
|
||||||
{
|
{
|
||||||
case TAKION_PACKET_TYPE_MESSAGE:
|
case TAKION_PACKET_TYPE_CONTROL:
|
||||||
mac_offset = 5;
|
mac_offset = 5;
|
||||||
key_pos_offset = 0x9;
|
key_pos_offset = 0x9;
|
||||||
break;
|
break;
|
||||||
|
@ -403,7 +527,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
|
||||||
key_pos_offset = 0xe;
|
key_pos_offset = 0xe;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CHIAKI_LOGW(takion->log, "Takion packet with unknown type %#x received\n", base_type);
|
CHIAKI_LOGW(takion->log, "Takion packet with unknown type (for gmac) %#x received\n", base_type);
|
||||||
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_WARNING, buf, buf_size);
|
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_WARNING, buf, buf_size);
|
||||||
return CHIAKI_ERR_INVALID_DATA;
|
return CHIAKI_ERR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +538,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t key_pos = ntohl(*((uint32_t *)(buf + key_pos_offset)));
|
uint32_t key_pos = ntohl(*((uint32_t *)(buf + key_pos_offset)));
|
||||||
if(base_type == TAKION_PACKET_TYPE_MESSAGE)
|
if(base_type == TAKION_PACKET_TYPE_CONTROL)
|
||||||
memset(buf + key_pos_offset, 0, sizeof(uint32_t));
|
memset(buf + key_pos_offset, 0, sizeof(uint32_t));
|
||||||
|
|
||||||
uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE];
|
uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE];
|
||||||
|
@ -458,7 +582,7 @@ static void takion_handle_packet(ChiakiTakion *takion, uint8_t *buf, size_t buf_
|
||||||
|
|
||||||
switch(base_type)
|
switch(base_type)
|
||||||
{
|
{
|
||||||
case TAKION_PACKET_TYPE_MESSAGE:
|
case TAKION_PACKET_TYPE_CONTROL:
|
||||||
takion_handle_packet_message(takion, buf, buf_size);
|
takion_handle_packet_message(takion, buf, buf_size);
|
||||||
break;
|
break;
|
||||||
case TAKION_PACKET_TYPE_VIDEO:
|
case TAKION_PACKET_TYPE_VIDEO:
|
||||||
|
@ -525,7 +649,7 @@ static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type
|
||||||
takion->data_cb((ChiakiTakionMessageDataType)data_type, data, data_size, takion->data_cb_user);
|
takion->data_cb((ChiakiTakionMessageDataType)data_type, data, data_size, takion->data_cb_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
chiaki_takion_send_message_data_ack(takion, 0, 0, channel, seq_num);
|
chiaki_takion_send_message_data_ack(takion, 0, channel, seq_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size)
|
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size)
|
||||||
|
@ -563,12 +687,9 @@ static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t
|
||||||
*
|
*
|
||||||
* @param raw_payload_size size of the actual data of the payload excluding type_a, type_b and payload_size
|
* @param raw_payload_size size of the actual data of the payload excluding type_a, type_b and payload_size
|
||||||
*/
|
*/
|
||||||
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint8_t *mac, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size)
|
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size)
|
||||||
{
|
{
|
||||||
*((uint32_t *)(buf + 0)) = htonl(tag);
|
*((uint32_t *)(buf + 0)) = htonl(tag);
|
||||||
if(mac)
|
|
||||||
memcpy(buf + 4, mac, CHIAKI_GKCRYPT_GMAC_SIZE);
|
|
||||||
else
|
|
||||||
memset(buf + 4, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
|
memset(buf + 4, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
|
||||||
*((uint32_t *)(buf + 8)) = htonl(key_pos);
|
*((uint32_t *)(buf + 8)) = htonl(key_pos);
|
||||||
*(buf + 0xc) = type_a;
|
*(buf + 0xc) = type_a;
|
||||||
|
@ -616,8 +737,8 @@ static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf,
|
||||||
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload)
|
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload)
|
||||||
{
|
{
|
||||||
uint8_t message[1 + MESSAGE_HEADER_SIZE + 0x10];
|
uint8_t message[1 + MESSAGE_HEADER_SIZE + 0x10];
|
||||||
message[0] = TAKION_PACKET_TYPE_MESSAGE;
|
message[0] = TAKION_PACKET_TYPE_CONTROL;
|
||||||
takion_write_message_header(message + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_INIT, 0, 0x10);
|
takion_write_message_header(message + 1, takion->tag_remote, 0, TAKION_MESSAGE_TYPE_A_INIT, 0, 0x10);
|
||||||
|
|
||||||
uint8_t *pl = message + 1 + MESSAGE_HEADER_SIZE;
|
uint8_t *pl = message + 1 + MESSAGE_HEADER_SIZE;
|
||||||
*((uint32_t *)(pl + 0)) = htonl(payload->tag0);
|
*((uint32_t *)(pl + 0)) = htonl(payload->tag0);
|
||||||
|
@ -634,8 +755,8 @@ static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMess
|
||||||
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie)
|
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie)
|
||||||
{
|
{
|
||||||
uint8_t message[1 + MESSAGE_HEADER_SIZE + TAKION_COOKIE_SIZE];
|
uint8_t message[1 + MESSAGE_HEADER_SIZE + TAKION_COOKIE_SIZE];
|
||||||
message[0] = TAKION_PACKET_TYPE_MESSAGE;
|
message[0] = TAKION_PACKET_TYPE_CONTROL;
|
||||||
takion_write_message_header(message + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_COOKIE, 0, TAKION_COOKIE_SIZE);
|
takion_write_message_header(message + 1, takion->tag_remote, 0, TAKION_MESSAGE_TYPE_A_COOKIE, 0, TAKION_COOKIE_SIZE);
|
||||||
memcpy(message + 1 + MESSAGE_HEADER_SIZE, cookie, TAKION_COOKIE_SIZE);
|
memcpy(message + 1 + MESSAGE_HEADER_SIZE, cookie, TAKION_COOKIE_SIZE);
|
||||||
return chiaki_takion_send_raw(takion, message, sizeof(message));
|
return chiaki_takion_send_raw(takion, message, sizeof(message));
|
||||||
}
|
}
|
||||||
|
@ -656,9 +777,9 @@ static ChiakiErrorCode takion_recv_message_init_ack(ChiakiTakion *takion, Takion
|
||||||
return CHIAKI_ERR_INVALID_RESPONSE;
|
return CHIAKI_ERR_INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message[0] != TAKION_PACKET_TYPE_MESSAGE)
|
if(message[0] != TAKION_PACKET_TYPE_CONTROL)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting init ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_MESSAGE);
|
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting init ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_CONTROL);
|
||||||
return CHIAKI_ERR_INVALID_RESPONSE;
|
return CHIAKI_ERR_INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,9 +825,9 @@ static ChiakiErrorCode takion_recv_message_cookie_ack(ChiakiTakion *takion)
|
||||||
return CHIAKI_ERR_INVALID_RESPONSE;
|
return CHIAKI_ERR_INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message[0] != TAKION_PACKET_TYPE_MESSAGE)
|
if(message[0] != TAKION_PACKET_TYPE_CONTROL)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting cookie ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_MESSAGE);
|
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting cookie ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_CONTROL);
|
||||||
return CHIAKI_ERR_INVALID_RESPONSE;
|
return CHIAKI_ERR_INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue