16 Commits

Author SHA1 Message Date
3c499c834b Fix stale data being saved when setting global settings.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 8m53s
2024-08-28 19:39:05 -04:00
17d6cc7d46 Let's try 0.0.22 again.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 7m47s
2024-08-28 19:20:55 -04:00
646bd7dc38 Fix changing boolean settings. 2024-08-28 19:16:19 -04:00
56e483782d Let's start work on 0.0.23. Clean out some libuv non-submodule cruft while I'm in here. 2024-08-28 19:10:16 -04:00
e1b9066b26 nix => 0.0.22.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 8m56s
2024-08-28 18:49:35 -04:00
7114ce2516 Let's release 0.0.22.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 8m54s
2024-08-28 18:40:10 -04:00
9240c6570a Changelog updates. Almost ready for a release.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 8m48s
2024-08-26 12:27:46 -04:00
f80a44ccd7 Title case settings names in the admin app.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2024-08-26 12:24:36 -04:00
e6f5eb244e Missing port.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 9m6s
2024-08-25 22:00:35 -04:00
ab62e83110 Fixed some peer ID brokenness.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2024-08-25 21:56:01 -04:00
aeefb9e536 Configure c-ares for haiku a bit better.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 7m16s
2024-08-25 13:48:57 -04:00
ee0efa536a Fix and assert against some more unsafe cross-thread JSContext use.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 7m10s
2024-08-25 13:30:46 -04:00
2523130fdc Fix some weird layout in the admin app on mobile.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 7m16s
2024-08-25 13:03:19 -04:00
c024777184 #buildfix
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 6m58s
2024-08-25 12:45:42 -04:00
5951d7cd2d Kill some warnings.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 3m41s
2024-08-25 10:07:44 -04:00
011670c70b Pass along and use the actual port we're listening on for peers.exchange.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 4m5s
2024-08-25 09:50:28 -04:00
13 changed files with 88 additions and 36 deletions

View File

@ -4,11 +4,10 @@ MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-rules
VERSION_CODE := 26 VERSION_CODE := 26
VERSION_NUMBER := 0.0.22-wip VERSION_NUMBER := 0.0.22
VERSION_NAME := Look for the helpers. VERSION_NAME := Get born soon.
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3460100.zip SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3460100.zip
LIBUV_URL := https://dist.libuv.org/dist/v1.48.0/libuv-v1.48.0.tar.gz
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
PROJECT = tildefriends PROJECT = tildefriends
@ -55,6 +54,7 @@ CFLAGS += \
-Wall \ -Wall \
-Wextra \ -Wextra \
-Wno-unused-parameter \ -Wno-unused-parameter \
-Wno-unknown-warning-option \
-MMD \ -MMD \
-MP \ -MP \
-ffunction-sections \ -ffunction-sections \
@ -501,7 +501,8 @@ $(UV_OBJS): CFLAGS += \
-Wno-unused-but-set-variable \ -Wno-unused-but-set-variable \
-Wno-unused-result \ -Wno-unused-result \
-Wno-unused-variable -Wno-unused-variable
$(UV_OBJS): CFLAGS := $(filter-out -flto,$(CFLAGS)) $(UV_OBJS): CFLAGS += -fno-lto
$(filter out/win%,$(UV_OBJS)): CFLAGS += -Wno-cast-function-type
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)
$(UV_OBJS): CFLAGS += \ $(UV_OBJS): CFLAGS += \
-D_GNU_SOURCE -D_GNU_SOURCE
@ -577,6 +578,7 @@ ifneq ($(UNAME_S),OpenBSD)
$(filter-out $(BUILD_DIR)/win%,$(SODIUM_OBJS)): CFLAGS += \ $(filter-out $(BUILD_DIR)/win%,$(SODIUM_OBJS)): CFLAGS += \
-DHAVE_ALLOCA_H -DHAVE_ALLOCA_H
endif endif
$(SODIUM_OBJS): CFLAGS := $(filter-out -flto,$(CFLAGS))
SQLITE_SOURCES := deps/sqlite/sqlite3.c SQLITE_SOURCES := deps/sqlite/sqlite3.c
SQLITE_OBJS := $(call get_objs,SQLITE_SOURCES) SQLITE_OBJS := $(call get_objs,SQLITE_SOURCES)
@ -1034,10 +1036,6 @@ apklog:
.PHONY: apklog .PHONY: apklog
fetchdeps: fetchdeps:
@echo "[fetch] libuv"
@test -f out/deps/libuv.tar.gz && test "$$(cat out/deps/libuv.txt 2>/dev/null)" = $(LIBUV_URL) || (mkdir -p out/deps/ && curl -q $(LIBUV_URL) -o out/deps/libuv.tar.gz)
@test -d deps/libuv/ && test "$$(cat out/deps/libuv.txt 2>/dev/null)" = $(LIBUV_URL) || (rm -rf deps/libuv/ && mkdir -p deps/libuv/ && tar -C deps/libuv/ -m --strip=1 -xf out/deps/libuv.tar.gz)
@echo -n $(LIBUV_URL) > out/deps/libuv.txt
@echo "[fetch] sqlite" @echo "[fetch] sqlite"
@test -f out/deps/sqlite.zip && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p out/deps/ && curl -q $(SQLITE_URL) -o out/deps/sqlite.zip) @test -f out/deps/sqlite.zip && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p out/deps/ && curl -q $(SQLITE_URL) -o out/deps/sqlite.zip)
@test -d deps/sqlite/ && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p deps/sqlite/ && unzip -qDjo -d deps/sqlite/ out/deps/sqlite.zip) @test -d deps/sqlite/ && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p deps/sqlite/ && unzip -qDjo -d deps/sqlite/ out/deps/sqlite.zip)

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🎛", "emoji": "🎛",
"previous": "&vrpS/vE7n588iYv1p8HafDxHB+YDHTrtUbJiu9nGA9I=.sha256" "previous": "&R49FywYF8CXPhoSEydLbSCgvCddeyTiBwGuDU/gqY+M=.sha256"
} }

View File

@ -27,23 +27,27 @@ function global_settings_set(key, value) {
}); });
} }
function title_case(name) {
return name.split('_').map(x => x.charAt(0).toUpperCase() + x.substring(1)).join(' ');
}
window.addEventListener('load', function () { window.addEventListener('load', function () {
const permission_template = (permission) => html` <code>${permission}</code>`; const permission_template = (permission) => html` <code>${permission}</code>`;
function input_template(key, description) { function input_template(key, description) {
if (description.type === 'boolean') { if (description.type === 'boolean') {
return html` return html`
<li class="w3-row"> <li class="w3-row">
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${key}</label> <label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>
<div class="w3-quarter w3-padding">${description.description}</div> <div class="w3-quarter w3-padding">${description.description}</div>
<input class="w3-quarter w3-check" type="checkbox" ?checked=${description.value} id=${'gs_' + key}></input> <div class="w3-quarter w3-padding w3-center"><input class="w3-check" type="checkbox" ?checked=${description.value} id=${'gs_' + key}></input></div>
<button class="w3-quarter w3-button w3-theme-action" @click=${(e) => global_settings_set(key, e.srcElement.previousElementSibling.checked)}>Set</button> <button class="w3-quarter w3-button w3-theme-action" @click=${(e) => global_settings_set(key, e.srcElement.previousElementSibling.firstChild.checked)}>Set</button>
</li> </li>
`; `;
} else if (description.type === 'textarea') { } else if (description.type === 'textarea') {
return html` return html`
<li class="w3-row"> <li class="w3-row">
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold" <label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold"
>${key}</label >${title_case(key)}</label
> >
<div class="w3-rest w3-padding">${description.description}</div> <div class="w3-rest w3-padding">${description.description}</div>
<textarea <textarea
@ -68,7 +72,7 @@ ${description.value}</textarea
} else { } else {
return html` return html`
<li class="w3-row"> <li class="w3-row">
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${key}</label> <label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>
<div class="w3-quarter w3-padding">${description.description}</div> <div class="w3-quarter w3-padding">${description.description}</div>
<input class="w3-input w3-quarter" type="text" value="${description.value}" id=${'gs_' + key}></input> <input class="w3-input w3-quarter" type="text" value="${description.value}" id=${'gs_' + key}></input>
<button class="w3-button w3-quarter w3-theme-action" @click=${(e) => global_settings_set(key, e.srcElement.previousElementSibling.value)}>Set</button> <button class="w3-button w3-quarter w3-theme-action" @click=${(e) => global_settings_set(key, e.srcElement.previousElementSibling.value)}>Set</button>

View File

@ -520,8 +520,9 @@ async function getProcessBlob(blobId, key, options) {
imports.core.globalSettingsGet = function (key) { imports.core.globalSettingsGet = function (key) {
return gGlobalSettings[key]; return gGlobalSettings[key];
}; };
imports.core.globalSettingsSet = function (key, value) { imports.core.globalSettingsSet = async function (key, value) {
print('Setting', key, value); print('Setting', key, value);
await loadSettings();
gGlobalSettings[key] = value; gGlobalSettings[key] = value;
setGlobalSettings(gGlobalSettings); setGlobalSettings(gGlobalSettings);
print('Done.'); print('Done.');
@ -1351,7 +1352,6 @@ function storePermission(user, packageOwner, packageName, permission, allow) {
export { export {
gGlobalSettings as globalSettings, gGlobalSettings as globalSettings,
setGlobalSettings,
invoke, invoke,
getSessionProcessBlob, getSessionProcessBlob,
}; };

View File

@ -21,14 +21,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.21"; version = "0.0.22";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-cBj9Hz0qT0Tqm7ivM8HPG9TNwC9iv0lTcE8XCNba8F4="; hash = "sha256-0x4LJXtMUxBsWEOoWAaQlStTfvqUf4Qs/5vJZ2EvBpY=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

View File

@ -34,23 +34,23 @@
#define CARES_TYPEOF_ARES_SSIZE_T ssize_t #define CARES_TYPEOF_ARES_SSIZE_T ssize_t
#endif #endif
#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) && !defined(__HAIKU__)
#define GETSERVBYNAME_R_ARGS 6 #define GETSERVBYNAME_R_ARGS 6
#define GETSERVBYPORT_R_ARGS 6 #define GETSERVBYPORT_R_ARGS 6
#define HAVE_GETSERVBYNAME_R 1 #define HAVE_GETSERVBYNAME_R 1
#define HAVE_GETSERVBYPORT_R 1 #define HAVE_GETSERVBYPORT_R 1
#endif #endif
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) && !defined(__HAIKU__)
#define HAVE_PIPE2 1 #define HAVE_PIPE2 1
#endif #endif
#if defined(__OpenBSD__) #if defined(__OpenBSD__) || defined(__HAIKU__)
#define GETSERVBYNAME_R_ARGS 4 #define GETSERVBYNAME_R_ARGS 4
#define GETSERVBYPORT_R_ARGS 4 #define GETSERVBYPORT_R_ARGS 4
#endif #endif
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__OpenBSD__) && !defined(__HAIKU__)
#define HAVE_MALLOC_H 1 #define HAVE_MALLOC_H 1
#define HAVE_EPOLL 1 #define HAVE_EPOLL 1
#define HAVE_SYS_EPOLL_H 1 #define HAVE_SYS_EPOLL_H 1
@ -86,7 +86,9 @@
#define HAVE_GETENV 1 #define HAVE_GETENV 1
#define HAVE_GETHOSTNAME 1 #define HAVE_GETHOSTNAME 1
#define HAVE_GETNAMEINFO 1 #define HAVE_GETNAMEINFO 1
#if !defined(__HAIKU__)
#define HAVE_GETRANDOM 1 #define HAVE_GETRANDOM 1
#endif
#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTIMEOFDAY 1
#define HAVE_IF_INDEXTONAME 1 #define HAVE_IF_INDEXTONAME 1
#define HAVE_IF_NAMETOINDEX 1 #define HAVE_IF_NAMETOINDEX 1

View File

@ -0,0 +1,12 @@
* Took an initial whack at encouraging internet-based discovery of open peers.
* Added settings to control whether replication, room, peer exchange, and account registration are allowed.
* Implemented prompt() on Android.
* Fixed some incorrect cross-thread use of the main JS context.
* Fixed yet another incorrect use of the DB from the main thread, from an RPC that isn't ever hit. Hmm.
* Minor admin layout fixes.
* Added c-ares for TXT record lookups.
* Latest libsodium-stable.
* Latest libbacktrace.
* Latest CodeMirror.
* Updated to Lit 3.2.0.
* Updated sqlite to 3.46.1.

View File

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends" package="com.unprompted.tildefriends"
android:versionCode="26" android:versionCode="26"
android:versionName="0.0.22-wip"> android:versionName="0.0.22">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application

View File

@ -39,7 +39,7 @@ const int64_t k_refresh_interval = 1ULL * 7 * 24 * 60 * 60 * 1000;
static JSValue _authenticate_jwt(tf_ssb_t* ssb, JSContext* context, const char* jwt); static JSValue _authenticate_jwt(tf_ssb_t* ssb, JSContext* context, const char* jwt);
static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name); static const char* _make_session_jwt(JSContext* context, tf_ssb_t* ssb, const char* name);
static const char* _make_set_session_cookie_header(tf_http_request_t* request, const char* session_cookie); static const char* _make_set_session_cookie_header(tf_http_request_t* request, const char* session_cookie);
static JSClassID _httpd_class_id; static JSClassID _httpd_class_id;
@ -334,7 +334,7 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va
tf_free((void*)session); tf_free((void*)session);
JSValue name = !JS_IsUndefined(jwt) ? JS_GetPropertyStr(context, jwt, "name") : JS_UNDEFINED; JSValue name = !JS_IsUndefined(jwt) ? JS_GetPropertyStr(context, jwt, "name") : JS_UNDEFINED;
const char* name_string = !JS_IsUndefined(name) ? JS_ToCString(context, name) : NULL; const char* name_string = !JS_IsUndefined(name) ? JS_ToCString(context, name) : NULL;
const char* session_token = _make_session_jwt(ssb, name_string); const char* session_token = _make_session_jwt(tf_ssb_get_context(ssb), ssb, name_string);
const char* cookie = _make_set_session_cookie_header(request, session_token); const char* cookie = _make_set_session_cookie_header(request, session_token);
tf_free((void*)session_token); tf_free((void*)session_token);
JS_FreeCString(context, name_string); JS_FreeCString(context, name_string);
@ -1305,7 +1305,7 @@ static bool _is_name_valid(const char* name)
return true; return true;
} }
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name) static const char* _make_session_jwt(JSContext* context, tf_ssb_t* ssb, const char* name)
{ {
if (!name || !*name) if (!name || !*name)
{ {
@ -1319,7 +1319,6 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
char header_base64[256]; char header_base64[256];
sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING); sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
JSContext* context = tf_ssb_get_context(ssb);
JSValue payload = JS_NewObject(context); JSValue payload = JS_NewObject(context);
JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name)); JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name));
JS_SetPropertyStr(context, payload, "exp", JS_NewInt64(context, now.tv_sec * 1000 + now.tv_nsec / 1000000LL + k_refresh_interval)); JS_SetPropertyStr(context, payload, "exp", JS_NewInt64(context, now.tv_sec * 1000 + now.tv_nsec / 1000000LL + k_refresh_interval));
@ -1493,7 +1492,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
if (registered) if (registered)
{ {
tf_free((void*)send_session); tf_free((void*)send_session);
send_session = _make_session_jwt(ssb, account_name); send_session = _make_session_jwt(context, ssb, account_name);
may_become_first_admin = true; may_become_first_admin = true;
} }
} }
@ -1513,7 +1512,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
if (set) if (set)
{ {
tf_free((void*)send_session); tf_free((void*)send_session);
send_session = _make_session_jwt(ssb, account_name); send_session = _make_session_jwt(context, ssb, account_name);
} }
} }
if (!set) if (!set)
@ -1526,7 +1525,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
if (have_account && *account_passwd && _verify_password(password, account_passwd)) if (have_account && *account_passwd && _verify_password(password, account_passwd))
{ {
tf_free((void*)send_session); tf_free((void*)send_session);
send_session = _make_session_jwt(ssb, account_name); send_session = _make_session_jwt(context, ssb, account_name);
may_become_first_admin = true; may_become_first_admin = true;
} }
else else
@ -1538,7 +1537,7 @@ static void _httpd_endpoint_login_work(tf_ssb_t* ssb, void* user_data)
else else
{ {
tf_free((void*)send_session); tf_free((void*)send_session);
send_session = _make_session_jwt(ssb, "guest"); send_session = _make_session_jwt(context, ssb, "guest");
} }
tf_free(post_form_data); tf_free(post_form_data);
} }

View File

@ -2402,6 +2402,14 @@ tf_trace_t* tf_ssb_get_trace(tf_ssb_t* ssb)
JSContext* tf_ssb_get_context(tf_ssb_t* ssb) JSContext* tf_ssb_get_context(tf_ssb_t* ssb)
{ {
if (ssb->thread_self && uv_thread_self() != ssb->thread_self)
{
const char* bt = tf_util_backtrace_string();
tf_printf("Acquiring JS context from non-main thread:\n%s\n", bt);
tf_free((void*)bt);
abort();
}
return ssb->context; return ssb->context;
} }
@ -3031,6 +3039,21 @@ int tf_ssb_server_open(tf_ssb_t* ssb, int port)
return status == 0 ? assigned_port : 0; return status == 0 ? assigned_port : 0;
} }
int tf_ssb_server_get_port(tf_ssb_t* ssb)
{
int port = 0;
if (ssb && ssb->server.data)
{
struct sockaddr_storage name = { 0 };
int size = (int)sizeof(name);
if (uv_tcp_getsockname(&ssb->server, (struct sockaddr*)&name, &size) == 0)
{
port = ntohs(((struct sockaddr_in*)&name)->sin_port);
}
}
return port;
}
void tf_ssb_server_close(tf_ssb_t* ssb) void tf_ssb_server_close(tf_ssb_t* ssb)
{ {
if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server))

View File

@ -364,6 +364,13 @@ void tf_ssb_connect_str(tf_ssb_t* ssb, const char* address);
*/ */
int tf_ssb_server_open(tf_ssb_t* ssb, int port); int tf_ssb_server_open(tf_ssb_t* ssb, int port);
/**
** Determine the port that a server is listening on.
** @param ssb The SSB instance.
** @return The port number, or 0 if not bound.
*/
int tf_ssb_server_get_port(tf_ssb_t* ssb);
/** /**
** Stop listening for SHS connections. ** Stop listening for SHS connections.
** @param ssb The SSB instance. ** @param ssb The SSB instance.

View File

@ -1384,8 +1384,8 @@ static void _tf_ssb_get_peers_exhange_callback(
peers_exchange_t* data = user_data; peers_exchange_t* data = user_data;
if (origin == k_tf_ssb_broadcast_origin_peer_exchange) if (origin == k_tf_ssb_broadcast_origin_peer_exchange)
{ {
char fullid[k_id_base64_len] = { 0 }; char fullid[256] = { 0 };
tf_base64_encode(pub, sizeof(pub), fullid, sizeof(fullid)); tf_base64_encode(pub, k_id_bin_len, fullid, sizeof(fullid));
char* dot = strchr(fullid, '.'); char* dot = strchr(fullid, '.');
if (dot) if (dot)
{ {
@ -1429,8 +1429,13 @@ static void _tf_ssb_rpc_peers_exchange_internal(
*dot = '\0'; *dot = '\0';
} }
int port = tf_ssb_connection_get_port(connection);
JSValue port_value = JS_GetPropertyStr(context, args, "port");
JS_ToInt32(context, &port, port_value);
JS_FreeValue(context, port_value);
char connection_string[1024] = { 0 }; char connection_string[1024] = { 0 };
snprintf(connection_string, sizeof(connection_string), "net:%s:%d~shs:%s", tf_ssb_connection_get_host(connection), tf_ssb_connection_get_port(connection), fullid + 1); snprintf(connection_string, sizeof(connection_string), "net:%s:%d~shs:%s", tf_ssb_connection_get_host(connection), port, fullid + 1);
tf_ssb_add_broadcast(ssb, connection_string, k_tf_ssb_broadcast_origin_peer_exchange, k_ssb_peer_exchange_expires_seconds); tf_ssb_add_broadcast(ssb, connection_string, k_tf_ssb_broadcast_origin_peer_exchange, k_ssb_peer_exchange_expires_seconds);
} }
@ -1478,6 +1483,7 @@ static void _tf_ssb_rpc_send_peers_exchange(tf_ssb_connection_t* connection)
JS_SetPropertyUint32(context, name, 1, JS_NewString(context, "exchange")); JS_SetPropertyUint32(context, name, 1, JS_NewString(context, "exchange"));
JS_SetPropertyStr(context, message, "name", name); JS_SetPropertyStr(context, message, "name", name);
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection); tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
JS_SetPropertyStr(context, message, "port", JS_NewInt32(context, tf_ssb_server_get_port(ssb)));
JS_SetPropertyStr(context, message, "peers", _tf_ssb_get_peers_exchange(ssb)); JS_SetPropertyStr(context, message, "peers", _tf_ssb_get_peers_exchange(ssb));
tf_ssb_connection_rpc_send_json(connection, k_ssb_rpc_flag_new_request, request_number, "peers.exchange", message, _tf_ssb_rpc_peers_exchange_internal, NULL, NULL); tf_ssb_connection_rpc_send_json(connection, k_ssb_rpc_flag_new_request, request_number, "peers.exchange", message, _tf_ssb_rpc_peers_exchange_internal, NULL, NULL);
JS_FreeValue(context, message); JS_FreeValue(context, message);
@ -1496,6 +1502,7 @@ static void _tf_ssb_rpc_peers_exchange(tf_ssb_connection_t* connection, uint8_t
JSContext* context = tf_ssb_connection_get_context(connection); JSContext* context = tf_ssb_connection_get_context(connection);
JSValue out_message = JS_NewObject(context); JSValue out_message = JS_NewObject(context);
JS_SetPropertyStr(context, out_message, "port", JS_NewInt32(context, tf_ssb_server_get_port(ssb)));
JS_SetPropertyStr(context, out_message, "peers", _tf_ssb_get_peers_exchange(ssb)); JS_SetPropertyStr(context, out_message, "peers", _tf_ssb_get_peers_exchange(ssb));
tf_ssb_connection_rpc_send_json(connection, flags, -request_number, NULL, out_message, NULL, NULL, NULL); tf_ssb_connection_rpc_send_json(connection, flags, -request_number, NULL, out_message, NULL, NULL, NULL);
JS_FreeValue(context, out_message); JS_FreeValue(context, out_message);

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.22-wip" #define VERSION_NUMBER "0.0.22"
#define VERSION_NAME "Look for the helpers." #define VERSION_NAME "Get born soon."