keepalive handshake: device_type + keepalive negotiation in UDP/TCP INIT
- Добавлен device_type (1 байт, CLIENT_TYPE_*) в INIT_REQUEST и INIT_RESPONSE - Добавлен keepalive_interval (2 байта) в INIT_RESPONSE - STCP handshake расширен с 43 до 46 байт (device_type+keepalive) - negotiate_keepalive(): оба desktop/server → min, иначе (есть mobile) → max - keepalive_interval вынесен в UTUN_INSTANCE для использования в handshake - stcp_client_connect() принимает device_type и keepalive_interval - peer_device_type/peer_keepalive_interval передаются через stcp_link в ETCP_LINK
This commit is contained in:
1 parent
43aca4a41b
commit
0f1bd3d120
37 files changed
+535
-309
No files matched your search
@@ -138,9 +138,9 @@ sdkmanager "platforms;android-36" "build-tools;36.0.0" "ndk;29.0.14206865"
|
||||
## Сборка
|
||||
|
||||
```
|
||||
./build.sh # APK
|
||||
./build.sh install # сборка + прошивка на подключённый телефон
|
||||
./build.sh install <SN> # на конкретный девайс
|
||||
./build.sh # clean + сборка + прошивка на подключённый телефон
|
||||
./build.sh noinstall # только сборка, без прошивки
|
||||
./build.sh <SN> # clean + сборка + прошивка на конкретный девайс
|
||||
```
|
||||
|
||||
### APK (Android)
|
||||
|
||||
@@ -4,6 +4,7 @@ cd "$(dirname "$0")"
|
||||
export ANDROID_HOME="${ANDROID_HOME:-/home/user/android}"
|
||||
echo "Building..."
|
||||
TMP=$(mktemp)
|
||||
./gradlew clean > /dev/null 2>&1
|
||||
if ! ./gradlew assembleDebug > "$TMP" 2>&1; then
|
||||
cat "$TMP"
|
||||
rm -f "$TMP"
|
||||
@@ -11,9 +12,9 @@ if ! ./gradlew assembleDebug > "$TMP" 2>&1; then
|
||||
fi
|
||||
rm -f "$TMP"
|
||||
echo "Build OK"
|
||||
if [ "$1" = "install" ]; then
|
||||
DEV=${2:-$(adb devices 2>/dev/null | awk 'NR==2{print $1}')}
|
||||
ADB=adb; [ -n "$DEV" ] && ADB="adb -s $DEV"
|
||||
$ADB install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
echo "Install OK"
|
||||
if [ "$1" != "noinstall" ]; then
|
||||
DEV=${1:-$(adb devices 2>/dev/null | awk 'NR==2{print $1}')}
|
||||
ADB=adb; [ -n "$DEV" ] && ADB="adb -s $DEV"
|
||||
$ADB install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
echo "Install OK"
|
||||
fi
|
||||
@@ -233,6 +233,7 @@ static int bridge_collect_invite_addrs(struct InviteAddrC* out, int max_cnt) {
|
||||
int cnt = 0;
|
||||
struct ETCP_SOCKET* s = g_cc.inst->etcp_sockets;
|
||||
while (s) {
|
||||
if (s->is_tcp) { s = s->next; continue; }
|
||||
struct sockaddr_storage* sa = s->interface_addr.ss_family ? &s->interface_addr : &s->local_addr;
|
||||
if (sa && sa->ss_family == AF_INET && cnt < max_cnt) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
||||
@@ -247,21 +248,22 @@ static int bridge_collect_invite_addrs(struct InviteAddrC* out, int max_cnt) {
|
||||
}
|
||||
s = s->next;
|
||||
}
|
||||
{ struct ETCP_SOCKET* ts = g_cc.inst->tcp_sockets;
|
||||
while (ts) {
|
||||
struct sockaddr_storage* sa = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
|
||||
{ struct ETCP_SOCKET* s2 = g_cc.inst->etcp_sockets;
|
||||
while (s2) {
|
||||
if (!s2->is_tcp) { s2 = s2->next; continue; }
|
||||
struct sockaddr_storage* sa = s2->interface_addr.ss_family ? &s2->interface_addr : &s2->local_addr;
|
||||
if (sa && sa->ss_family == AF_INET && cnt < max_cnt) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
||||
out[cnt].family = 4; out[cnt].socketId = ts->sock_id; out[cnt].proto = INVITE_PROTO_TCP;
|
||||
out[cnt].family = 4; out[cnt].socketId = s2->sock_id; out[cnt].proto = INVITE_PROTO_TCP;
|
||||
memcpy(out[cnt].address, &sin->sin_addr, 4);
|
||||
out[cnt].port = ntohs(sin->sin_port); cnt++;
|
||||
} else if (sa && sa->ss_family == AF_INET6 && cnt < max_cnt) {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
||||
out[cnt].family = 6; out[cnt].socketId = ts->sock_id; out[cnt].proto = INVITE_PROTO_TCP;
|
||||
out[cnt].family = 6; out[cnt].socketId = s2->sock_id; out[cnt].proto = INVITE_PROTO_TCP;
|
||||
memcpy(out[cnt].address, &sin6->sin6_addr, 16);
|
||||
out[cnt].port = ntohs(sin6->sin6_port); cnt++;
|
||||
}
|
||||
ts = ts->next; }
|
||||
s2 = s2->next; }
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
@@ -1015,12 +1017,19 @@ char* utun_bridge_get_member_links_json(uint64_t node_id) {
|
||||
|
||||
char la[INET6_ADDRSTRLEN] = ""; int lf = 0; uint16_t lp = 0;
|
||||
if (lk->conn) {
|
||||
const struct sockaddr_storage* lsa = &lk->conn->local_addr;
|
||||
const struct sockaddr_storage* lsa = lk->conn->interface_addr.ss_family ? &lk->conn->interface_addr : &lk->conn->local_addr;
|
||||
if (lsa->ss_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in*)lsa)->sin_addr, la, sizeof(la)); lf = 4; lp = ntohs(((struct sockaddr_in*)lsa)->sin_port);
|
||||
} else if (lsa->ss_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6*)lsa)->sin6_addr, la, sizeof(la)); lf = 6; lp = ntohs(((struct sockaddr_in6*)lsa)->sin6_port);
|
||||
}
|
||||
} else if (lk->is_tcp && lk->tcp_link) {
|
||||
const struct sockaddr_storage* lsa = stcp_link_get_local_addr(lk->tcp_link);
|
||||
if (lsa && lsa->ss_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in*)lsa)->sin_addr, la, sizeof(la)); lf = 4; lp = ntohs(((struct sockaddr_in*)lsa)->sin_port);
|
||||
} else if (lsa && lsa->ss_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6*)lsa)->sin6_addr, la, sizeof(la)); lf = 6; lp = ntohs(((struct sockaddr_in6*)lsa)->sin6_port);
|
||||
}
|
||||
}
|
||||
|
||||
char ra[INET6_ADDRSTRLEN] = ""; int rf = 0; uint16_t rp = 0;
|
||||
@@ -1035,9 +1044,10 @@ char* utun_bridge_get_member_links_json(uint64_t node_id) {
|
||||
}
|
||||
|
||||
const char* sep = first ? "" : ","; first = 0;
|
||||
const char* sn = lk->conn ? lk->conn->name : "";
|
||||
pos += snprintf(buf + pos, sizeof(buf) - (size_t)pos,
|
||||
"%s{\"lf\":%d,\"la\":\"%s\",\"lp\":%d,\"rf\":%d,\"ra\":\"%s\",\"rp\":%d,\"st\":%d,\"ls\":%d,\"is\":%d}",
|
||||
sep, lf, la, (int)lp, rf, ra, (int)rp, st, ls, lk->is_server);
|
||||
"%s{\"id\":%d,\"lf\":%d,\"la\":\"%s\",\"lp\":%d,\"rf\":%d,\"ra\":\"%s\",\"rp\":%d,\"st\":%d,\"ls\":%d,\"is\":%d,\"sn\":\"%s\"}",
|
||||
sep, lk->local_link_id, lf, la, (int)lp, rf, ra, (int)rp, st, ls, lk->is_server, sn);
|
||||
}
|
||||
if (pos < (int)sizeof(buf))
|
||||
pos += snprintf(buf + pos, sizeof(buf) - (size_t)pos, "]}");
|
||||
@@ -1055,45 +1065,46 @@ char* utun_bridge_get_local_sockets_json(void) {
|
||||
if (!chat_core_is_initialized() || !g_cc.inst) return u_strdup("[]");
|
||||
struct UTUN_INSTANCE* inst = g_cc.inst;
|
||||
|
||||
/* count active TCP connections */
|
||||
int active_conns = 0, active_links = 0;
|
||||
if (inst->connections) {
|
||||
for (struct ll_entry* entry = inst->connections->head; entry; entry = entry->next) {
|
||||
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
|
||||
if (ce && ce->conn && ce->conn->initialized) {
|
||||
int has_tcp = 0;
|
||||
for (struct ETCP_LINK* lk = ce->conn->links; lk; lk = lk->next) {
|
||||
if (lk->is_tcp) { has_tcp = 1; break; }
|
||||
}
|
||||
if (!has_tcp) continue;
|
||||
active_conns++;
|
||||
active_links += ce->conn->links_up;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inst->tcp_connections) {
|
||||
for (struct ll_entry* entry = inst->tcp_connections->head; entry; entry = entry->next) {
|
||||
struct tcp_conn_entry* te = (struct tcp_conn_entry*)entry->data;
|
||||
if (te && te->etcp_conn && te->etcp_conn->initialized) {
|
||||
active_conns++;
|
||||
active_links += te->etcp_conn->links_up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t cap = 4096, pos = 1;
|
||||
char* json = u_malloc(cap);
|
||||
if (!json) return u_strdup("[]");
|
||||
json[0] = '[';
|
||||
int first = 1;
|
||||
|
||||
bridge_log(BLEV_INFO, "getLocalSockets: tcp_sockets=%p etcp_sockets=%p conns=%d links=%d",
|
||||
(void*)inst->tcp_sockets, (void*)inst->etcp_sockets, active_conns, active_links);
|
||||
bridge_log(BLEV_INFO, "getLocalSockets: etcp_sockets=%p", (void*)inst->etcp_sockets);
|
||||
|
||||
/* Helper: count per-socket links_up / links_down */
|
||||
#define SOCK_COUNT_LINKS(_s, _lu, _ld) do { \
|
||||
int *_p_lu = &(_lu), *_p_ld = &(_ld); \
|
||||
*_p_lu = 0; *_p_ld = 0; \
|
||||
if (inst->connections) { \
|
||||
for (struct ll_entry* _e = inst->connections->head; _e; _e = _e->next) { \
|
||||
struct conn_queue_entry* _ce = (struct conn_queue_entry*)_e->data; \
|
||||
if (!_ce || !_ce->conn) continue; \
|
||||
for (struct ETCP_LINK* _lk = _ce->conn->links; _lk; _lk = _lk->next) { \
|
||||
if (_lk->conn != (_s)) continue; \
|
||||
if (_lk->link_state == 3) (*_p_lu)++; else (*_p_ld)++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (inst->tcp_connections) { \
|
||||
for (struct ll_entry* _e = inst->tcp_connections->head; _e; _e = _e->next) { \
|
||||
struct tcp_conn_entry* _te = (struct tcp_conn_entry*)_e->data; \
|
||||
if (!_te || !_te->etcp_conn) continue; \
|
||||
for (struct ETCP_LINK* _lk = _te->etcp_conn->links; _lk; _lk = _lk->next) { \
|
||||
if (_lk->conn != (_s)) continue; \
|
||||
if (_lk->link_state == 3) (*_p_lu)++; else (*_p_ld)++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* TCP sockets */
|
||||
{ struct ETCP_SOCKET* ts = inst->tcp_sockets;
|
||||
while (ts) {
|
||||
{ struct ETCP_SOCKET* s = inst->etcp_sockets;
|
||||
while (s) {
|
||||
if (!s->is_tcp) { s = s->next; continue; }
|
||||
char ip_str[INET6_ADDRSTRLEN] = ""; int port = 0;
|
||||
const struct sockaddr_storage* addr = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
|
||||
const struct sockaddr_storage* addr = s->interface_addr.ss_family ? &s->interface_addr : &s->local_addr;
|
||||
if (addr->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
|
||||
port = ntohs(sin->sin_port);
|
||||
@@ -1103,21 +1114,25 @@ char* utun_bridge_get_local_sockets_json(void) {
|
||||
port = ntohs(sin6->sin6_port);
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, ip_str, sizeof(ip_str));
|
||||
}
|
||||
int lu, ld; SOCK_COUNT_LINKS(s, lu, ld);
|
||||
int state = 2; /* bound and listening */
|
||||
const char* sep = first ? "" : ","; first = 0;
|
||||
size_t needed = snprintf(NULL, 0, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"TCP\",\"st\":%d,\"lk\":%d}",
|
||||
sep, ts->sock_id, ts->name, ip_str, port, state, active_links);
|
||||
size_t needed = snprintf(NULL, 0,
|
||||
"%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"TCP\",\"st\":%d,\"lu\":%d,\"ld\":%d}",
|
||||
sep, s->sock_id, s->name, ip_str, port, state, lu, ld);
|
||||
while (pos + needed + 2 > cap) { char* tmp = u_realloc(json, cap * 2); if (!tmp) break; json = tmp; cap *= 2; }
|
||||
if (pos + needed + 2 <= cap)
|
||||
pos += (size_t)snprintf(json + pos, cap - pos, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"TCP\",\"st\":%d,\"lk\":%d}",
|
||||
sep, ts->sock_id, ts->name, ip_str, port, state, active_links);
|
||||
ts = ts->next;
|
||||
pos += (size_t)snprintf(json + pos, cap - pos,
|
||||
"%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"TCP\",\"st\":%d,\"lu\":%d,\"ld\":%d}",
|
||||
sep, s->sock_id, s->name, ip_str, port, state, lu, ld);
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* UDP sockets */
|
||||
{ struct ETCP_SOCKET* es = inst->etcp_sockets;
|
||||
while (es) {
|
||||
if (es->is_tcp) { es = es->next; continue; }
|
||||
char ip_str[INET6_ADDRSTRLEN] = ""; int port = 0;
|
||||
const struct sockaddr_storage* addr = es->interface_addr.ss_family ? &es->interface_addr : &es->local_addr;
|
||||
if (addr->ss_family == AF_INET) {
|
||||
@@ -1129,19 +1144,23 @@ char* utun_bridge_get_local_sockets_json(void) {
|
||||
port = ntohs(sin6->sin6_port);
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, ip_str, sizeof(ip_str));
|
||||
}
|
||||
int lk = es->links_queue ? queue_entry_count(es->links_queue) : 0;
|
||||
int lu, ld; SOCK_COUNT_LINKS(es, lu, ld);
|
||||
int state = 2; /* bound and listening */
|
||||
const char* sep = first ? "" : ","; first = 0;
|
||||
size_t needed = snprintf(NULL, 0, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"UDP\",\"st\":%d,\"lk\":%d}",
|
||||
sep, es->sock_id, es->name, ip_str, port, state, lk);
|
||||
size_t needed = snprintf(NULL, 0,
|
||||
"%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"UDP\",\"st\":%d,\"lu\":%d,\"ld\":%d}",
|
||||
sep, es->sock_id, es->name, ip_str, port, state, lu, ld);
|
||||
while (pos + needed + 2 > cap) { char* tmp = u_realloc(json, cap * 2); if (!tmp) break; json = tmp; cap *= 2; }
|
||||
if (pos + needed + 2 <= cap)
|
||||
pos += (size_t)snprintf(json + pos, cap - pos, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"UDP\",\"st\":%d,\"lk\":%d}",
|
||||
sep, es->sock_id, es->name, ip_str, port, state, lk);
|
||||
pos += (size_t)snprintf(json + pos, cap - pos,
|
||||
"%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"UDP\",\"st\":%d,\"lu\":%d,\"ld\":%d}",
|
||||
sep, es->sock_id, es->name, ip_str, port, state, lu, ld);
|
||||
es = es->next;
|
||||
}
|
||||
}
|
||||
|
||||
#undef SOCK_COUNT_LINKS
|
||||
|
||||
json[pos++] = ']'; json[pos] = '\0';
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,10 @@ static void chat_event_forward(int type, const uint8_t* data, int len) {
|
||||
static void nodeinfo_event_cb(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* nq, void* arg) {
|
||||
(void)group; (void)arg;
|
||||
if (!nq || !g_event_handler) return;
|
||||
uint16_t best_rtt = node_best_rtt(nq);
|
||||
uint16_t best_rtt = topo_get_chain_rtt(nq);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "nodeinfo_cb: nid=%016llx pres=%02x up=%02x rtt=%u(0x%04X) paths=%zu",
|
||||
(unsigned long long)nq->node_id, nq->conn_presence, nq->conn_up,
|
||||
best_rtt, best_rtt, nq->paths ? queue_entry_count(nq->paths) : 0);
|
||||
uint8_t data[12];
|
||||
memcpy(data, &nq->node_id, 8);
|
||||
data[8] = nq->conn_presence;
|
||||
@@ -299,6 +302,7 @@ static void* instance_thread(void* arg) {
|
||||
etcp_router_bind(g_inst, ETCP_RT_ID_CHAT_SYNC, NULL);
|
||||
|
||||
utun_add_nodeinfo_cbk(g_inst, nodeinfo_event_cb, NULL);
|
||||
etcp_add_link_status_cbk(g_inst, on_link_status_changed, NULL);
|
||||
|
||||
/* Set my_name from config */
|
||||
if (g_inst->config->global.name[0]) {
|
||||
@@ -433,8 +437,11 @@ int instance_lite_start(const char* config_text) {
|
||||
debug_config_init();
|
||||
debug_set_level(DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_SYS, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_CHAT_SYNC, DEBUG_LEVEL_TRACE);
|
||||
debug_set_category_level(DEBUG_CATEGORY_MEMBER_SYNC, DEBUG_LEVEL_TRACE);
|
||||
debug_set_category_level(DEBUG_CATEGORY_CHAT_SYNC, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_MEMBER_SYNC, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_DEBUG, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_ETCP, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_DUMP, DEBUG_LEVEL_WARN);
|
||||
debug_enable_function_name(0);
|
||||
|
||||
cfg_get_val(config_text, "db_path", g_db_path, sizeof(g_db_path));
|
||||
|
||||
@@ -38,6 +38,8 @@ QString AccountList::addrStr(const void* addr, int family) {
|
||||
}
|
||||
if (family == 6) {
|
||||
const uint16_t* a = (const uint16_t*)addr;
|
||||
int zero = 1; for (int i = 0; i < 8; i++) if (a[i]) { zero = 0; break; }
|
||||
if (zero) return "[::]";
|
||||
return QString("%1:%2:%3:%4:%5:%6:%7:%8")
|
||||
.arg(ntohs(a[0]), 0, 16).arg(ntohs(a[1]), 0, 16)
|
||||
.arg(ntohs(a[2]), 0, 16).arg(ntohs(a[3]), 0, 16)
|
||||
@@ -336,8 +338,16 @@ void AccountList::updateDetailDisplay() {
|
||||
QString lc = (lk.linkState == 3 && lk.linkStatus == 1) ? "#4CAF50" : "#E53935";
|
||||
QString left = QString("%1:%2").arg(addrStr(lk.localAddr.constData(), lk.localFamily)).arg(lk.localPort);
|
||||
QString right = QString("%1:%2").arg(addrStr(lk.addr.constData(), lk.family)).arg(lk.port);
|
||||
lines.append(QString("<span style='color:%1;'>●</span> %2 %3 → %4")
|
||||
.arg(lc, proto, left, right));
|
||||
const char* arrow = lk.isServer
|
||||
? "<b style='color:#FF9800;font-size:13pt;'>◀</b>"
|
||||
: "<b style='color:#2196F3;font-size:13pt;'>▶</b>";
|
||||
if (lk.localFamily == 6 || lk.family == 6) {
|
||||
lines.append(QString("<span style='color:%1;'>●</span> %2 %3:%4").arg(lc, proto, addrStr(lk.localAddr.constData(), lk.localFamily)).arg(lk.localPort));
|
||||
lines.append(QString(" %1 %2:%3").arg(arrow, addrStr(lk.addr.constData(), lk.family)).arg(lk.port));
|
||||
} else {
|
||||
lines.append(QString("<span style='color:%1;'>●</span> %2 %3 %4 %5")
|
||||
.arg(lc, proto, left, arrow, right));
|
||||
}
|
||||
}
|
||||
/* DB addresses without live link */
|
||||
for (const auto& a : m_detailAddrs) {
|
||||
|
||||
@@ -27,7 +27,7 @@ struct TOPO_GROUP_NODE;
|
||||
#define GUI_EVT_NODE_CHANGED 11 /* data: [node_id:8] */
|
||||
#define GUI_EVT_ATTACHMENT_DOWNLOADED 14 /* data: [ch_id_len:1][ch_id:var][msg_id:8] */
|
||||
#define GUI_EVT_DOWNLOAD_PROGRESS 15 /* data: [ch_id_len:1][ch_id:var][msg_id:8][blocks_done:4][num_blocks:4] */
|
||||
#define GUI_EVT_NODEINFO_UPDATE 16 /* data: node_id:8 conn_presence:1 conn_up:1 best_rtt_packed:2 */
|
||||
#define GUI_EVT_NODEINFO_UPDATE 16 /* data: node_id:8 conn_presence:1 conn_up:1 best_rtt:2(0.1ms,0xFFFF=nodata) */
|
||||
#define GUI_EVT_CONN_LIST 20 /* data: [count:2][entry:46B]* — binary conn list */
|
||||
#define GUI_EVT_CONN_METRICS 21 /* data: text dump of selected connection metrics */
|
||||
#define GUI_EVT_MEMBER_DETAIL 22 /* data: [node_id:8][flags:1][own_tcp_active:2][links...][socks...] — live snapshot for member detail panel */
|
||||
|
||||
@@ -318,12 +318,15 @@ void gui_bridge_set_member_removed_cb(gui_member_removed_fn cb) {
|
||||
extern "C" void gui_nodeinfo_cb_impl(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* nq, void* arg) {
|
||||
(void)arg;
|
||||
if (!nq) return;
|
||||
uint16_t best_rtt = node_best_rtt(nq);
|
||||
uint8_t data[12];
|
||||
uint16_t best_rtt = topo_get_chain_rtt(nq);
|
||||
uint8_t data[16];
|
||||
memcpy(data, &nq->node_id, 8);
|
||||
data[8] = nq->conn_presence;
|
||||
data[9] = nq->conn_up;
|
||||
memcpy(data + 10, &best_rtt, 2);
|
||||
uint16_t bgp_nodes = group ? (uint16_t)queue_entry_count(group->nodes) : 0;
|
||||
memcpy(data + 12, &bgp_nodes, 2);
|
||||
memcpy(data + 14, &bgp_nodes, 2);
|
||||
gui_bridge_post(GUI_EVT_NODEINFO_UPDATE, data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -217,19 +217,20 @@ QList<NodeAddr> UtunNode::getInviteAddresses(DbManager* db) {
|
||||
|
||||
/* 3) TCP from local TCP sockets */
|
||||
{
|
||||
struct ETCP_SOCKET* ts = m_instance->tcp_sockets;
|
||||
while (ts) {
|
||||
struct sockaddr_storage* sa = &ts->interface_addr;
|
||||
struct ETCP_SOCKET* s = m_instance->etcp_sockets;
|
||||
while (s) {
|
||||
if (!s->is_tcp) { s = s->next; continue; }
|
||||
struct sockaddr_storage* sa = &s->interface_addr;
|
||||
if (sa->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
||||
QByteArray addr((const char*)&sin->sin_addr, 4);
|
||||
add_addr(addr, ntohs(sin->sin_port), 4, (int)ts->sock_id, INVITE_PROTO_TCP);
|
||||
add_addr(addr, ntohs(sin->sin_port), 4, (int)s->sock_id, INVITE_PROTO_TCP);
|
||||
} else if (sa->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
||||
QByteArray addr((const char*)&sin6->sin6_addr, 16);
|
||||
add_addr(addr, ntohs(sin6->sin6_port), 6, (int)ts->sock_id, INVITE_PROTO_TCP);
|
||||
add_addr(addr, ntohs(sin6->sin6_port), 6, (int)s->sock_id, INVITE_PROTO_TCP);
|
||||
}
|
||||
ts = ts->next;
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user