|
|
|
|
@ -658,3 +658,134 @@ void chat_sync_connect_node(struct UTUN_INSTANCE* inst, uint64_t node_id) {
|
|
|
|
|
uint8_t req[8]; memcpy(req, &node_id, 8); |
|
|
|
|
gui_bridge_call(GUI_OP_LOAD_NODEINFO, req, 8, NULL, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ── Invite link connect ── */ |
|
|
|
|
|
|
|
|
|
struct cs_invite_arg { |
|
|
|
|
uint64_t node_id; |
|
|
|
|
uint8_t pubkey[SC_PUBKEY_SIZE]; |
|
|
|
|
uint8_t* addrs_data; |
|
|
|
|
int addr_count; |
|
|
|
|
uint8_t* ch_id; |
|
|
|
|
int ch_id_len; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void cs_connect_result_cb(int result, uint64_t node_id, void* arg) { |
|
|
|
|
(void)arg; |
|
|
|
|
uint8_t data[12]; |
|
|
|
|
memcpy(data, &node_id, 8); |
|
|
|
|
memcpy(data + 8, &result, 4); |
|
|
|
|
gui_bridge_post(GUI_EVT_CONNECT_RESULT, data, 12); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void cs_connect_from_invite_impl(void* arg) { |
|
|
|
|
struct cs_invite_arg* a = (struct cs_invite_arg*)arg; |
|
|
|
|
uint64_t node_id = a->node_id; |
|
|
|
|
if (!g_cs || !g_cs->inst || !g_cs->inst->bgp || !g_cs->inst->conn_mgr) { |
|
|
|
|
uint8_t err[12]; int r = -7; |
|
|
|
|
memcpy(err, &node_id, 8); memcpy(err + 8, &r, 4); |
|
|
|
|
gui_bridge_post(GUI_EVT_CONNECT_RESULT, err, 12); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ROUTE_BGP* bgp = g_cs->inst->bgp; |
|
|
|
|
if (nodeinfo_find_by_id(bgp, node_id)) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "chat_sync: node 0x%016llx already in BGP, connecting", (unsigned long long)node_id); |
|
|
|
|
conn_mgr_connect_node(g_cs->inst->conn_mgr, node_id, 30000, cs_connect_result_cb, NULL); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t dyn_sz = (size_t)a->addr_count * sizeof(struct NODEINFO_IPV4_ADDR); |
|
|
|
|
size_t data_sz = sizeof(struct NODEINFO_Q) - sizeof(struct ll_entry) + dyn_sz + 8; |
|
|
|
|
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)queue_entry_new(data_sz); |
|
|
|
|
if (!nq) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "chat_sync: failed to alloc NODEINFO_Q"); |
|
|
|
|
uint8_t err[12]; int r = -7; |
|
|
|
|
memcpy(err, &node_id, 8); memcpy(err + 8, &r, 4); |
|
|
|
|
gui_bridge_post(GUI_EVT_CONNECT_RESULT, err, 12); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct NODEINFO* ni = &nq->node; |
|
|
|
|
ni->node_id = node_id; |
|
|
|
|
ni->ver = 0; |
|
|
|
|
memcpy(ni->public_key, a->pubkey, SC_PUBKEY_SIZE); |
|
|
|
|
memset(ni->ed25519_public_key, 0, SC_PUBKEY_SIZE); |
|
|
|
|
ni->node_name_len = 0; |
|
|
|
|
ni->local_v4_sockets = 0; |
|
|
|
|
ni->local_v4_addrs = (uint8_t)a->addr_count; |
|
|
|
|
ni->local_v6_sockets = 0; |
|
|
|
|
ni->local_v6_addrs = 0; |
|
|
|
|
ni->local_v4_subnets = 0; |
|
|
|
|
ni->local_v6_subnets = 0; |
|
|
|
|
ni->tranzit_nodes = 0; |
|
|
|
|
ni->hop_count = 0; |
|
|
|
|
|
|
|
|
|
uint8_t* dyn = (uint8_t*)ni + sizeof(struct NODEINFO); |
|
|
|
|
const uint8_t* src = a->addrs_data; |
|
|
|
|
for (int i = 0; i < a->addr_count; i++) { |
|
|
|
|
struct NODEINFO_IPV4_ADDR* addr = (struct NODEINFO_IPV4_ADDR*)(dyn + i * sizeof(struct NODEINFO_IPV4_ADDR)); |
|
|
|
|
memset(addr, 0, sizeof(*addr)); |
|
|
|
|
uint8_t family = *src++; |
|
|
|
|
if (family == 4) { |
|
|
|
|
memcpy(addr->addr, src, 4); src += 4; |
|
|
|
|
uint16_t port_be = ((uint16_t)src[0] << 8) | src[1]; src += 2; |
|
|
|
|
addr->port = port_be; |
|
|
|
|
addr->type = ADDR_TYPE_REAL; |
|
|
|
|
addr->socket_id = 0; |
|
|
|
|
addr->protocol = NODE_PROTO_UDP; |
|
|
|
|
} else { |
|
|
|
|
src += 18; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
nq->alien = 0; |
|
|
|
|
nq->dirty = 0; |
|
|
|
|
nq->last_ver = 0; |
|
|
|
|
nq->conn_mgr_type = CONN_TYPE_NONE; |
|
|
|
|
nq->conn_mgr_intermediariy_count = 0; |
|
|
|
|
memset(&nq->connectivity, 0, sizeof(nq->connectivity)); |
|
|
|
|
nq->best_socket = NULL; |
|
|
|
|
|
|
|
|
|
queue_data_put_with_index(bgp->nodes, &nq->ll); |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "chat_sync: created NODEINFO for 0x%016llx, %d addrs, connecting", |
|
|
|
|
(unsigned long long)node_id, a->addr_count); |
|
|
|
|
conn_mgr_connect_node(g_cs->inst->conn_mgr, node_id, 30000, cs_connect_result_cb, NULL); |
|
|
|
|
|
|
|
|
|
cleanup: |
|
|
|
|
u_free(a->addrs_data); |
|
|
|
|
u_free(a->ch_id); |
|
|
|
|
u_free(a); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void chat_sync_connect_from_invite(uint64_t node_id, const uint8_t* pubkey_bin, |
|
|
|
|
const uint8_t* addrs_data, int addr_count, |
|
|
|
|
const uint8_t* channel_id, int ch_id_len) { |
|
|
|
|
if (!g_cs || !g_cs->inst || !g_cs->inst->ua) { |
|
|
|
|
int r = -7; |
|
|
|
|
uint8_t err[12]; memcpy(err, &node_id, 8); memcpy(err + 8, &r, 4); |
|
|
|
|
gui_bridge_post(GUI_EVT_CONNECT_RESULT, err, 12); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct cs_invite_arg* a = u_calloc(1, sizeof(struct cs_invite_arg)); |
|
|
|
|
if (!a) return; |
|
|
|
|
|
|
|
|
|
a->node_id = node_id; |
|
|
|
|
memcpy(a->pubkey, pubkey_bin, SC_PUBKEY_SIZE); |
|
|
|
|
|
|
|
|
|
size_t addrs_sz = (size_t)addr_count * 7; |
|
|
|
|
a->addrs_data = u_malloc(addrs_sz); |
|
|
|
|
if (!a->addrs_data) { u_free(a); return; } |
|
|
|
|
memcpy(a->addrs_data, addrs_data, addrs_sz); |
|
|
|
|
a->addr_count = addr_count; |
|
|
|
|
|
|
|
|
|
a->ch_id = u_malloc((size_t)ch_id_len + 1); |
|
|
|
|
if (!a->ch_id) { u_free(a->addrs_data); u_free(a); return; } |
|
|
|
|
memcpy(a->ch_id, channel_id, (size_t)ch_id_len); |
|
|
|
|
a->ch_id_len = ch_id_len; |
|
|
|
|
|
|
|
|
|
gui_bridge_post_uasync(g_cs->inst->ua, cs_connect_from_invite_impl, a); |
|
|
|
|
} |
|
|
|
|
|