diff --git a/apps/intro/app.js b/apps/intro/app.js index 3a2313b7..2869637b 100644 --- a/apps/intro/app.js +++ b/apps/intro/app.js @@ -5,8 +5,10 @@ async function main() { } tfrpc.register(async function complete() { - if (core.user?.credentials?.permissions?.administration && - (await core.globalSettingsGet('index')) == '/~core/intro/') { + if ( + core.user?.credentials?.permissions?.administration && + (await core.globalSettingsGet('index')) == '/~core/intro/' + ) { return await core.globalSettingsSet('index', '/~core/ssb/'); } }); diff --git a/src/ssb.c b/src/ssb.c index 254c98b2..e1b18610 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -165,6 +165,12 @@ typedef struct _tf_ssb_timer_t void* user_data; } tf_ssb_timer_t; +typedef struct _tf_ssb_broadcast_result_t +{ + struct sockaddr_storage addr; + int result; +} tf_ssb_broadcast_result_t; + typedef struct _tf_ssb_t { bool own_context; @@ -192,6 +198,9 @@ typedef struct _tf_ssb_t uv_timer_t request_activity_timer; uv_tcp_t server; + tf_ssb_broadcast_result_t* broadcast_results; + int broadcast_results_count; + uint8_t network_key[32]; uint8_t pub[crypto_sign_PUBLICKEYBYTES]; @@ -2841,6 +2850,12 @@ void tf_ssb_destroy(tf_ssb_t* ssb) tf_free(ssb->room_name); ssb->room_name = NULL; } + if (ssb->broadcast_results_count) + { + tf_free(ssb->broadcast_results); + ssb->broadcast_results = NULL; + ssb->broadcast_results_count = 0; + } ssb->shutting_down_deferred = true; if (ssb->connection_ref_count == 0 && ssb->db_ref_count == 0) @@ -3257,6 +3272,39 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status) _tf_ssb_connection_read_start(connection); } +static void _tf_ssb_update_broadcast_result(tf_ssb_t* ssb, struct sockaddr* address, const char* address_str, int result) +{ + for (int i = 0; i < ssb->broadcast_results_count; i++) + { + if (ssb->broadcast_results[i].addr.ss_family == address->sa_family && address->sa_family == AF_INET && + memcmp(&ssb->broadcast_results[i].addr, address, sizeof(struct sockaddr_in)) == 0) + { + if (result != ssb->broadcast_results[i].result) + { + if (result) + { + char broadcast_str[256] = { 0 }; + uv_ip4_name((struct sockaddr_in*)address, broadcast_str, sizeof(broadcast_str)); + tf_printf("Unable to send broadcast for %s via %s (%d): %s.\n", address_str, broadcast_str, result, uv_strerror(result)); + } + ssb->broadcast_results[i].result = result; + } + return; + } + } + + if (address->sa_family == AF_INET) + { + struct sockaddr_storage storage = { 0 }; + memcpy(&storage, address, sizeof(struct sockaddr_in)); + ssb->broadcast_results = tf_resize_vec(ssb->broadcast_results, sizeof(tf_ssb_broadcast_result_t) * (ssb->broadcast_results_count + 1)); + ssb->broadcast_results[ssb->broadcast_results_count++] = (tf_ssb_broadcast_result_t) { + .result = result, + .addr = storage, + }; + } +} + static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address, struct sockaddr_in* netmask) { struct sockaddr server_addr; @@ -3290,12 +3338,7 @@ static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address, s broadcast_addr.sin_port = htons(8008); broadcast_addr.sin_addr.s_addr = (address->sin_addr.s_addr & netmask->sin_addr.s_addr) | (INADDR_BROADCAST & ~netmask->sin_addr.s_addr); r = uv_udp_try_send(&ssb->broadcast_sender, &buf, 1, (struct sockaddr*)&broadcast_addr); - if (r < 0) - { - char broadcast_str[256] = { 0 }; - uv_ip4_name(&broadcast_addr, broadcast_str, sizeof(broadcast_str)); - tf_printf("failed to send broadcast for %s via %s (%d): %s\n", address_str, broadcast_str, r, uv_strerror(r)); - } + _tf_ssb_update_broadcast_result(ssb, (struct sockaddr*)&broadcast_addr, address_str, r); } typedef struct _seeds_t