|
|
|
|
@ -230,6 +230,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
|
|
|
|
if (!link) return NULL; |
|
|
|
|
|
|
|
|
|
link->conn = conn; |
|
|
|
|
link->etcp = etcp; |
|
|
|
|
link->is_server = is_server; |
|
|
|
|
memcpy(&link->remote_addr, remote_addr, sizeof(struct sockaddr_storage)); |
|
|
|
|
link->last_activity = time(NULL); |
|
|
|
|
@ -360,7 +361,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
|
|
|
|
} *ack_hdr=(void*)&pkt->data[0]; |
|
|
|
|
uint64_t peer_id; |
|
|
|
|
memcpy(&peer_id, &pkt->data[1], 4); |
|
|
|
|
if (ack_hdr->code!=0x02 && ack_hdr->code!=0x04) { errorcode=4; goto ec_fr; }// не init
|
|
|
|
|
if (ack_hdr->code!=ETCP_INIT_REQUEST && ack_hdr->code!=ETCP_CHANNEL_INIT) { errorcode=4; goto ec_fr; }// не init
|
|
|
|
|
|
|
|
|
|
struct ETCP_CONN* conn=e_sock->instance->connections; |
|
|
|
|
while (conn) {// ищем есть ли подключение к этому пиру
|
|
|
|
|
@ -377,7 +378,9 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
|
|
|
|
} |
|
|
|
|
struct ETCP_LINK* link = etcp_link_new(conn, e_sock, &addr, 1); |
|
|
|
|
if (ack_hdr->code==0x02) etcp_conn_reset(conn); |
|
|
|
|
// send reply - подключение создано
|
|
|
|
|
|
|
|
|
|
// send response - подключение создано
|
|
|
|
|
|
|
|
|
|
struct { |
|
|
|
|
uint8_t main_id[2]; |
|
|
|
|
uint8_t timestamp[2]; |
|
|
|
|
@ -385,7 +388,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
|
|
|
|
uint8_t id[8]; |
|
|
|
|
uint8_t mtu[2]; |
|
|
|
|
} *ack_repl_hdr=(void*)&pkt->data[0]; |
|
|
|
|
ack_repl_hdr->code=0x03; |
|
|
|
|
ack_repl_hdr->code+=1; |
|
|
|
|
ack_repl_hdr->main_id[0]=0; |
|
|
|
|
ack_repl_hdr->main_id[1]=0; |
|
|
|
|
memcpy(&ack_repl_hdr->id[0], &e_sock->instance->node_id, 8); |
|
|
|
|
@ -405,7 +408,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
|
|
|
|
pkt->noencrypt_len=0; |
|
|
|
|
pkt->link=link; |
|
|
|
|
|
|
|
|
|
etcp_input(pkt); |
|
|
|
|
etcp_conn_input(pkt->link->conn, pkt); |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
ec_fr: |
|
|
|
|
@ -415,89 +418,6 @@ ec_fr:
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define MIN(a,b) ((a) < (b) ? (a) : (b)) |
|
|
|
|
|
|
|
|
|
int etcp_input(struct ETCP_DGRAM* pkt) { |
|
|
|
|
if (!pkt || !pkt->link) return -1; |
|
|
|
|
|
|
|
|
|
uint8_t* data = pkt->data; |
|
|
|
|
size_t len = pkt->data_len; |
|
|
|
|
|
|
|
|
|
if (len < 1) return -1; |
|
|
|
|
|
|
|
|
|
uint8_t header = data[0]; |
|
|
|
|
data++; len--; |
|
|
|
|
|
|
|
|
|
struct ETCP_LINK* link = pkt->link; |
|
|
|
|
struct ETCP_CONN* etcp = link->etcp; |
|
|
|
|
|
|
|
|
|
// Check if we have peer key by checking if peer_node_id is set
|
|
|
|
|
int has_peer_key = (etcp->peer_node_id != 0); |
|
|
|
|
|
|
|
|
|
if (header != ETCP_INIT_REQUEST && header != ETCP_CHANNEL_INIT && has_peer_key) { |
|
|
|
|
// Decrypt
|
|
|
|
|
sc_context_t* sc = &etcp->crypto_ctx; |
|
|
|
|
uint8_t decrypted[PACKET_DATA_SIZE]; |
|
|
|
|
size_t decrypted_len; |
|
|
|
|
if (sc_decrypt(sc, data, len, decrypted, &decrypted_len) != SC_OK) { |
|
|
|
|
link->decrypt_errors++; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
memcpy(data, decrypted, decrypted_len); |
|
|
|
|
len = decrypted_len; |
|
|
|
|
link->total_decrypted += len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!link) { |
|
|
|
|
if (header == ETCP_INIT_REQUEST || header == ETCP_CHANNEL_INIT) { |
|
|
|
|
// Create new link - this shouldn't happen as link should be set
|
|
|
|
|
return -1; |
|
|
|
|
} else { |
|
|
|
|
// Send reset if not init
|
|
|
|
|
uint8_t reset_pkt[1] = {ETCP_RESET}; |
|
|
|
|
etcp_connections_send(link->conn, reset_pkt, 1, (struct sockaddr*)&link->remote_addr, sizeof(link->remote_addr)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (header == ETCP_INIT_REQUEST) { |
|
|
|
|
// Parse init
|
|
|
|
|
if (len < 8 + 2 + 2 + SC_PUBKEY_SIZE) return -1; |
|
|
|
|
uint64_t peer_node_id; |
|
|
|
|
memcpy(&peer_node_id, data, 8); data += 8; len -= 8; |
|
|
|
|
uint16_t peer_mtu = (data[0] << 8) | data[1]; data += 2; len -= 2; |
|
|
|
|
uint16_t peer_keepalive = (data[0] << 8) | data[1]; data += 2; len -= 2; |
|
|
|
|
uint8_t peer_pubkey[SC_PUBKEY_SIZE]; |
|
|
|
|
memcpy(peer_pubkey, data, SC_PUBKEY_SIZE); |
|
|
|
|
|
|
|
|
|
etcp->peer_node_id = peer_node_id; |
|
|
|
|
memcpy(etcp->crypto_ctx.peer_public_key, peer_pubkey, SC_PUBKEY_SIZE); |
|
|
|
|
etcp->peer_node_id = peer_node_id; // Set peer_node_id to indicate we have peer key
|
|
|
|
|
sc_set_peer_public_key(&etcp->crypto_ctx, peer_pubkey, 0); |
|
|
|
|
|
|
|
|
|
link->mtu = MIN(etcp->mtu, peer_mtu); |
|
|
|
|
link->keepalive_interval = peer_keepalive; |
|
|
|
|
link->initialized = 1; |
|
|
|
|
|
|
|
|
|
// Send response
|
|
|
|
|
etcp_link_send_init_response(link, etcp->mtu, link->keepalive_interval); |
|
|
|
|
|
|
|
|
|
} else if (header == ETCP_INIT_RESPONSE) { |
|
|
|
|
// Similar parsing without pubkey
|
|
|
|
|
} else if (header == ETCP_CHANNEL_RESPONSE) { |
|
|
|
|
// Parse
|
|
|
|
|
} else if (header == ETCP_RESET) { |
|
|
|
|
etcp_conn_reset(etcp); |
|
|
|
|
} else { |
|
|
|
|
// Forward to etcp_conn_input
|
|
|
|
|
pkt->link = link; |
|
|
|
|
etcp_conn_input(etcp, pkt); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int init_connections(struct UTUN_INSTANCE* instance) { |
|
|
|
|
if (!instance || !instance->config) return -1; |
|
|
|
|
|
|
|
|
|
@ -555,11 +475,6 @@ int init_connections(struct UTUN_INSTANCE* instance) {
|
|
|
|
|
sc_set_peer_public_key(&etcp_conn->crypto_ctx, client->peer_public_key_hex, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add connection to the instance's linked list
|
|
|
|
|
etcp_conn->next = instance->connections; |
|
|
|
|
instance->connections = etcp_conn; |
|
|
|
|
instance->connections_count++; |
|
|
|
|
|
|
|
|
|
// Create links for this client
|
|
|
|
|
struct CFG_CLIENT_LINK* client_link = client->links; |
|
|
|
|
while (client_link) { |
|
|
|
|
|