|
|
|
@ -203,11 +203,57 @@ int etcp_input(struct packet_buffer* pkt, struct ETCP_SOCKET* socket, struct ETC |
|
|
|
if (pkt->metadata.data_len < 1) return -1; |
|
|
|
if (pkt->metadata.data_len < 1) return -1; |
|
|
|
|
|
|
|
|
|
|
|
uint8_t* data = pkt->data; |
|
|
|
uint8_t* data = pkt->data; |
|
|
|
|
|
|
|
size_t data_len = pkt->metadata.data_len; |
|
|
|
uint8_t cmd = data[0]; |
|
|
|
uint8_t cmd = data[0]; |
|
|
|
|
|
|
|
|
|
|
|
struct sockaddr* src_addr = packet_remote_addr(pkt); |
|
|
|
struct sockaddr* src_addr = packet_remote_addr(pkt); |
|
|
|
socklen_t addr_len = sizeof(struct sockaddr_storage); |
|
|
|
socklen_t addr_len = sizeof(struct sockaddr_storage); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Дешифруем пакет, если есть session_key
|
|
|
|
|
|
|
|
sc_context_t* sc = conns->etcp->crypto_ctx; |
|
|
|
|
|
|
|
uint8_t decrypted_buf[1500]; |
|
|
|
|
|
|
|
bool was_decrypted = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sc && sc->session_ready && data_len > SC_TAG_SIZE) { |
|
|
|
|
|
|
|
size_t decrypted_len = sizeof(decrypted_buf); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Для INIT_REQUEST пакета - pubkey в конце не шифруется
|
|
|
|
|
|
|
|
bool has_pubkey_at_end = (cmd == ETCP_INIT_REQUEST); |
|
|
|
|
|
|
|
size_t encrypted_part_len = has_pubkey_at_end ?
|
|
|
|
|
|
|
|
data_len - SC_PUBKEY_SIZE : data_len; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (encrypted_part_len > SC_TAG_SIZE) { |
|
|
|
|
|
|
|
if (sc_decrypt(sc, data, encrypted_part_len, decrypted_buf, &decrypted_len) == SC_OK) { |
|
|
|
|
|
|
|
data = decrypted_buf; |
|
|
|
|
|
|
|
data_len = decrypted_len; |
|
|
|
|
|
|
|
cmd = data[0]; |
|
|
|
|
|
|
|
was_decrypted = true; |
|
|
|
|
|
|
|
conns->total_decrypted++; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
conns->decrypt_errors++; |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Decryption failed"); |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Извлекаем pubkey из конца только для INIT_REQUEST
|
|
|
|
|
|
|
|
if (cmd == ETCP_INIT_REQUEST && data_len >= SC_PUBKEY_SIZE) { |
|
|
|
|
|
|
|
// Сохраняем pubkey перед изменением data_len
|
|
|
|
|
|
|
|
uint8_t pubkey[SC_PUBKEY_SIZE]; |
|
|
|
|
|
|
|
memcpy(pubkey, data + data_len - SC_PUBKEY_SIZE, SC_PUBKEY_SIZE); |
|
|
|
|
|
|
|
data_len -= SC_PUBKEY_SIZE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Устанавливаем pubkey в secure channel
|
|
|
|
|
|
|
|
if (sc && sc->initialized) { |
|
|
|
|
|
|
|
sc_set_peer_public_key(sc, pubkey); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Обновляем cmd, так как data_len изменился
|
|
|
|
|
|
|
|
cmd = data[0]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Обработка INIT REQUEST
|
|
|
|
if (cmd == ETCP_INIT_REQUEST) { |
|
|
|
if (cmd == ETCP_INIT_REQUEST) { |
|
|
|
if (pkt->metadata.data_len < 1 + 8 + SC_PUBKEY_SIZE + 2 + 2) { |
|
|
|
if (pkt->metadata.data_len < 1 + 8 + SC_PUBKEY_SIZE + 2 + 2) { |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
@ -312,13 +358,45 @@ int etcp_link_init(struct ETCP_CONN* etcp, struct ETCP_LINK* link) { (void)etcp; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int etcp_link_send(struct ETCP_CONN* etcp, struct ETCP_LINK* link,
|
|
|
|
int etcp_link_send(struct ETCP_CONN* etcp, struct ETCP_LINK* link,
|
|
|
|
const uint8_t* data, size_t len) { |
|
|
|
const uint8_t* data, size_t len) { |
|
|
|
if (!etcp || !link || !data || len == 0) return -1; |
|
|
|
if (!etcp || !link || !data || len == 0) return -1; |
|
|
|
|
|
|
|
|
|
|
|
link->last_activity = time(NULL); |
|
|
|
link->last_activity = time(NULL); |
|
|
|
|
|
|
|
|
|
|
|
return etcp_socket_send((struct ETCP_SOCKET*)link->socket, data, len,
|
|
|
|
sc_context_t* sc = etcp->crypto_ctx; |
|
|
|
(struct sockaddr*)&link->remote_addr); |
|
|
|
int fd = link->socket->fd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sc && sc->session_ready && len < 1400) { |
|
|
|
|
|
|
|
uint8_t encrypted_buf[1500]; |
|
|
|
|
|
|
|
size_t encrypted_len = sizeof(encrypted_buf); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sc_encrypt(sc, data, len, encrypted_buf, &encrypted_len) == SC_OK) { |
|
|
|
|
|
|
|
ssize_t sent = sendto(fd, encrypted_buf, encrypted_len, MSG_DONTWAIT, |
|
|
|
|
|
|
|
(struct sockaddr*)&link->remote_addr,
|
|
|
|
|
|
|
|
link->remote_addr_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sent < 0) { |
|
|
|
|
|
|
|
if (errno != EAGAIN && errno != EWOULDBLOCK) { |
|
|
|
|
|
|
|
link->conns->send_errors++; |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "sendto failed: %s", strerror(errno)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
link->conns->total_encrypted++; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
link->conns->encrypt_errors++; |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Encryption failed"); |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ssize_t sent = sendto(fd, data, len, MSG_DONTWAIT, |
|
|
|
|
|
|
|
(struct sockaddr*)&link->remote_addr,
|
|
|
|
|
|
|
|
link->remote_addr_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (sent >= 0) ? 0 : -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval) { |
|
|
|
int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval) { |
|
|
|
|