Keep cancelled links alive until their constructor returns
This commit is contained in:
1 parent
a51c080407
commit
a2861b0570
2 files changed
+28
-9
No files matched your search
@@ -117,25 +117,26 @@ static void socks_etcp_read_callback(socket_t sock, void* arg) {
|
||||
void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock) {
|
||||
struct UTUN_INSTANCE *inst = tcp_sock->instance;
|
||||
const uint8_t *pubkey = stcp_link_get_peer_pubkey(link);
|
||||
if (!pubkey) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: no peer pubkey"); return; }
|
||||
if (!pubkey) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: no peer pubkey"); stcp_link_close(link); return; }
|
||||
uint64_t node_id = sc_derive_node_id_from_pubkey(pubkey);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: accepted TCP from peer=0x%016llx", (unsigned long long)node_id);
|
||||
|
||||
struct ETCP_CONN *conn = instance_find_conn(inst, node_id);
|
||||
int new_conn = conn == NULL;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: %s conn=%p peer=0x%016llx pubkey=%016llx",
|
||||
conn ? "existing" : "NEW", (void*)conn, (unsigned long long)node_id, (unsigned long long)wire_read64(pubkey));
|
||||
|
||||
if (!conn) {
|
||||
conn = etcp_connection_create(inst, NULL);
|
||||
if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: etcp_connection_create failed"); return; }
|
||||
if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: etcp_connection_create failed/cancelled"); stcp_link_close(link); return; }
|
||||
conn->peer_node_id = node_id;
|
||||
if (sc_init_ctx(&conn->crypto_ctx, &inst->my_keys) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: sc_init_ctx failed");
|
||||
etcp_connection_close(conn); return;
|
||||
etcp_connection_close(conn); stcp_link_close(link); return;
|
||||
}
|
||||
if (sc_set_peer_public_key(&conn->crypto_ctx, pubkey, SC_PEER_PUBKEY_BIN) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: sc_set_peer_public_key failed");
|
||||
etcp_connection_close(conn); return;
|
||||
etcp_connection_close(conn); stcp_link_close(link); return;
|
||||
}
|
||||
etcp_update_log_name(conn);
|
||||
{ struct conn_queue_entry* ce = (struct conn_queue_entry*)conn->conn_queue_entry->data; ce->peer_node_id = node_id; queue_remove_data(conn->conn_queue, conn->conn_queue_entry); queue_data_put_with_index(conn->conn_queue, conn->conn_queue_entry); }
|
||||
@@ -145,7 +146,12 @@ void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock) {
|
||||
const struct sockaddr_storage* ra = stcp_link_get_peer_addr(link);
|
||||
if (!ra) ra = stcp_link_get_remote_addr(link);
|
||||
struct ETCP_LINK *tlink = etcp_link_new(conn, tcp_sock, ra, 1);
|
||||
if (!tlink) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: etcp_link_new failed"); return; }
|
||||
if (!tlink) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "tcp_server_on_link: link creation failed/cancelled peer=%016llx", (unsigned long long)node_id);
|
||||
stcp_link_close(link);
|
||||
if (new_conn) etcp_connection_close(conn);
|
||||
return;
|
||||
}
|
||||
tlink->tcp_link = link;
|
||||
tlink->is_server = 1;
|
||||
|
||||
@@ -346,6 +352,7 @@ void etcp_link_enter_init(struct ETCP_LINK* link) {
|
||||
int old_state = link->link_state;
|
||||
link->link_state = LINK_STATE_HANDSHAKE; // handshake
|
||||
etcp_fire_link_status_cbk(link, old_state, link->link_status);
|
||||
if (!etcp_link_rx_alive(link->etcp, link)) return;
|
||||
if (link->is_server != 0) return;
|
||||
int reset = (link->etcp->got_initial_pkt == 0);
|
||||
etcp_link_send_init(link, reset, 0);
|
||||
@@ -1044,7 +1051,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
||||
const struct sockaddr_storage* remote_addr, uint8_t is_server) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "null etcp"); return NULL; }
|
||||
if (etcp->state == 2) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] link_new on deleted conn", etcp->log_name); return NULL; }
|
||||
if (etcp->state == 2 || etcp->close_requested) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] link_new on closing conn", etcp->log_name); return NULL; }
|
||||
int is_tcp = (conn == NULL) || conn->is_tcp;
|
||||
|
||||
struct ETCP_LINK* link = u_calloc(1, sizeof(struct ETCP_LINK));
|
||||
@@ -1150,11 +1157,23 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "NEW link etcp=[%s] link=%p socket=%s id=%u server=%u mtu=%u tcp=%u DATA_MSS=%u cwnd=%u",
|
||||
etcp->log_name, link, conn ? conn->name : "tcp", link->local_link_id, link->is_server, link->mtu, link->is_tcp,
|
||||
etcp->normalizer->frag_size, link->inflight_lim_bytes);
|
||||
link->constructing = 1;
|
||||
etcp_fire_link_status_cbk(link, -1, 0);
|
||||
|
||||
if (!is_tcp && is_server == 0) {
|
||||
if (!link->closing && !etcp->close_requested && !is_tcp && is_server == 0) {
|
||||
etcp_link_enter_init(link);
|
||||
}
|
||||
link->constructing = 0;
|
||||
if (link->closing) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] link creation cancelled path=%u", etcp->log_name, link->local_link_id);
|
||||
u_free(link->bbr); u_free(link);
|
||||
return NULL;
|
||||
}
|
||||
if (etcp->close_requested) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] link creation stopped by connection close path=%u", etcp->log_name, link->local_link_id);
|
||||
etcp_link_close(link);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
callring_put(CR_LINK_NEW, (uintptr_t)link, (uintptr_t)etcp);
|
||||
return link;
|
||||
@@ -1254,8 +1273,7 @@ void etcp_link_close(struct ETCP_LINK* link) {
|
||||
etcp_fire_link_status_cbk(link, old_state, old_status);
|
||||
if (!etcp->close_requested) etcp_on_link_down(etcp, NULL);
|
||||
callring_put(CR_LINK_CLOSE_FREE, (uintptr_t)link, 0);
|
||||
u_free(link->bbr);
|
||||
u_free(link);
|
||||
if (!link->constructing) { u_free(link->bbr); u_free(link); }
|
||||
etcp->callbacks_running--;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@ struct ETCP_LINK {
|
||||
uint8_t is_server; // инициирует подключение клиент
|
||||
uint8_t initialized; // Флаг инициализации (1=подтверждено или получен request)
|
||||
uint8_t closing; // Close начат: повторный вход из callback игнорируется до окончательного free
|
||||
uint8_t constructing; // Конструктор ещё владеет памятью: close отвязывает ресурсы, free выполняет конструктор
|
||||
uint8_t local_link_id; // id моего линка
|
||||
uint8_t remote_link_id; // id этого линка на peer (устанавливается в момент initialized)
|
||||
uint8_t remote_socket_id; // socket id peer
|
||||
|
||||
Reference in new issue
Block a user