|
|
|
|
@ -39,6 +39,18 @@ void stcp_conn_free(struct stcp_conn *c) {
|
|
|
|
|
if (c->allocated) u_free(c); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stcp_check_crc(const uint8_t *data, size_t data_len) { |
|
|
|
|
uint32_t recv_crc = ((uint32_t)data[data_len]) | ((uint32_t)data[data_len + 1] << 8) | |
|
|
|
|
((uint32_t)data[data_len + 2] << 16) | ((uint32_t)data[data_len + 3] << 24); |
|
|
|
|
uint32_t calc_crc = crc32_calc(data, data_len); |
|
|
|
|
if (recv_crc != calc_crc) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "stcp CRC mismatch recv=%08x calc=%08x data_len=%zu", |
|
|
|
|
recv_crc, calc_crc, data_len); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int stcp_frame_encrypt(struct stcp_conn *c, const uint8_t *data, size_t data_len, uint8_t *output, size_t *output_len) { |
|
|
|
|
uint32_t crc = crc32_calc(data, data_len); |
|
|
|
|
output[0] = (uint8_t)(data_len >> 0); |
|
|
|
|
@ -64,13 +76,7 @@ int stcp_frame_decrypt(uint8_t *data, size_t len, struct sc_stream_state *stream
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
size_t data_len = len - SC_CRC32_SIZE; |
|
|
|
|
uint32_t recv_crc = ((uint32_t)data[data_len]) | ((uint32_t)data[data_len + 1] << 8) | |
|
|
|
|
((uint32_t)data[data_len + 2] << 16) | ((uint32_t)data[data_len + 3] << 24); |
|
|
|
|
uint32_t calc_crc = crc32_calc(data, data_len); |
|
|
|
|
if (recv_crc != calc_crc) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "stcp_frame_decrypt CRC mismatch recv=%08x calc=%08x", recv_crc, calc_crc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (stcp_check_crc(data, data_len) != 0) return -1; |
|
|
|
|
*out_len = data_len; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
@ -249,13 +255,7 @@ void stcp_recv_try(struct stcp_conn *c) {
|
|
|
|
|
|
|
|
|
|
size_t data_len = (size_t)c->recv_msg_size; |
|
|
|
|
uint8_t *plain = c->recv_buf + 2; |
|
|
|
|
uint32_t recv_crc = ((uint32_t)plain[data_len]) | ((uint32_t)plain[data_len + 1] << 8) | |
|
|
|
|
((uint32_t)plain[data_len + 2] << 16) | ((uint32_t)plain[data_len + 3] << 24); |
|
|
|
|
uint32_t calc_crc = crc32_calc(plain, data_len); |
|
|
|
|
if (recv_crc != calc_crc) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "stcp_recv_try CRC mismatch recv=%08x calc=%08x data_len=%zu", recv_crc, calc_crc, data_len); |
|
|
|
|
stcp_conn_do_close(c, 5); return; |
|
|
|
|
} |
|
|
|
|
if (stcp_check_crc(plain, data_len) != 0) { stcp_conn_do_close(c, 5); return; } |
|
|
|
|
|
|
|
|
|
if (c->recv_on_chunk) c->recv_on_chunk(c, plain, data_len); |
|
|
|
|
if (c->state == STCP_STATE_CLOSED || c->state == STCP_STATE_ERROR) return; |
|
|
|
|
@ -301,7 +301,8 @@ void stcp_conn_do_close(struct stcp_conn *c, int err) {
|
|
|
|
|
void (*cb)(struct stcp_conn*, int, void*) = c->on_close; |
|
|
|
|
c->on_close = NULL; |
|
|
|
|
cb(c, err, c->close_arg); |
|
|
|
|
} else if (c->allocated) { |
|
|
|
|
} |
|
|
|
|
if (c->allocated) { |
|
|
|
|
uasync_call_soon(c->ua, c, stcp_conn_deferred_free); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|