mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -07:00
Finish Senkusha
This commit is contained in:
parent
ab740fbe58
commit
7e235fc405
7 changed files with 249 additions and 43 deletions
|
@ -56,7 +56,7 @@ typedef struct senkusha_t
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session);
|
||||||
CHIAKI_EXPORT void chiaki_senkusha_fini(ChiakiSenkusha *senkusha);
|
CHIAKI_EXPORT void chiaki_senkusha_fini(ChiakiSenkusha *senkusha);
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha, uint32_t *mtu_in, uint32_t *mtu_out, uint64_t *rtt_us);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,8 +147,9 @@ typedef struct chiaki_session_t
|
||||||
ChiakiRPCrypt rpcrypt;
|
ChiakiRPCrypt rpcrypt;
|
||||||
char session_id[CHIAKI_SESSION_ID_SIZE_MAX]; // zero-terminated
|
char session_id[CHIAKI_SESSION_ID_SIZE_MAX]; // zero-terminated
|
||||||
uint8_t handshake_key[CHIAKI_HANDSHAKE_KEY_SIZE];
|
uint8_t handshake_key[CHIAKI_HANDSHAKE_KEY_SIZE];
|
||||||
unsigned int mtu;
|
uint32_t mtu_in;
|
||||||
unsigned int rtt;
|
uint32_t mtu_out;
|
||||||
|
uint64_t rtt_us;
|
||||||
ChiakiECDH ecdh;
|
ChiakiECDH ecdh;
|
||||||
|
|
||||||
ChiakiQuitReason quit_reason;
|
ChiakiQuitReason quit_reason;
|
||||||
|
|
|
@ -228,8 +228,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *ta
|
||||||
*/
|
*/
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, uint8_t *payload, size_t payload_size);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, uint8_t *payload, size_t payload_size);
|
||||||
|
|
||||||
|
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_VIDEO 0x17
|
||||||
|
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_AUDIO 0x12
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
|
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE 0x12
|
||||||
|
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_VIDEO_ADD 0x3
|
||||||
|
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_NALU_INFO_STRUCTS_ADD 0x3
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *buf, size_t buf_size, size_t *header_size_out, ChiakiTakionAVPacket *packet);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *buf, size_t buf_size, size_t *header_size_out, ChiakiTakionAVPacket *packet);
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
|
||||||
|
|
|
@ -40,17 +40,27 @@
|
||||||
#define SENKUSHA_PING_COUNT_DEFAULT 10
|
#define SENKUSHA_PING_COUNT_DEFAULT 10
|
||||||
#define EXPECT_PONG_TIMEOUT_MS 1000
|
#define EXPECT_PONG_TIMEOUT_MS 1000
|
||||||
|
|
||||||
|
// Assuming IPv4, sizeof(ip header) + sizeof(udp header)
|
||||||
|
#define MTU_UDP_PACKET_ADD 0x1c
|
||||||
|
|
||||||
|
#define MTU_AV_PACKET_ADD CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE
|
||||||
|
|
||||||
|
// Amount of bytes to add to AV data size for MTU pings to get the full size of the ip packet for MTU
|
||||||
|
#define MTU_PING_DATA_ADD (MTU_UDP_PACKET_ADD + MTU_AV_PACKET_ADD)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
STATE_TAKION_CONNECT,
|
STATE_TAKION_CONNECT,
|
||||||
STATE_EXPECT_BANG,
|
STATE_EXPECT_BANG,
|
||||||
STATE_EXPECT_DATA_ACK,
|
STATE_EXPECT_DATA_ACK,
|
||||||
STATE_EXPECT_PONG,
|
STATE_EXPECT_PONG,
|
||||||
STATE_EXPECT_MTU
|
STATE_EXPECT_MTU,
|
||||||
|
STATE_EXPECT_CLIENT_MTU_COMMAND
|
||||||
} SenkushaState;
|
} SenkushaState;
|
||||||
|
|
||||||
static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t ping_test_index, uint16_t ping_count);
|
static ChiakiErrorCode senkusha_run_rtt_test(ChiakiSenkusha *senkusha, uint16_t ping_test_index, uint16_t ping_count, uint64_t *rtt_us);
|
||||||
static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu);
|
static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu);
|
||||||
|
static ChiakiErrorCode senkusha_run_mtu_out_test(ChiakiSenkusha *senkusha, uint32_t mtu_in, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu);
|
||||||
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user);
|
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user);
|
||||||
static void senkusha_takion_data(ChiakiSenkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
|
static void senkusha_takion_data(ChiakiSenkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
|
||||||
static void senkusha_takion_data_ack(ChiakiSenkusha *senkusha, ChiakiSeqNum32 seq_num);
|
static void senkusha_takion_data_ack(ChiakiSenkusha *senkusha, ChiakiSeqNum32 seq_num);
|
||||||
|
@ -59,7 +69,7 @@ static ChiakiErrorCode senkusha_send_big(ChiakiSenkusha *senkusha);
|
||||||
static ChiakiErrorCode senkusha_send_disconnect(ChiakiSenkusha *senkusha);
|
static ChiakiErrorCode senkusha_send_disconnect(ChiakiSenkusha *senkusha);
|
||||||
static ChiakiErrorCode senkusha_send_echo_command(ChiakiSenkusha *senkusha, bool enable);
|
static ChiakiErrorCode senkusha_send_echo_command(ChiakiSenkusha *senkusha, bool enable);
|
||||||
static ChiakiErrorCode senkusha_send_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaMtuCommand *command);
|
static ChiakiErrorCode senkusha_send_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaMtuCommand *command);
|
||||||
static ChiakiErrorCode senkusha_send_client_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaClientMtuCommand *command);
|
static ChiakiErrorCode senkusha_send_client_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaClientMtuCommand *command, bool wait_for_ack);
|
||||||
static ChiakiErrorCode senkusha_send_data_wait_for_ack(ChiakiSenkusha *senkusha, uint8_t *buf, size_t buf_size);
|
static ChiakiErrorCode senkusha_send_data_wait_for_ack(ChiakiSenkusha *senkusha, uint8_t *buf, size_t buf_size);
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session)
|
||||||
|
@ -103,7 +113,7 @@ static bool state_finished_cond_check(void *user)
|
||||||
return senkusha->state_finished || senkusha->should_stop;
|
return senkusha->state_finished || senkusha->should_stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha, uint32_t *mtu_in, uint32_t *mtu_out, uint64_t *rtt_us)
|
||||||
{
|
{
|
||||||
ChiakiSession *session = senkusha->session;
|
ChiakiSession *session = senkusha->session;
|
||||||
ChiakiErrorCode err;
|
ChiakiErrorCode err;
|
||||||
|
@ -199,19 +209,30 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha)
|
||||||
|
|
||||||
CHIAKI_LOGI(session->log, "Senkusha successfully received bang");
|
CHIAKI_LOGI(session->log, "Senkusha successfully received bang");
|
||||||
|
|
||||||
err = senkusha_run_ping_test(senkusha, 0, SENKUSHA_PING_COUNT_DEFAULT);
|
err = senkusha_run_rtt_test(senkusha, 0, SENKUSHA_PING_COUNT_DEFAULT, rtt_us);
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(senkusha->log, "Senkusha Ping Test failed");
|
CHIAKI_LOGE(senkusha->log, "Senkusha Ping Test failed");
|
||||||
goto disconnect;
|
goto disconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: timeout should be measured rtt * 5
|
uint64_t mtu_timeout_ms = (*rtt_us * 5) / 1000;
|
||||||
uint32_t mtu_in;
|
if(mtu_timeout_ms < 5)
|
||||||
err = senkusha_run_mtu_in_test(senkusha, 576, 1454, 3, 200, &mtu_in);
|
mtu_timeout_ms = 5;
|
||||||
|
if(mtu_timeout_ms > 500)
|
||||||
|
mtu_timeout_ms = 500;
|
||||||
|
|
||||||
|
err = senkusha_run_mtu_in_test(senkusha, 576, 1454, 3, mtu_timeout_ms, mtu_in);
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(senkusha->log, "Senkusha MTU test failed");
|
CHIAKI_LOGE(senkusha->log, "Senkusha MTU in test failed");
|
||||||
|
goto disconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = senkusha_run_mtu_out_test(senkusha, *mtu_in, 576, 1454, 3, mtu_timeout_ms, mtu_out);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha MTU out test failed");
|
||||||
goto disconnect;
|
goto disconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +249,7 @@ quit:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t ping_test_index, uint16_t ping_count)
|
static ChiakiErrorCode senkusha_run_rtt_test(ChiakiSenkusha *senkusha, uint16_t ping_test_index, uint16_t ping_count, uint64_t *rtt_us)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha Ping Test with count %u starting", (unsigned int)ping_count);
|
CHIAKI_LOGI(senkusha->log, "Senkusha Ping Test with count %u starting", (unsigned int)ping_count);
|
||||||
|
|
||||||
|
@ -241,6 +262,8 @@ static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t
|
||||||
|
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha enabled echo");
|
CHIAKI_LOGI(senkusha->log, "Senkusha enabled echo");
|
||||||
|
|
||||||
|
uint64_t rtt_us_acc = 0;
|
||||||
|
uint64_t pings_successful = 0;
|
||||||
for(uint16_t ping_index=0; ping_index<ping_count; ping_index++)
|
for(uint16_t ping_index=0; ping_index<ping_count; ping_index++)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha sending Ping %u of test index %u", (unsigned int)ping_index, (unsigned int)ping_test_index);
|
CHIAKI_LOGI(senkusha->log, "Senkusha sending Ping %u of test index %u", (unsigned int)ping_index, (unsigned int)ping_test_index);
|
||||||
|
@ -263,7 +286,7 @@ static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tag = 0x1337; //chiaki_random_32();
|
uint32_t tag = chiaki_random_32();
|
||||||
*((uint32_t *)(data + header_size + 4)) = htonl(tag);
|
*((uint32_t *)(data + header_size + 4)) = htonl(tag);
|
||||||
|
|
||||||
senkusha->state = STATE_EXPECT_PONG;
|
senkusha->state = STATE_EXPECT_PONG;
|
||||||
|
@ -299,6 +322,8 @@ static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t delta_us = senkusha->pong_time_us - time_start_us;
|
uint64_t delta_us = senkusha->pong_time_us - time_start_us;
|
||||||
|
rtt_us_acc += delta_us;
|
||||||
|
pings_successful += 1;
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha received Pong, RTT = %.3f ms", (float)delta_us * 0.001f);
|
CHIAKI_LOGI(senkusha->log, "Senkusha received Pong, RTT = %.3f ms", (float)delta_us * 0.001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,12 +336,21 @@ static ChiakiErrorCode senkusha_run_ping_test(ChiakiSenkusha *senkusha, uint16_t
|
||||||
|
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha disabled echo");
|
CHIAKI_LOGI(senkusha->log, "Senkusha disabled echo");
|
||||||
|
|
||||||
|
if(pings_successful < 1)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha Ping test did not receive a single Pong");
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
*rtt_us = rtt_us_acc / pings_successful;
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha determined average RTT = %.3f ms", (float)(*rtt_us) * 0.001f);
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu)
|
static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha starting MTU test with min %u, max %u, retries %u, timeout %llu ms",
|
CHIAKI_LOGI(senkusha->log, "Senkusha starting MTU in test with min %u, max %u, retries %u, timeout %llu ms",
|
||||||
(unsigned int)min, (unsigned int)max, (unsigned int)retries, (unsigned long long)timeout_ms);
|
(unsigned int)min, (unsigned int)max, (unsigned int)retries, (unsigned long long)timeout_ms);
|
||||||
|
|
||||||
uint32_t cur = max;
|
uint32_t cur = max;
|
||||||
|
@ -328,6 +362,7 @@ static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32
|
||||||
{
|
{
|
||||||
senkusha->state = STATE_EXPECT_MTU;
|
senkusha->state = STATE_EXPECT_MTU;
|
||||||
senkusha->state_finished = false;
|
senkusha->state_finished = false;
|
||||||
|
senkusha->state_failed = false;
|
||||||
senkusha->mtu_id = ++request_id;
|
senkusha->mtu_id = ++request_id;
|
||||||
|
|
||||||
tkproto_SenkushaMtuCommand mtu_cmd;
|
tkproto_SenkushaMtuCommand mtu_cmd;
|
||||||
|
@ -373,19 +408,161 @@ static ChiakiErrorCode senkusha_run_mtu_in_test(ChiakiSenkusha *senkusha, uint32
|
||||||
cur = min + (max - min) / 2;
|
cur = min + (max - min) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_LOGI(senkusha->log, "Senkusha determined MTU %u", (unsigned int)max);
|
CHIAKI_LOGI(senkusha->log, "Senkusha determined inbound MTU %u", (unsigned int)max);
|
||||||
*mtu = max;
|
*mtu = max;
|
||||||
|
|
||||||
/*tkproto_SenkushaClientMtuCommand client_mtu_cmd;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChiakiErrorCode senkusha_run_mtu_out_test(ChiakiSenkusha *senkusha, uint32_t mtu_in, uint32_t min, uint32_t max, uint32_t retries, uint64_t timeout_ms, uint32_t *mtu)
|
||||||
|
{
|
||||||
|
if(min < 8 + MTU_PING_DATA_ADD || max < min || mtu_in < min || mtu_in > max)
|
||||||
|
return CHIAKI_ERR_INVALID_DATA;
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha starting MTU out test with min %u, max %u, retries %u, timeout %llu ms",
|
||||||
|
(unsigned int)min, (unsigned int)max, (unsigned int)retries, (unsigned long long)timeout_ms);
|
||||||
|
|
||||||
|
senkusha->state = STATE_EXPECT_CLIENT_MTU_COMMAND;
|
||||||
|
senkusha->state_finished = false;
|
||||||
|
senkusha->state_failed = false;
|
||||||
|
senkusha->mtu_id = 1;
|
||||||
|
|
||||||
|
tkproto_SenkushaClientMtuCommand client_mtu_cmd;
|
||||||
|
client_mtu_cmd.id = senkusha->mtu_id;
|
||||||
|
client_mtu_cmd.state = true;
|
||||||
|
client_mtu_cmd.mtu_req = mtu_in;
|
||||||
|
client_mtu_cmd.has_mtu_down = true;
|
||||||
|
client_mtu_cmd.mtu_down = mtu_in;
|
||||||
|
ChiakiErrorCode err = senkusha_send_client_mtu_command(senkusha, &client_mtu_cmd, false);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to send client MTU command");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha sent initial client MTU command");
|
||||||
|
|
||||||
|
err = chiaki_cond_timedwait_pred(&senkusha->state_cond, &senkusha->state_mutex, EXPECT_TIMEOUT_MS, state_finished_cond_check, senkusha);
|
||||||
|
assert(err == CHIAKI_ERR_SUCCESS || err == CHIAKI_ERR_TIMEOUT);
|
||||||
|
|
||||||
|
if(!senkusha->state_finished)
|
||||||
|
{
|
||||||
|
if(err == CHIAKI_ERR_TIMEOUT)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha Client MTU Command from server receive timeout");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(senkusha->should_stop)
|
||||||
|
return CHIAKI_ERR_CANCELED;
|
||||||
|
else
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to receive Client MTU command");
|
||||||
|
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t packet_buf_size = max - MTU_UDP_PACKET_ADD;
|
||||||
|
uint8_t *packet_buf = malloc(packet_buf_size);
|
||||||
|
if(!packet_buf)
|
||||||
|
return CHIAKI_ERR_MEMORY;
|
||||||
|
memset(packet_buf, 0, MTU_AV_PACKET_ADD + 8);
|
||||||
|
static const char padding[] = { 'C', 'H', 'I', 'A', 'K', 'I' };
|
||||||
|
for(size_t i=0; i<packet_buf_size - (MTU_AV_PACKET_ADD + 8); i++)
|
||||||
|
packet_buf[i + (MTU_AV_PACKET_ADD + 8)] = padding[i % sizeof(padding)];
|
||||||
|
|
||||||
|
err = CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
uint32_t cur = mtu_in;
|
||||||
|
while(max > min)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
for(uint32_t attempt=0; attempt<retries; attempt++)
|
||||||
|
{
|
||||||
|
uint32_t tag = chiaki_random_32();
|
||||||
|
|
||||||
|
senkusha->state = STATE_EXPECT_PONG;
|
||||||
|
senkusha->state_finished = false;
|
||||||
|
senkusha->state_failed = false;
|
||||||
|
senkusha->ping_tag = tag;
|
||||||
|
senkusha->ping_test_index = 0;
|
||||||
|
senkusha->ping_index = (uint16_t)attempt;
|
||||||
|
|
||||||
|
ChiakiTakionAVPacket av_packet = { 0 };
|
||||||
|
av_packet.codec = 0xff;
|
||||||
|
av_packet.is_video = false;
|
||||||
|
av_packet.frame_index = senkusha->ping_test_index;
|
||||||
|
av_packet.unit_index = senkusha->ping_index;
|
||||||
|
av_packet.units_in_frame_total = 0x800;
|
||||||
|
|
||||||
|
size_t header_size;
|
||||||
|
err = chiaki_takion_v7_av_packet_format_header(packet_buf, packet_buf_size, &header_size, &av_packet);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to format AV Header");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
assert(header_size == MTU_AV_PACKET_ADD);
|
||||||
|
|
||||||
|
*((uint32_t *)(packet_buf + MTU_AV_PACKET_ADD)) = 0;
|
||||||
|
*((uint32_t *)(packet_buf + MTU_AV_PACKET_ADD + 4)) = htonl(tag);
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha MTU %u out ping attempt %u", (unsigned int)cur, (unsigned int)attempt);
|
||||||
|
|
||||||
|
err = chiaki_takion_send_raw(&senkusha->takion, packet_buf, cur - MTU_UDP_PACKET_ADD);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to send ping");
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = chiaki_cond_timedwait_pred(&senkusha->state_cond, &senkusha->state_mutex, timeout_ms, state_finished_cond_check, senkusha);
|
||||||
|
assert(err == CHIAKI_ERR_SUCCESS || err == CHIAKI_ERR_TIMEOUT);
|
||||||
|
|
||||||
|
if(!senkusha->state_finished)
|
||||||
|
{
|
||||||
|
if(err == CHIAKI_ERR_TIMEOUT)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha MTU pong %u timeout", (unsigned int)cur);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(senkusha->should_stop)
|
||||||
|
{
|
||||||
|
err = CHIAKI_ERR_CANCELED;
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to receive MTU pong");
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha MTU ping %u success", (unsigned int)cur);
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(success)
|
||||||
|
min = cur + 1;
|
||||||
|
else
|
||||||
|
max = cur - 1;
|
||||||
|
cur = min + (max - min) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha determined outbound MTU %u", (unsigned int)max);
|
||||||
|
*mtu = max;
|
||||||
|
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha sending final Client MTU Command");
|
||||||
client_mtu_cmd.id = 2;
|
client_mtu_cmd.id = 2;
|
||||||
client_mtu_cmd.state = false;
|
client_mtu_cmd.state = false;
|
||||||
client_mtu_cmd.mtu_req = 1454;
|
client_mtu_cmd.mtu_req = max;
|
||||||
client_mtu_cmd.has_mtu_down = true;
|
client_mtu_cmd.has_mtu_down = true;
|
||||||
client_mtu_cmd.mtu_down = 1454;
|
client_mtu_cmd.mtu_down = mtu_in;
|
||||||
ChiakiErrorCode err = senkusha_send_client_mtu_command(senkusha, &client_mtu_cmd);
|
err = senkusha_send_client_mtu_command(senkusha, &client_mtu_cmd, true);
|
||||||
CHIAKI_LOGD(senkusha->log, "MTU result: %d\n", err);*/
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha failed to send client MTU command");
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
beach:
|
||||||
|
free(packet_buf);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user)
|
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user)
|
||||||
|
@ -447,6 +624,30 @@ static void senkusha_takion_data(ChiakiSenkusha *senkusha, ChiakiTakionMessageDa
|
||||||
chiaki_cond_signal(&senkusha->state_cond);
|
chiaki_cond_signal(&senkusha->state_cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(senkusha->state == STATE_EXPECT_CLIENT_MTU_COMMAND)
|
||||||
|
{
|
||||||
|
if(msg.type != tkproto_TakionMessage_PayloadType_SENKUSHA
|
||||||
|
|| !msg.has_senkusha_payload
|
||||||
|
|| msg.senkusha_payload.command != tkproto_SenkushaPayload_Command_CLIENT_MTU_COMMAND
|
||||||
|
|| !msg.senkusha_payload.has_client_mtu_command
|
||||||
|
|| msg.senkusha_payload.client_mtu_command.id != senkusha->mtu_id)
|
||||||
|
{
|
||||||
|
// There might be another MTU_COMMAND from the server, which we ignore, but this is not an error.
|
||||||
|
if(msg.type != tkproto_TakionMessage_PayloadType_SENKUSHA
|
||||||
|
|| !msg.has_senkusha_payload
|
||||||
|
|| msg.senkusha_payload.command != tkproto_SenkushaPayload_Command_MTU_COMMAND)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(senkusha->log, "Senkusha expected Client MTU Command with matching id but received something else");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CHIAKI_LOGI(senkusha->log, "Senkusha received expected Client MTU Command");
|
||||||
|
senkusha->state_finished = true;
|
||||||
|
chiaki_cond_signal(&senkusha->state_cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
chiaki_mutex_unlock(&senkusha->state_mutex);
|
chiaki_mutex_unlock(&senkusha->state_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +673,8 @@ static void senkusha_takion_av(ChiakiSenkusha *senkusha, ChiakiTakionAVPacket *p
|
||||||
|
|
||||||
if(senkusha->state == STATE_EXPECT_PONG)
|
if(senkusha->state == STATE_EXPECT_PONG)
|
||||||
{
|
{
|
||||||
if(packet->frame_index != senkusha->ping_test_index
|
if(packet->is_video
|
||||||
|
|| packet->frame_index != senkusha->ping_test_index
|
||||||
|| packet->unit_index != senkusha->ping_index
|
|| packet->unit_index != senkusha->ping_index
|
||||||
|| packet->data_size < 8)
|
|| packet->data_size < 8)
|
||||||
{
|
{
|
||||||
|
@ -623,7 +825,7 @@ static ChiakiErrorCode senkusha_send_mtu_command(ChiakiSenkusha *senkusha, tkpro
|
||||||
return chiaki_takion_send_message_data(&senkusha->takion, 1, 8, buf, stream.bytes_written, NULL);
|
return chiaki_takion_send_message_data(&senkusha->takion, 1, 8, buf, stream.bytes_written, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChiakiErrorCode senkusha_send_client_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaClientMtuCommand *command)
|
static ChiakiErrorCode senkusha_send_client_mtu_command(ChiakiSenkusha *senkusha, tkproto_SenkushaClientMtuCommand *command, bool wait_for_ack)
|
||||||
{
|
{
|
||||||
tkproto_TakionMessage msg;
|
tkproto_TakionMessage msg;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
@ -643,6 +845,9 @@ static ChiakiErrorCode senkusha_send_client_mtu_command(ChiakiSenkusha *senkusha
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!wait_for_ack)
|
||||||
|
return chiaki_takion_send_message_data(&senkusha->takion, 1, 8, buf, stream.bytes_written, NULL);
|
||||||
|
|
||||||
return senkusha_send_data_wait_for_ack(senkusha, buf, stream.bytes_written);
|
return senkusha_send_data_wait_for_ack(senkusha, buf, stream.bytes_written);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -317,22 +317,22 @@ static void *session_thread_func(void *arg)
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
QUIT(quit_ctrl);
|
QUIT(quit_ctrl);
|
||||||
|
|
||||||
err = chiaki_senkusha_run(&senkusha);
|
err = chiaki_senkusha_run(&senkusha, &session->mtu_in, &session->mtu_out, &session->rtt_us);
|
||||||
chiaki_senkusha_fini(&senkusha);
|
chiaki_senkusha_fini(&senkusha);
|
||||||
|
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err == CHIAKI_ERR_SUCCESS)
|
||||||
{
|
CHIAKI_LOGI(session->log, "Senkusha completed successfully");
|
||||||
CHIAKI_LOGE(session->log, "Senkusha failed");
|
else if(err == CHIAKI_ERR_CANCELED)
|
||||||
QUIT(quit_ctrl);
|
QUIT(quit_ctrl);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(session->log, "Senkusha failed, but we still try to connect with fallback values");
|
||||||
|
session->mtu_in = 1454;
|
||||||
|
session->mtu_out = 1454;
|
||||||
|
session->rtt_us = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_LOGI(session->log, "Senkusha completed successfully");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Senkusha should set that
|
|
||||||
session->mtu = 1454;
|
|
||||||
session->rtt = 12;
|
|
||||||
|
|
||||||
err = chiaki_random_bytes_crypt(session->handshake_key, sizeof(session->handshake_key));
|
err = chiaki_random_bytes_crypt(session->handshake_key, sizeof(session->handshake_key));
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -646,8 +646,8 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream
|
||||||
ChiakiSession *session = stream_connection->session;
|
ChiakiSession *session = stream_connection->session;
|
||||||
|
|
||||||
ChiakiLaunchSpec launch_spec;
|
ChiakiLaunchSpec launch_spec;
|
||||||
launch_spec.mtu = session->mtu;
|
launch_spec.mtu = session->mtu_in;
|
||||||
launch_spec.rtt = session->rtt;
|
launch_spec.rtt = session->rtt_us / 1000;
|
||||||
launch_spec.handshake_key = session->handshake_key;
|
launch_spec.handshake_key = session->handshake_key;
|
||||||
|
|
||||||
launch_spec.width = session->connect_info.video_profile.width;
|
launch_spec.width = session->connect_info.video_profile.width;
|
||||||
|
|
|
@ -1180,9 +1180,6 @@ static void takion_handle_packet_av(ChiakiTakion *takion, uint8_t base_type, uin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_VIDEO 0x17
|
|
||||||
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_AUDIO 0x12
|
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
memset(packet, 0, sizeof(ChiakiTakionAVPacket));
|
memset(packet, 0, sizeof(ChiakiTakionAVPacket));
|
||||||
|
@ -1266,10 +1263,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPac
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE 0x12
|
|
||||||
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_VIDEO_ADD 0x3
|
|
||||||
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_NALU_INFO_STRUCTS_ADD 0x3
|
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *buf, size_t buf_size, size_t *header_size_out, ChiakiTakionAVPacket *packet)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *buf, size_t buf_size, size_t *header_size_out, ChiakiTakionAVPacket *packet)
|
||||||
{
|
{
|
||||||
size_t header_size = CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE;
|
size_t header_size = CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue