commit 85cd35e3213636d832ca02d50efed224930e60db parent 9d154ab2cdad25432c80be66f43bfb7f4759b72c Author: t3sserakt <t3ss@posteo.de> Date: Fri, 19 Dec 2025 18:44:34 +0100 Merge remote-tracking branch 'origin/master' Diffstat:
45 files changed, 8575 insertions(+), 87 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -32,3 +32,5 @@ google-services.json # Android Profiling *.hprof + +**/.DS_Store diff --git a/android_studio/app/build.gradle.kts b/android_studio/app/build.gradle.kts @@ -5,12 +5,12 @@ plugins { android { namespace = "org.gnu.gnunet" - compileSdk = 35 + compileSdk = 34 defaultConfig { applicationId = "org.gnu.gnunet" - minSdk = 31 - targetSdk = 35 + minSdk = 29 + targetSdk = 34 versionCode = 1 versionName = "1.0" @@ -44,6 +44,7 @@ android { } buildFeatures { viewBinding = true + aidl = true } } @@ -56,4 +57,6 @@ dependencies { testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) + implementation("org.gnunet:gnunet-ipc-contract:1.0.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1") } \ No newline at end of file diff --git a/android_studio/app/src/main/AndroidManifest.xml b/android_studio/app/src/main/AndroidManifest.xml @@ -2,9 +2,13 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> + <!-- bestehende Berechtigungen --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <!-- nötig, wenn du den Foreground-Service nutzt --> + <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> + <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" @@ -15,16 +19,39 @@ android:supportsRtl="true" android:theme="@style/Theme.GNUnet" android:allowNativeHeapPointerTagging="false" - tools:targetApi="31"> + tools:targetApi="34"> + <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + + <!-- ✳️ Öffentlicher Bound Service für den IPC-Contract --> + <service + android:name=".ipc.GnunetChatIpcService" + android:exported="true" + android:enabled="true"> + <intent-filter> + <!-- Muss exakt zum Client-Intent passen --> + <action android:name="org.gnunet.gnunetmessenger.ipc.BIND_GNUNET_CHAT" /> + </intent-filter> + </service> + + <!-- 🔧 Optional: Foreground-Service, falls der Server im Hintergrund + dauerhaft laufen soll (API 26+ Background-Limits) --> + <service + android:name=".ipc.GnunetForegroundService" + android:exported="false" + android:foregroundServiceType="dataSync" /> + // AndroidManifest (Server) + <service + android:name=".core.GnunetCoreService" + android:exported="false" + android:foregroundServiceType="dataSync" /> </application> </manifest> \ No newline at end of file diff --git a/android_studio/app/src/main/assets/gnunet.conf b/android_studio/app/src/main/assets/gnunet.conf @@ -10,6 +10,207 @@ GLOBAL_PREFIX = OPTIONS = -l $GNUNET_CACHE_HOME/gnunet-%Y-%m-%d.log CONFIG = /home/gnunet21/gnunet.conf +[cadet] +IMMEDIATE_START = YES +START_ON_DEMAND = YES +HOSTNAME = localhost +BINARY = gnunet-service-cadet +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +REFRESH_CONNECTION_TIME = 5 min +ID_ANNOUNCE_TIME = 1 h +CONNECT_TIMEOUT = 30 s +DHT_REPLICATION_LEVEL = 3 +MAX_CONNECTIONS = 1000 +MAX_ROUTES = 5000 +MAX_MSGS_QUEUE = 10000 +MAX_PEERS = 1000 +RATCHET_TIME = 1 h +RATCHET_MESSAGES = 64 + +[core] +START_ON_DEMAND = YES +HOSTNAME = localhost +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-core.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +USE_EPHEMERAL_KEYS = YES + +[datastore] +START_ON_DEMAND = YES +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-datastore.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTNAME = localhost +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 500 MB +BLOOMFILTER = $GNUNET_DATA_HOME/datastore/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $GNUNET_DATA_HOME/datastore/sqlite.db + +[datastore-heap] +HASHMAPSIZE = 1024 + +[dht] +IMMEDIATE_START = YES +START_ON_DEMAND = YES +HOSTNAME = localhost +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dht.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +CACHE_RESULTS = YES +DISABLE_TRY_CONNECT = NO + +[dhtcache] +DATABASE = heap +QUOTA = 50 MB +DISABLE_BF_RC = NO + +[dhtu-gnunet] +ENABLED = YES + +[dns] +START_ON_DEMAND = YES +HOSTNAME = localhost +BINARY = gnunet-service-dns +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dns.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +IFNAME = gnunet-dns +IPV6ADDR = 2001:DB8::1 +IPV6PREFIX = 126 +IPV4ADDR = 169.254.1.1 +IPV4MASK = 255.255.0.0 +DNS_EXIT = 8.8.8.8 + +[fs] +RUN_PER_USER = YES +START_ON_DEMAND = YES +IMMEDIATE_START = YES +INDEXDB = $GNUNET_DATA_HOME/fs/idxinfo.lst +RESPECT = $GNUNET_DATA_HOME/fs/credit/ +STATE_DIR = $GNUNET_DATA_HOME/fs/persistence/ +UPDATE_DIR = $GNUNET_DATA_HOME/fs/updates/ +HOSTNAME = localhost +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-fs.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +DATASTORE_QUEUE_SIZE = 32 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 +DISABLE_ANON_TRANSFER = NO +MAX_CADET_CLIENTS = 128 + +[gns] +START_ON_DEMAND = YES +IMMEDIATE_START = YES +HOSTNAME = localhost +BINARY = gnunet-service-gns +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-gns.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PARALLEL_BACKGROUND_QUERIES = 1000 +INTERCEPT_DNS = NO +.pin.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W +.gnunet.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W + +[hostlist] +IMMEDIATE_START = YES +NOARMBIND = YES +BINARY = gnunet-daemon-hostlist +HTTPPORT = 8080 +HOSTLISTFILE = $GNUNET_CONFIG_HOME/hostlist/learned.txt +ADVERTISING = YES +BOOTSTRAPPING = YES +LEARNING = YES +PROVIDE_HOSTLIST = NO +SERVERS = https://bootstrap.gnunet.org/v22 + +[identity] +START_ON_DEMAND = YES +RUN_PER_USER = YES +HOSTNAME = localhost +BINARY = gnunet-service-identity +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-identity.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +EGODIR = $GNUNET_DATA_HOME/identity/egos/ +SUBSYSTEM_CFG = $GNUNET_CONFIG_HOME/identity/subsystem_defaults.conf + +[messenger] +START_ON_DEMAND = YES +RUN_PER_USER = YES +HOSTNAME = localhost +BINARY = gnunet-service-messenger +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-messenger.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MESSENGER_DIR = $GNUNET_DATA_HOME/messenger/ +MESSENGER_AUTO_CONNECTING = YES +MESSENGER_AUTO_ROUTING = YES +MESSENGER_MIN_ROUTERS = 3 + +[namecache] +START_ON_DEMAND = YES +RUN_PER_USER = NO +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-namecache.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTNAME = localhost +BINARY = gnunet-service-namecache +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DATABASE = sqlite +DISABLE = NO + +[namecache-sqlite] +FILENAME = $GNUNET_DATA_HOME/namecache/sqlite.db + +[namestore] +START_ON_DEMAND = YES +RUN_PER_USER = YES +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-namestore.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTNAME = localhost +BINARY = gnunet-service-namestore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DATABASE = sqlite +CACHE_KEYS = YES + +[namestore-sqlite] +INIT_ON_CONNECT = YES +FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db + +[uri] +gns = gnunet-namestore -e 1a -u + [nat] START_ON_DEMAND = YES HOSTNAME = localhost @@ -30,8 +231,25 @@ STUN_FREQUENCY = 5 min STUN_SERVERS = stun.gnunet.org stun.services.mozilla.com:3478 stun.ekiga.net:3478 STUN_STALE = 60 min +[nse] +START_ON_DEMAND = YES +IMMEDIATE_START = YES +HOSTNAME = localhost +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nse.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +PROOFFILE = $GNUNET_DATA_HOME/nse/proof.dat +HISTOGRAM_DIR = $GNUNET_CACHE_HOME/nse/histogram +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 15 + [peerstore] IMMEDIATE_START = YES +USE_INCLUDED_HELLOS = YES HOSTNAME = localhost BINARY = gnunet-service-peerstore UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-peerstore.sock @@ -42,6 +260,26 @@ DATABASE = sqlite [peerstore-sqlite] FILENAME = $GNUNET_DATA_HOME/peerstore/sqlite.db +[reclaim] +START_ON_DEMAND = YES +RUN_PER_USER = YES +HOSTNAME = localhost +BINARY = gnunet-service-reclaim +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-reclaim.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +TICKET_REFRESH_INTERVAL = 6h + +[regex] +START_ON_DEMAND = YES +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-regex.sock +HOSTNAME = localhost +BINARY = gnunet-service-regex +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; + [resolver] START_ON_DEMAND = YES HOSTNAME = localhost @@ -52,6 +290,20 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver.sock UNIX_MATCH_UID = NO UNIX_MATCH_GID = NO +[revocation] +START_ON_DEMAND = YES +IMMEDIATE_START = YES +HOSTNAME = localhost +BINARY = gnunet-service-revocation +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-revocation.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +WORKBITS = 22 +EPOCH_DURATION = 365 d +DATABASE = $GNUNET_DATA_HOME/revocation.dat + [statistics] START_ON_DEMAND = YES HOSTNAME = localhost @@ -63,6 +315,16 @@ UNIX_MATCH_UID = NO UNIX_MATCH_GID = YES DATABASE = $GNUNET_DATA_HOME/statistics.dat +[set] +START_ON_DEMAND = YES +HOSTNAME = localhost +BINARY = gnunet-service-set +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-set.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + [transport] START_ON_DEMAND = YES HOSTNAME = localhost @@ -89,7 +351,7 @@ PRIVATE_KEY = /data/user/0/org.gnu.gnunet/files/private_key.ecc SYSTEM_TYPE = UNKNOWN [PATHS] -GNUNET_HOME = /data/user/0/org.gnu.gnunet/home +GNUNET_HOME = /data/user/0/org.gnu.gnunet/files/home GNUNET_DATA_HOME = $GNUNET_HOME/data GNUNET_CONFIG_HOME = $GNUNET_HOME/config GNUNET_CACHE_HOME = $GNUNET_HOME/cache diff --git a/android_studio/app/src/main/assets/plugins/libgnunet_plugin_datacache_heap.so b/android_studio/app/src/main/assets/plugins/libgnunet_plugin_datacache_heap.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunet_plugin_datastore_sqlite.so b/android_studio/app/src/main/assets/plugins/libgnunet_plugin_datastore_sqlite.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunet_plugin_namecache_sqlite.so b/android_studio/app/src/main/assets/plugins/libgnunet_plugin_namecache_sqlite.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunet_plugin_namestore_sqlite.so b/android_studio/app/src/main/assets/plugins/libgnunet_plugin_namestore_sqlite.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunet_plugin_peerstore_sqlite.so b/android_studio/app/src/main/assets/plugins/libgnunet_plugin_peerstore_sqlite.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunetutil.so b/android_studio/app/src/main/assets/plugins/libgnunetutil.so Binary files differ. diff --git a/android_studio/app/src/main/assets/plugins/libgnunetutil.so# b/android_studio/app/src/main/assets/plugins/libgnunetutil.so# Binary files differ. diff --git a/android_studio/app/src/main/cpp/CMakeLists.txt b/android_studio/app/src/main/cpp/CMakeLists.txt @@ -14,25 +14,45 @@ project("gnunet") # configure import libs set(distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../distribution) -add_library(libidn SHARED IMPORTED) -set_target_properties(libidn PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libidn/lib/${ANDROID_ABI}/libidn.so) +add_library(idn SHARED IMPORTED) +set_target_properties(idn PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/idn/lib/${ANDROID_ABI}/libidn.so) add_library(sqliteX SHARED IMPORTED) set_target_properties(sqliteX PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/sqlite/lib/${ANDROID_ABI}/libsqliteX.so) -add_library(libgnunetutil SHARED IMPORTED) -set_target_properties(libgnunetutil PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetutil/lib/${ANDROID_ABI}/libgnunetutil.so) -add_library(libgnunetsq SHARED IMPORTED) -set_target_properties(libgnunetsq PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetsq/lib/${ANDROID_ABI}/libgnunetsq.so) - -add_library(libgnunethello SHARED IMPORTED) -set_target_properties(libgnunethello PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunethello/lib/${ANDROID_ABI}/libgnunethello.so) -add_library(libgnunet SHARED IMPORTED) -set_target_properties(libgnunet PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunet/lib/${ANDROID_ABI}/libgnunet.so) +add_library(gnunetutil SHARED IMPORTED) +set_target_properties(gnunetutil PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetutil/lib/${ANDROID_ABI}/libgnunetutil.so) +add_library(gnunetsq SHARED IMPORTED) +set_target_properties(gnunetsq PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetsq/lib/${ANDROID_ABI}/libgnunetsq.so) +add_library(gnunetjson SHARED IMPORTED) +set_target_properties(gnunetjson PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetjson/lib/${ANDROID_ABI}/libgnunetjson.so) +add_library(gnunetgnsrecord SHARED IMPORTED) +set_target_properties(gnunetgnsrecord PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetgnsrecord/lib/${ANDROID_ABI}/libgnunetgnsrecord.so) +add_library(gnunetblock SHARED IMPORTED) +set_target_properties(gnunetblock PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetblock/lib/${ANDROID_ABI}/libgnunetblock.so) +add_library(gnunetregexblock SHARED IMPORTED) +set_target_properties(gnunetregexblock PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetregexblock/lib/${ANDROID_ABI}/libgnunetregexblock.so) +add_library(gnunetblockgroup SHARED IMPORTED) +set_target_properties(gnunetblockgroup PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetblockgroup/lib/${ANDROID_ABI}/libgnunetblockgroup.so) +add_library(gnunethello SHARED IMPORTED) +set_target_properties(gnunethello PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunethello/lib/${ANDROID_ABI}/libgnunethello.so) +#[[add_library(gnunet_plugin_peerstore_sqlite SHARED IMPORTED) +set_target_properties(gnunet_plugin_peerstore_sqlite PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunet_plugin_peerstore_sqlite/lib/${ANDROID_ABI}/libgnunet_plugin_peerstore_sqlite.so)]] +add_library(gnunet SHARED IMPORTED) +set_target_properties(gnunet PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunet/lib/${ANDROID_ABI}/libgnunet.so) +add_library(gnunetchat SHARED IMPORTED) +set_target_properties(gnunetchat PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/gnunetchat/lib/${ANDROID_ABI}/libgnunetchat.so) add_library(libgpg-error SHARED IMPORTED) set_target_properties(libgpg-error PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/libgpg-error/lib/${ANDROID_ABI}/libgpg-error.so) @@ -63,6 +83,18 @@ set_target_properties(libintl PROPERTIES IMPORTED_LOCATION add_library(libgettext SHARED IMPORTED) set_target_properties(libgettext PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/gettext/lib/${ANDROID_ABI}/libgettextlib-0.22.5.so) +add_library(jansson SHARED IMPORTED) +set_target_properties(jansson PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/jansson/lib/${ANDROID_ABI}/libjansson.so) +add_library(wolfssl SHARED IMPORTED) +set_target_properties(wolfssl PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/wolfssl/lib/${ANDROID_ABI}/libwolfssl.so) +add_library(libcurl SHARED IMPORTED) +set_target_properties(libcurl PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/libcurl/lib/${ANDROID_ABI}/libcurl.so) +add_library(microhttpd SHARED IMPORTED) +set_target_properties(microhttpd PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/microhttpd/lib/${ANDROID_ABI}/libmicrohttpd.so) # build application's shared lib set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -83,10 +115,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") add_library(gnunetti SHARED # List C/C++ source files with relative paths to this CMakeLists.txt. native-lib.cpp + GnunetChatIpcBridge.cpp ) target_include_directories(gnunetti PRIVATE - ${distribution_DIR}/libidn/lib/${ANDROID_ABI}/include + ${distribution_DIR}/idn/lib/${ANDROID_ABI}/include ${distribution_DIR}/sqlite/lib/${ANDROID_ABI}/include ${distribution_DIR}/libsodium/lib/${ANDROID_ABI}/include ${distribution_DIR}/libgcrypt/lib/${ANDROID_ABI}/include @@ -98,11 +131,20 @@ target_include_directories(gnunetti PRIVATE ${distribution_DIR}/libiconv/lib/${ANDROID_ABI}/include ${distribution_DIR}/libintl/lib/${ANDROID_ABI}/include ${distribution_DIR}/gettext/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetutil/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunet/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunethello/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunet_plugin_peerstore_sqlite/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetsq/lib/${ANDROID_ABI}/include) + ${distribution_DIR}/gnunetutil/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunet/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunethello/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunet_plugin_peerstore_sqlite/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetsq/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetgnsrecord/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetblock/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetregexblock/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetblockgroup/lib/${ANDROID_ABI}/include + ${distribution_DIR}/gnunetchat/lib/${ANDROID_ABI}/include + ${distribution_DIR}/wolfssl/lib/${ANDROID_ABI}/include + ${distribution_DIR}/libcurl/lib/${ANDROID_ABI}/include + ${distribution_DIR}/jansson/lib/${ANDROID_ABI}/include + ${distribution_DIR}/microhttpd/lib/${ANDROID_ABI}/include) # Specifies libraries CMake should link to your target library. You # can link libraries from various origins, such as libraries defined in this @@ -114,18 +156,27 @@ target_link_libraries(gnunetti libgcrypt libsodium libtool - libidn + idn gmp libunistring libz libiconv libintl libgettext - libgnunetutil - libgnunetsq - libgnunethello - #libgnunet_plugin_peerstore_sqlite - libgnunet + wolfssl + libcurl + jansson + microhttpd + gnunetsq + gnunetregexblock + gnunetblock + gnunetblockgroup + gnunetgnsrecord + gnunetjson + gnunethello + gnunetutil + gnunet + gnunetchat sqliteX log) diff --git a/android_studio/app/src/main/cpp/GnunetChatIpcBridge.cpp b/android_studio/app/src/main/cpp/GnunetChatIpcBridge.cpp @@ -0,0 +1,625 @@ +#include <jni.h> +#include <map> +#include <mutex> +#include <memory> +#include <atomic> +#include <string> +#include <android/log.h> +#include <android/asset_manager.h> +#include <android/asset_manager_jni.h> +#include "gnunet_chat_lib.h" +#include "gnunet_util_lib.h" + + +#define LOG_TAG "GnunetChatIpcBridge" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +// ====================================================== +// Globale Verwaltung +// ====================================================== + +static JavaVM* g_vm = nullptr; + +// Session-Map: handle (jlong) -> ChatSession +static std::mutex g_mapMtx; +struct ChatSession; +static std::map<long, std::unique_ptr<ChatSession>> g_sessions; +static std::atomic_long g_nextHandle{1}; + +static const struct GNUNET_CONFIGURATION_Handle* g_cfg = nullptr; +static std::atomic_bool g_cfgInited{false}; + +// Hilfsfunktion: Thread-sicheres JNIEnv-Beschaffen + optionales Detach +struct ScopedEnv { + JNIEnv* env = nullptr; + bool didAttach = false; + + ScopedEnv() { + if (!g_vm) return; + if (g_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK || !env) { + if (g_vm->AttachCurrentThread(&env, nullptr) == JNI_OK) { + didAttach = true; + } else { + env = nullptr; + } + } + } + ~ScopedEnv() { + if (didAttach && g_vm) { + g_vm->DetachCurrentThread(); + } + } + JNIEnv* get() const { return env; } +}; + +// ====================================================== +// Session-Struktur mit GNUnet-Handle +// ====================================================== + +struct ChatSession { + jlong handle = 0; + // Optional: Java-Callback-Objekt (IChatCallback Implementierung aus deinem Service) + jobject cbGlobal = nullptr; + + // Beispielhafte Session-Daten + std::string profileName = "GNUnet"; + bool connected = false; + + // GNUnet Chat Handle + struct GNUNET_CHAT_Handle* chatHandle = nullptr; + + ChatSession() = default; + + ~ChatSession() { + // GlobalRef bereinigen + if (cbGlobal) { + ScopedEnv senv; + if (auto* env = senv.get()) { + env->DeleteGlobalRef(cbGlobal); + } + cbGlobal = nullptr; + } + + // GNUnet Chat stoppen + if (chatHandle) { + LOGD("Stopping GNUNET_CHAT handle for session %ld", (long)handle); + GNUNET_CHAT_disconnect(chatHandle); + chatHandle = nullptr; + } + } +}; + +// Helper: Session lookup +static ChatSession* findSessionOrNull(long h) { + std::lock_guard<std::mutex> lk(g_mapMtx); + auto it = g_sessions.find(h); + return (it == g_sessions.end()) ? nullptr : it->second.get(); +} + +// ====================================================== +// JNI Setup +// ====================================================== + +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + g_vm = vm; + return JNI_VERSION_1_6; +} + +// ====================================================== +// GNUnet Callback (eingehende Nachrichten) +// -> Beispiel: ruft eine Methode am Java-Callback auf (onMessageReceived(String)) +// ====================================================== + +static JNIEnv* GetEnv() { + JNIEnv* env = nullptr; + if (g_vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) { + if (g_vm->AttachCurrentThread(&env, nullptr) != JNI_OK) return nullptr; + } + return env; +} + +// ---- kleine Helfer ---- +static void fillChatContextDto(JNIEnv* env, jobject jCtx, struct GNUNET_CHAT_Context* ctx) { + if (!env || !jCtx) return; + jclass cls = env->GetObjectClass(jCtx); + if (!cls) return; + + jfieldID fType = env->GetFieldID(cls, "chatContextType", "I"); + jfieldID fIsGroup = env->GetFieldID(cls, "isGroup", "Z"); + jfieldID fIsPlat = env->GetFieldID(cls, "isPlatform", "Z"); + jfieldID fUserPtr = env->GetFieldID(cls, "userPointer", "Ljava/lang/String;"); + + int type = 0; + bool isGroup = false; + bool isPlatform = false; + // Heuristik: Ist eine Gruppe am Context? + if (ctx) { + if (GNUNET_CHAT_context_get_group(ctx)) { isGroup = true; type = 1; } + // platform: falls du später einen Indikator hast → hier setzen + } + + env->SetIntField(jCtx, fType, (jint) type); + env->SetBooleanField(jCtx, fIsGroup, (jboolean) isGroup); + env->SetBooleanField(jCtx, fIsPlat, (jboolean) isPlatform); + env->SetObjectField(jCtx, fUserPtr, nullptr); +} + +static jlong getTimestampMillis(struct GNUNET_CHAT_Message* msg) { + if (!msg) return 0; + time_t ts = GNUNET_CHAT_message_get_timestamp(msg); + if (ts <= 0) return 0; + return (jlong) ts * 1000LL; +} + +// ---- Haupt-Callback: nur die Felder, die du brauchst ---- +static static enum GNUNET_GenericReturnValue chat_message_cb(void* cls, + struct GNUNET_CHAT_Context* ctx, + struct GNUNET_CHAT_Message* msg) { + auto* sess = static_cast<ChatSession*>(cls); + if (!sess || !sess->cbGlobal || !msg) { + return GNUNET_YES; // niemals Scheduler blockieren + } + + JNIEnv* env = GetEnv(); + if (!env) return GNUNET_YES; + + jclass clsCb = env->GetObjectClass(sess->cbGlobal); + jclass clsCtx = env->FindClass("org/gnunet/gnunetmessenger/ipc/ChatContextDto"); + jclass clsMsg = env->FindClass("org/gnunet/gnunetmessenger/ipc/ChatMessageDto"); + if (!clsCb || !clsCtx || !clsMsg) return GNUNET_YES; + + jmethodID ctorCtx = env->GetMethodID(clsCtx, "<init>", "()V"); + jmethodID ctorMsg = env->GetMethodID(clsMsg, "<init>", "()V"); + if (!ctorCtx || !ctorMsg) return GNUNET_YES; + + jobject jCtx = env->NewObject(clsCtx, ctorCtx); + jobject jMsg = env->NewObject(clsMsg, ctorMsg); + if (!jCtx || !jMsg) return GNUNET_YES; + + // -> Kontext füllen + fillChatContextDto(env, jCtx, ctx); // deine Helper-Funktion + + // -> ChatMessageDto-Felder setzen (minimal TEXT/WARNING) + jfieldID fKind = env->GetFieldID(clsMsg, "kind", "I"); + jfieldID fTimestamp = env->GetFieldID(clsMsg, "timestamp", "J"); + jfieldID fText = env->GetFieldID(clsMsg, "text", "Ljava/lang/String;"); + if (!fKind || !fTimestamp || !fText) { + env->DeleteLocalRef(jCtx); + env->DeleteLocalRef(jMsg); + return GNUNET_YES; + } + + const int kind = (int) GNUNET_CHAT_message_get_kind(msg); + env->SetIntField(jMsg, fKind, (jint) kind); + env->SetLongField(jMsg, fTimestamp, (jlong) getTimestampMillis(msg)); // dein Helper + + switch (kind) { + case GNUNET_CHAT_KIND_WARNING: + case GNUNET_CHAT_KIND_TEXT: { + const char* t = GNUNET_CHAT_message_get_text(msg); + jstring jT = t ? env->NewStringUTF(t) : nullptr; + env->SetObjectField(jMsg, fText, jT); + if (jT) env->DeleteLocalRef(jT); + break; + } + case GNUNET_CHAT_KIND_INVITATION: + default: + env->SetObjectField(jMsg, fText, (jobject) nullptr); + break; + } + + // Java-Callback: void onMessage(ChatContextDto, ChatMessageDto) + jmethodID mOnMessage = env->GetMethodID( + clsCb, + "onMessage", + "(Lorg/gnunet/gnunetmessenger/ipc/ChatContextDto;" + "Lorg/gnunet/gnunetmessenger/ipc/ChatMessageDto;)V" + ); + if (mOnMessage) { + env->CallVoidMethod(sess->cbGlobal, mOnMessage, jCtx, jMsg); + } + + env->DeleteLocalRef(jCtx); + env->DeleteLocalRef(jMsg); + return GNUNET_YES; +} + + + +extern "C" JNIEXPORT jboolean JNICALL +Java_org_gnunet_gnunetmessenger_ipc_NativeBridge_initCfgFromAsset( + JNIEnv* env, jclass, + jobject jAssetManager, jstring jAssetName) +{ + if (g_cfgInited.load()) return JNI_TRUE; + + AAssetManager* mgr = AAssetManager_fromJava(env, jAssetManager); + if (!mgr) return JNI_FALSE; + + const char* assetName = env->GetStringUTFChars(jAssetName, nullptr); + AAsset* asset = AAssetManager_open(mgr, assetName, AASSET_MODE_BUFFER); + env->ReleaseStringUTFChars(jAssetName, assetName); + if (!asset) return JNI_FALSE; + + off_t sz = AAsset_getLength(asset); + if (sz <= 0) { AAsset_close(asset); return JNI_FALSE; } + + std::vector<char> buf; + buf.resize(static_cast<size_t>(sz)); + const int readBytes = AAsset_read(asset, buf.data(), sz); + AAsset_close(asset); + if (readBytes != sz) return JNI_FALSE; + + // Config-Handle mit Projekt-Daten erzeugen (Android-Build hat die GNUnet-Projektinfos) + struct GNUNET_CONFIGURATION_Handle* cfg = + GNUNET_CONFIGURATION_create(GNUNET_OS_project_data_gnunet()); + if (!cfg) return JNI_FALSE; + + // Wichtig: deserialize erwartet die exakte Datenlänge (ohne extra NUL) + if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize(cfg, buf.data(), + static_cast<size_t>(sz), nullptr)) { + GNUNET_CONFIGURATION_destroy(cfg); + return JNI_FALSE; + } + + g_cfg = cfg; + g_cfgInited.store(true); + return JNI_TRUE; +} + +// ====================================================== +// JNI: startChat +// Signature in Kotlin/Java (Server): +// private external fun nativeStartChat(appName: String, callback: IChatCallback): Long +// Package/Cls: org.gnu.gnunet.ipc.GnunetChatIpcService +// ====================================================== + +// Ergänzung: zum Freigeben der Config +extern "C" JNIEXPORT void JNICALL +Java_org_gnunet_gnunetmessenger_ipc_NativeBridge_destroyCfg( + JNIEnv*, jclass, jlong cfgPtr) { + auto* cfg = reinterpret_cast<GNUNET_CONFIGURATION_Handle*>(cfgPtr); + if (cfg) GNUNET_CONFIGURATION_destroy(cfg); +} + +// Start mit bereits erstellter cfg +extern "C" JNIEXPORT jlong JNICALL +Java_org_gnunet_gnunetmessenger_ipc_NativeBridge_nativeStartChatUsingCfg( + JNIEnv* env, jclass, + jlong cfgPtr, jstring jAppName, jobject jCallback) { + + const char* appName = env->GetStringUTFChars(jAppName, nullptr); + LOGD("nativeStartChat(%s)", appName ? appName : "(null)"); + + // Neue Session anlegen + auto sess = std::make_unique<ChatSession>(); + sess->handle = g_nextHandle++; + if (jCallback) { + sess->cbGlobal = env->NewGlobalRef(jCallback); // global ref behalten + } + + // --- GNUnet Chat starten --- + sess->chatHandle = GNUNET_CHAT_start( + reinterpret_cast<const GNUNET_CONFIGURATION_Handle *>(cfgPtr), &chat_message_cb, sess.get()); + GNUNET_CONFIGURATION_destroy(reinterpret_cast<GNUNET_CONFIGURATION_Handle *>(cfgPtr)); + + if (!sess->chatHandle) { + LOGE("GNUNET_CHAT_start failed"); + if (sess->cbGlobal) { + env->DeleteGlobalRef(sess->cbGlobal); + sess->cbGlobal = nullptr; + } + env->ReleaseStringUTFChars(jAppName, appName); + return 0; + } + + // Session registrieren + long handle = (long)sess->handle; + { + std::lock_guard<std::mutex> lk(g_mapMtx); + g_sessions.emplace(handle, std::move(sess)); + } + + env->ReleaseStringUTFChars(jAppName, appName); + LOGD("Session created with handle=%ld", handle); + return static_cast<jlong>(handle); +} + +// ====================================================== +// JNI: createAccount +// Signature in Kotlin/Java: +// private external fun nativeCreateAccount(handle: Long, name: String): Int +// ====================================================== + +extern "C" JNIEXPORT jint JNICALL +Java_org_gnu_gnunet_ipc_GnunetChatIpcService_nativeCreateAccount( + JNIEnv* env, jobject /*thiz*/, jlong jHandle, jstring jName) { + + const char* name = env->GetStringUTFChars(jName, nullptr); + long h = static_cast<long>(jHandle); + LOGD("nativeCreateAccount(handle=%ld, name=%s)", h, name ? name : "(null)"); + + ChatSession* sess = findSessionOrNull(h); + if (!sess || !sess->chatHandle) { + env->ReleaseStringUTFChars(jName, name); + return -1; // GNUNET_SYSERR analog + } + + const char* nameC = env->GetStringUTFChars(jName, nullptr); + if (!nameC) { + LOGE("nativeCreateAccount: failed to get UTF chars"); + return GNUNET_SYSERR; + } + + int rc = GNUNET_CHAT_account_create(sess->chatHandle, nameC); + + env->ReleaseStringUTFChars(jName, name); + return rc; +} + +// ====================================================== +// JNI: connect +// Signature in Kotlin/Java: +// private external fun nativeConnect(handle: Long, accountKey: String, accountName: String) +// Du kannst die Parameterform anpassen – aktuell minimal. +// ====================================================== + +extern "C" JNIEXPORT void JNICALL +Java_org_gnu_gnunet_ipc_GnunetChatIpcService_nativeConnect( + JNIEnv* env, jobject /*thiz*/, jlong jHandle, + jstring jAccountKey, jstring jAccountName) { + + long h = static_cast<long>(jHandle); + const char* key = jAccountKey ? env->GetStringUTFChars(jAccountKey, nullptr) : ""; + const char* name = jAccountName ? env->GetStringUTFChars(jAccountName, nullptr) : ""; + struct GNUNET_CHAT_Account *account; + LOGD("nativeConnect(handle=%ld, key=%s, name=%s)", h, key, name); + + ChatSession* sess = findSessionOrNull(h); + if (!sess || !sess->chatHandle) { + if (jAccountKey) env->ReleaseStringUTFChars(jAccountKey, key); + if (jAccountName) env->ReleaseStringUTFChars(jAccountName, name); + return; + } + + account = GNUNET_CHAT_find_account( + sess->chatHandle, + name + ); + + GNUNET_CHAT_connect(sess->chatHandle, account); + + sess->connected = true; // Platzhalter + + if (jAccountKey) env->ReleaseStringUTFChars(jAccountKey, key); + if (jAccountName) env->ReleaseStringUTFChars(jAccountName, name); +} + +// ====================================================== +// JNI: disconnect +// Signature in Kotlin/Java: +// private external fun nativeDisconnect(handle: Long) +// ====================================================== + +extern "C" JNIEXPORT void JNICALL +Java_org_gnu_gnunet_ipc_GnunetChatIpcService_nativeDisconnect( + JNIEnv* /*env*/, jobject /*thiz*/, jlong jHandle) { + + long h = static_cast<long>(jHandle); + LOGD("nativeDisconnect(handle=%ld)", h); + + ChatSession* sess = findSessionOrNull(h); + if (!sess || !sess->chatHandle) return; + + if (sess->chatHandle) { + GNUNET_CHAT_disconnect(sess->chatHandle); // ✅ + sess->chatHandle = nullptr; + sess->connected = false; + } + sess->connected = false; // Platzhalter +} + +// ====================================================== +// JNI: getProfileName +// Signature in Kotlin/Java: +// private external fun nativeGetProfileName(handle: Long): String +// ====================================================== + +extern "C" JNIEXPORT jstring JNICALL +Java_org_gnu_gnunet_ipc_GnunetChatIpcService_nativeGetProfileName( + JNIEnv* env, jobject /*thiz*/, jlong jHandle) { + + long h = static_cast<long>(jHandle); + ChatSession* sess = findSessionOrNull(h); + if (!sess) return env->NewStringUTF(""); + + sess->profileName = GNUNET_CHAT_get_name (sess->chatHandle); + return env->NewStringUTF(sess->profileName.c_str()); +} + +// ====================================================== +// JNI: setProfileName +// Signature in Kotlin/Java: +// private external fun nativeSetProfileName(handle: Long, name: String) +// ====================================================== + +extern "C" JNIEXPORT void JNICALL +Java_org_gnu_gnunet_ipc_GnunetChatIpcService_nativeSetProfileName( + JNIEnv* env, jobject /*thiz*/, jlong jHandle, jstring jName) { + + long h = static_cast<long>(jHandle); + const char* name = env->GetStringUTFChars(jName, nullptr); + + ChatSession* sess = findSessionOrNull(h); + if (sess) { + GNUNET_CHAT_set_name (sess->chatHandle ,name); + sess->profileName = name ? name : ""; + } + + env->ReleaseStringUTFChars(jName, name); +} + +// --------- Hilfsfunktion: ChatAccountDto bauen --------- +static jobject buildChatAccountDto(JNIEnv* env, + const char* key, + const char* name) +{ + if (!env) return nullptr; + + jclass clsDto = env->FindClass("org/gnunet/gnunetmessenger/ipc/ChatAccountDto"); + if (!clsDto) return nullptr; + + jmethodID ctor = env->GetMethodID(clsDto, "<init>", "()V"); + if (!ctor) return nullptr; + + jobject dto = env->NewObject(clsDto, ctor); + if (!dto) return nullptr; + + jfieldID fKey = env->GetFieldID(clsDto, "key", "Ljava/lang/String;"); + jfieldID fName = env->GetFieldID(clsDto, "name", "Ljava/lang/String;"); + if (!fKey || !fName) return dto; // Felder optional setzen + + jstring jKey = key ? env->NewStringUTF(key) : nullptr; + jstring jName = name ? env->NewStringUTF(name) : nullptr; + + env->SetObjectField(dto, fKey, jKey); + env->SetObjectField(dto, fName, jName); + + if (jKey) env->DeleteLocalRef(jKey); + if (jName) env->DeleteLocalRef(jName); + + return dto; +} + +// --------- Daten für die Iteration + JNI Callback IDs cachen --------- +struct IterateAccountsCtx { + jclass cbClass = nullptr; + jobject cbGlobal = nullptr; + jmethodID onAccount = nullptr; // (LChatAccountDto;)V + jmethodID onDone = nullptr; // ()V + jmethodID onError = nullptr; // (ILjava/lang/String;)V +}; + +// --------- GNUnet-Callback: wird je Account aufgerufen --------- +static enum GNUNET_GenericReturnValue +iterateAccountsCb(void* cls, + GNUNET_CHAT_Handle* /*handle*/, + GNUNET_CHAT_Account* account) +{ + auto* ictx = static_cast<IterateAccountsCtx*>(cls); + if (!ictx) return GNUNET_YES; + + ScopedEnv senv; + JNIEnv* env = senv.get(); + if (!env || !ictx->cbGlobal || !ictx->onAccount) return GNUNET_YES; + + const char* name = GNUNET_CHAT_account_get_name(account); + const char* key = ""; // Platzhalter + //const char* name = "Account"; // Platzhalter + + jobject dto = buildChatAccountDto(env, key, name); + if (dto) { + env->CallVoidMethod(ictx->cbGlobal, ictx->onAccount, dto); + env->DeleteLocalRef(dto); + } + // Weiter iterieren + return GNUNET_YES; +} + +// --------- JNI: nativeIterateAccounts(handle, IAccountCallback) --------- +extern "C" JNIEXPORT void JNICALL +Java_org_gnunet_gnunetmessenger_ipc_NativeBridge_nativeIterateAccounts( + JNIEnv* env, jclass /*clazz*/, + jlong jHandle, + jobject jAccountCallback /* IAccountCallback */) +{ + // 1) Session finden + std::unique_ptr<ChatSession>* sessPtr = nullptr; + { + std::lock_guard<std::mutex> lk(g_mapMtx); + auto it = g_sessions.find((long) jHandle); + if (it != g_sessions.end()) { + sessPtr = &it->second; + } + } + if (!sessPtr || !sessPtr->get()) { + // Callback.onError(...) (falls verfügbar), sonst nur loggen + jclass cbCls = env->GetObjectClass(jAccountCallback); + if (cbCls) { + jmethodID onError = env->GetMethodID(cbCls, "onError", "(ILjava/lang/String;)V"); + if (onError) { + jstring jMsg = env->NewStringUTF("No such session"); + env->CallVoidMethod(jAccountCallback, onError, (jint) -1, jMsg); + if (jMsg) env->DeleteLocalRef(jMsg); + } + env->DeleteLocalRef(cbCls); + } + return; + } + + ChatSession* sess = sessPtr->get(); + if (!sess->chatHandle) { + jclass cbCls = env->GetObjectClass(jAccountCallback); + if (cbCls) { + jmethodID onError = env->GetMethodID(cbCls, "onError", "(ILjava/lang/String;)V"); + if (onError) { + jstring jMsg = env->NewStringUTF("Chat not started (chatHandle==null)"); + env->CallVoidMethod(jAccountCallback, onError, (jint) -2, jMsg); + if (jMsg) env->DeleteLocalRef(jMsg); + } + env->DeleteLocalRef(cbCls); + } + return; + } + + // 2) Callback-Methoden auflösen & GlobalRef halten (falls GNUnet anderen Thread nutzt) + IterateAccountsCtx ictx; + + ictx.cbGlobal = env->NewGlobalRef(jAccountCallback); + if (!ictx.cbGlobal) return; + + ictx.cbClass = (jclass) env->NewGlobalRef(env->GetObjectClass(jAccountCallback)); + if (!ictx.cbClass) { + env->DeleteGlobalRef(ictx.cbGlobal); + return; + } + + ictx.onAccount = env->GetMethodID( + ictx.cbClass, "onAccount", + "(Lorg/gnunet/gnunetmessenger/ipc/ChatAccountDto;)V"); + ictx.onDone = env->GetMethodID(ictx.cbClass, "onDone", "()V"); + ictx.onError = env->GetMethodID(ictx.cbClass, "onError", "(ILjava/lang/String;)V"); + + if (!ictx.onAccount) { + // Minimal: ohne onAccount können wir nichts tun + if (ictx.onError) { + jstring jMsg = env->NewStringUTF("IAccountCallback.onAccount not found"); + env->CallVoidMethod(ictx.cbGlobal, ictx.onError, (jint) -3, jMsg); + if (jMsg) env->DeleteLocalRef(jMsg); + } + env->DeleteGlobalRef(ictx.cbClass); + env->DeleteGlobalRef(ictx.cbGlobal); + return; + } + + // 3) Iteration starten (synchron) + int rc = GNUNET_CHAT_iterate_accounts(sess->chatHandle, &iterateAccountsCb, &ictx); + + // 4) Abschluss melden + if (rc < 0) { + if (ictx.onError) { + jstring jMsg = env->NewStringUTF("iterate_accounts failed"); + env->CallVoidMethod(ictx.cbGlobal, ictx.onError, (jint) rc, jMsg); + if (jMsg) env->DeleteLocalRef(jMsg); + } + } else { + if (ictx.onDone) { + env->CallVoidMethod(ictx.cbGlobal, ictx.onDone); + } + } + + // 5) Aufräumen + env->DeleteGlobalRef(ictx.cbClass); + env->DeleteGlobalRef(ictx.cbGlobal); +} +\ No newline at end of file diff --git a/android_studio/app/src/main/cpp/native-lib.cpp b/android_studio/app/src/main/cpp/native-lib.cpp @@ -8,6 +8,11 @@ #include <android/asset_manager_jni.h> #include "gnunet_util_lib.h" #include <ltdl.h> +#include <dlfcn.h> +#include <sys/stat.h> +#include <libgen.h> +#include <fcntl.h> +#include <unistd.h> #define TAG "GNUNET" @@ -27,14 +32,43 @@ static const char *tag = "GNUNET"; void *thread_func(void*) { - ssize_t rdsz; - char buf[128]; - while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) { - if(buf[rdsz - 1] == '\n') --rdsz; - buf[rdsz] = 0; /* add null-terminator */ - __android_log_write(ANDROID_LOG_DEBUG, tag, buf); + static const size_t READ_CHUNK = 1024; + static const size_t MAX_LINE = 8192; // eigene Obergrenze pro „logische“ Zeile + std::string acc; acc.reserve(MAX_LINE); + std::vector<char> tmp(READ_CHUNK); + + ssize_t n; + while ((n = read(pfd[0], tmp.data(), tmp.size())) > 0) { + acc.append(tmp.data(), n); + + size_t pos; + while ((pos = acc.find('\n')) != std::string::npos) { + std::string line = acc.substr(0, pos); + acc.erase(0, pos + 1); + + // Leer \r am Ende weg + if (!line.empty() && line.back() == '\r') line.pop_back(); + + // In handliche Teile splitten, um log-Limit/ANSI zu vermeiden + const size_t CHUNK = 1000; + for (size_t i = 0; i < line.size(); i += CHUNK) { + std::string_view part(line.c_str() + i, std::min(CHUNK, line.size() - i)); + __android_log_write(ANDROID_LOG_DEBUG, tag, std::string(part).c_str()); + } + } + + // Falls Zeile extrem lang wird, „notfall“ flushen: + if (acc.size() > MAX_LINE) { + __android_log_write(ANDROID_LOG_DEBUG, tag, "[truncated: line too long]"); + acc.clear(); + } } - return 0; + + // Rest ohne Newline flushen + if (!acc.empty()) { + __android_log_write(ANDROID_LOG_DEBUG, tag, acc.c_str()); + } + return nullptr; } int start_logger(const char *app_name) @@ -237,30 +271,205 @@ run (void *cls, } END -------------- Multi library code ----------------------------- */ +void ensure_directory_exists(const char* path) { + struct stat st; + if (stat(path, &st) != 0) { + if (mkdir(path, 0700) != 0) { + __android_log_print(ANDROID_LOG_ERROR, "APP", "Failed to create dir: %s (%s)", path, strerror(errno)); + } else { + __android_log_print(ANDROID_LOG_DEBUG, "APP", "Created dir: %s", path); + } + } else { + __android_log_print(ANDROID_LOG_DEBUG, "APP", "Dir already exists: %s", path); + } +} + +void ensure_file_exists(const char* path) { + struct stat st; + if (stat(path, &st) != 0) { + // Datei existiert nicht → versuchen, anzulegen + int fd = open(path, O_CREAT | O_WRONLY, 0600); + if (fd < 0) { + __android_log_print(ANDROID_LOG_ERROR, "APP", "Failed to create file: %s (%s)", path, strerror(errno)); + } else { + __android_log_print(ANDROID_LOG_DEBUG, "APP", "Created file: %s", path); + close(fd); + } + } else { + __android_log_print(ANDROID_LOG_DEBUG, "APP", "File already exists: %s", path); + } +} + +void copy_plugins(AAssetManager* mgr, const char* dest_dir) { + // Zielverzeichnis erstellen + mkdir(dest_dir, 0700); // Ignoriert Fehler, wenn schon existiert + + // Asset-Verzeichnis öffnen + AAssetDir* assetDir = AAssetManager_openDir(mgr, "plugins"); + if (!assetDir) { + LOGE("Could not open assets/plugins/"); + return; + } + + const char* filename = nullptr; + while ((filename = AAssetDir_getNextFileName(assetDir)) != nullptr) { + LOGD("Copying %s...", filename); + + // Pfad innerhalb von Assets + std::string asset_path = std::string("plugins/") + filename; + + AAsset* asset = AAssetManager_open(mgr, asset_path.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + LOGE("Failed to open asset %s", asset_path.c_str()); + continue; + } + + // Zielpfad vorbereiten + std::string out_path = std::string(dest_dir) + "/" + filename; + int out_fd = open(out_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0700); + if (out_fd < 0) { + LOGE("Could not create output file %s", out_path.c_str()); + AAsset_close(asset); + continue; + } + + // Kopieren + char buffer[4096]; + int read_bytes; + while ((read_bytes = AAsset_read(asset, buffer, sizeof(buffer))) > 0) { + write(out_fd, buffer, read_bytes); + } + + close(out_fd); + AAsset_close(asset); + LOGD("Copied to %s", out_path.c_str()); + } + + AAssetDir_close(assetDir); +} + +void set_executable_permissions(const char* path) { + if (chmod(path, 0700) != 0) { + __android_log_print(ANDROID_LOG_ERROR, "GNUNET", "chmod failed for %s: %s", path, strerror(errno)); + } else { + __android_log_print(ANDROID_LOG_DEBUG, "GNUNET", "chmod OK: %s", path); + } +} + extern "C" JNIEXPORT jstring JNICALL Java_org_gnu_gnunet_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */, - jobject assets) { - + jobject assets, + jstring path) { + + jboolean isCopy = JNI_FALSE; + const char *c_install_path = env->GetStringUTFChars(path, &isCopy); + const struct GNUNET_OS_ProjectData *default_pd = GNUNET_OS_project_data_gnunet(); + const struct GNUNET_OS_ProjectData my_pd = { + .libname = "libgnunetutil", + .project_dirname = "gnunet", + .binary_name = "gnunet-arm", + .version = default_pd->version, + .env_varname = "GNUNET_PREFIX", + .base_config_varname = "GNUNET_BASE_CONFIG", + .bug_email = "gnunet-developers@gnu.org", + .homepage = "http://www.gnu.org/s/gnunet/", + .config_file = "gnunet.conf", + .user_config_file = "~/.config/gnunet.conf", + .is_gnu = 1, + .gettext_domain = "gnunet", + .gettext_path = NULL, + .agpl_url = GNUNET_AGPL_URL, + .install_path_override = c_install_path + }; + void* handle_gnunet_util = dlopen("libgnunetutil.so", RTLD_NOW); + if (!handle_gnunet_util) return env->NewStringUTF("libgnunetutil.so not loaded"); + /* void* handle_plugin_peerstore_sqlite = dlopen("libgnunet_plugin_peerstore_sqlite.so", RTLD_NOW); + if (!handle_plugin_peerstore_sqlite) return env->NewStringUTF("libgnunet_plugin_peerstore_sqlite.so not loaded");*/ android_java_asset_manager = (*env).NewGlobalRef(assets); AAssetManager *mgr = AAssetManager_fromJava(env, android_java_asset_manager); - std::string tmp_file = GNUNET_DISK_mktemp ("test"); + std::string install_path_str(c_install_path); + ensure_directory_exists((install_path_str + "/gnunet").c_str()); + ensure_directory_exists((install_path_str + "/tmp").c_str()); + ensure_directory_exists((install_path_str + "/share").c_str()); + ensure_directory_exists((install_path_str + "/share/gnunet").c_str()); + ensure_directory_exists((install_path_str + "/share/gnunet/hellos").c_str()); + ensure_directory_exists((install_path_str + "/home").c_str()); + ensure_directory_exists((install_path_str + "/home/data").c_str()); + ensure_file_exists((install_path_str + "/home/data/statistics.dat").c_str()); + ensure_directory_exists((install_path_str + "/home/data/nse").c_str()); + set_executable_permissions((install_path_str + "/home/data/nse").c_str()); + ensure_file_exists((install_path_str + "/home/data/nse/proof.dat").c_str()); + set_executable_permissions((install_path_str + "/home/data/nse/proof.dat").c_str()); + ensure_directory_exists((install_path_str + "/lib").c_str()); + ensure_directory_exists((install_path_str + "/lib/gnunet").c_str()); + copy_plugins(mgr, "/data/user/0/org.gnu.gnunet/files/lib/gnunet"); + set_executable_permissions("/data/user/0/org.gnu.gnunet/files/lib/gnunet/libgnunet_plugin_datacache_heap.so"); + + struct stat st; + if (0 == stat("/data/user/0/org.gnu.gnunet/files/home/data/nse/proof.dat", &st)) { + __android_log_print(ANDROID_LOG_DEBUG, "GNUNET", "proof.dat size = %lld", (long long)st.st_size); + } else { + __android_log_print(ANDROID_LOG_ERROR, "GNUNET", "proof.dat not found after creation"); + } + + const char* proof_path = "/data/user/0/org.gnu.gnunet/files/home/data/nse/proof.dat"; + FILE* f = fopen(proof_path, "a"); + if (!f) { + __android_log_print(ANDROID_LOG_ERROR, "GNUNET", "fopen() failed on %s", proof_path); + perror("fopen"); + } else { + fprintf(f, "Write test at %ld\n", time(nullptr)); + fclose(f); + __android_log_print(ANDROID_LOG_DEBUG, "GNUNET", "Write to %s successful", proof_path); + } + + void* plugin = dlopen("/data/user/0/org.gnu.gnunet/files/lib/gnunet/libgnunet_plugin_datacache_heap.so", RTLD_NOW); + + if (!plugin) + __android_log_print(ANDROID_LOG_ERROR, "DLTEST", "dlopen failed: %s", dlerror()); + else + __android_log_print(ANDROID_LOG_DEBUG, "DLTEST", "dlopen SUCCESS for libgnunet_plugin_datacache_heap"); + + set_executable_permissions("/data/user/0/org.gnu.gnunet/files/lib/gnunet/libgnunet_plugin_datastore.so"); + + void* plugin2 = dlopen("/data/user/0/org.gnu.gnunet/files/lib/gnunet/libgnunet_plugin_datastore.so", RTLD_NOW); + + if (!plugin2) + __android_log_print(ANDROID_LOG_ERROR, "DLTEST", "dlopen failed: %s", dlerror()); + else + __android_log_print(ANDROID_LOG_DEBUG, "DLTEST", "dlopen SUCCESS for libgnunet_plugin_datastore"); + + void* handle_util = dlopen("/data/user/0/org.gnu.gnunet/files/lib/gnunet/libgnunetutil.so", RTLD_NOW | RTLD_GLOBAL); + if (!handle_util) { + __android_log_print(ANDROID_LOG_ERROR, "DLTEST", "Failed to load libgnunetutil.so: %s", dlerror()); + } else { + __android_log_print(ANDROID_LOG_DEBUG, "DLTEST", "Loaded libgnunetutil.so successfully"); + } + + const char* tmp = GNUNET_DISK_mktemp(&my_pd, "test"); + if (tmp == nullptr) { + // Fehlerbehandlung + __android_log_print(ANDROID_LOG_ERROR, "GNUNET", "mktemp failed!"); + return env->NewStringUTF("mktemp failed"); + } + std::string tmp_file = tmp; LOGD ("Temp file is here: %s", tmp_file.c_str()); int ok = lt_dlinit(); LOGD("lt_dlinit return code: %d", ok); LOGD ("current ltdl search path: %s", lt_dlgetsearchpath()); - lt_dlsetsearchpath ("/data/user/0/org.gnu.gnunet/files/"); + lt_dlsetsearchpath ("/data/user/0/org.gnu.gnunet/files/lib/gnunet"); LOGD ("current ltdl search path afterwards: %s", lt_dlgetsearchpath()); char *const non_const_ptr = const_cast<char*>(tmp_file.c_str()); char *const argvx[] = { "BuggerAll", - NULL + nullptr }; @@ -275,7 +484,7 @@ Java_org_gnu_gnunet_MainActivity_stringFromJNI( "Simulate error message. We do not no what is the actual log level.\n"); */ - AAsset *plugin_asset = AAssetManager_open(mgr, "libgnunet_plugin_peerstore_sqlite.so", AASSET_MODE_BUFFER); + /*AAsset *plugin_asset = AAssetManager_open(mgr, "libgnunet_plugin_peerstore_sqlite.so", AASSET_MODE_BUFFER); const off_t &length = AAsset_getLength(plugin_asset); char plugin_buf[length]; LOGD("libgnunet_plugin_peerstore_sqlite.so size is %ld bytes", length); @@ -292,7 +501,7 @@ Java_org_gnu_gnunet_MainActivity_stringFromJNI( GNUNET_DISK_file_write (fh, plugin_buf, length); - GNUNET_DISK_file_close (fh); + GNUNET_DISK_file_close (fh);*/ // The following code does work; so does the kotlin code that copies the .so file from the assets folder. std::vector<int> data = {1, 2, 3, 4, 5, 6}; @@ -308,21 +517,33 @@ Java_org_gnu_gnunet_MainActivity_stringFromJNI( outfile.close(); - cfg = GNUNET_CONFIGURATION_create (); + cfg = GNUNET_CONFIGURATION_create (GNUNET_OS_project_data_gnunet()); + if (cfg == nullptr) { + LOGE("Failed to create GNUNET configuration object"); + return env->NewStringUTF("Failed to create GNUNET configuration object"); + } AAsset *asset = AAssetManager_open(mgr, "gnunet.conf", AASSET_MODE_BUFFER); - const off_t &confif_file_size = AAsset_getLength(asset); - LOGD("gnunet.conf is %ld bytes", confif_file_size); - char buf[confif_file_size]; + off_t config_file_size = AAsset_getLength(asset); + LOGD("gnunet.conf is %ld bytes long", config_file_size); - AAsset_read(asset, buf, confif_file_size); - if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, buf, strlen(buf), NULL)) + std::vector<char> buf(config_file_size); + + int actually_read = AAsset_read(asset, buf.data(), config_file_size); + LOGD("actually read %d bytes", actually_read); + + // Sicherstellen, dass der Puffer nullterminiert ist + buf.push_back('\0'); + + if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize(cfg, buf.data(), config_file_size, NULL)) { LOGE ("Deserialization of configuration failed!"); } AAsset_close(asset); + LOGD("about to run GNUNET_PROGRAM_monolith_main"); - GNUNET_PROGRAM_monolith_main (1, + GNUNET_PROGRAM_monolith_main (&my_pd, + 1, argvx, cfg); diff --git a/android_studio/app/src/main/java/org/gnu/gnunet/MainActivity.kt b/android_studio/app/src/main/java/org/gnu/gnunet/MainActivity.kt @@ -1,9 +1,12 @@ package org.gnu.gnunet +import android.content.Intent import android.content.res.AssetManager -import androidx.appcompat.app.AppCompatActivity +import android.os.Build import android.os.Bundle import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import org.gnu.gnunet.core.GnunetCoreService import org.gnu.gnunet.databinding.ActivityMainBinding import java.io.File import java.io.FileOutputStream @@ -17,10 +20,25 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val dataPath: String = filesDir.getAbsolutePath() + /*try { + System.loadLibrary("gnunetutil") // Muss ganz früh geladen sein + Log.d("DEBUG", "libgnunetutil.so geladen") + } catch (e: UnsatisfiedLinkError) { + Log.e("DEBUG", "Fehler beim Laden libgnunetutil", e) + } + + try { + System.loadLibrary("gnunet_plugin_peerstore_sqlite") // Muss ganz früh geladen sein + Log.d("DEBUG", "libgnunet_plugin_peerstore_sqlite.so geladen") + } catch (e: UnsatisfiedLinkError) { + Log.e("DEBUG", "Fehler beim Laden libgnunet_plugin_peerstore_sqlite", e) + }*/ + binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - var isSuccess = copyFileFromAssetsToInternalStorage("libgnunet_plugin_peerstore_sqlite.so", "libgnunet_plugin_peerstore_sqlite.so") + var isSuccess = copyFileFromAssetsToInternalStorage("plugins/libgnunet_plugin_peerstore_sqlite.so", "libgnunet_plugin_peerstore_sqlite.so") if (isSuccess) { Log.d("GNUNET", "onCreate: file libgnunet_plugin_peerstore_sqlite.so copied successfully") } else { @@ -34,8 +52,15 @@ class MainActivity : AppCompatActivity() { Log.e("GNUNET", "onCreate: file private_key.ecc not copied :(") } + Log.d("GNUNET", "is asset null? assets = $assets") // Example of a call to a native method - binding.sampleText.text = stringFromJNI(assets) + val intent = Intent(this, GnunetCoreService::class.java) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent) + } else { + startService(intent) + } + //binding.sampleText.text = stringFromJNI(assets, dataPath) } private fun copyFileFromAssetsToInternalStorage(fileName: String, outputFileName: String): Boolean { @@ -78,12 +103,29 @@ class MainActivity : AppCompatActivity() { * A native method that is implemented by the 'gnunet' native library, * which is packaged with this application. */ - external fun stringFromJNI(assets: AssetManager): String + external fun stringFromJNI(assets: AssetManager, + path: String): String companion object { // Used to load the 'gnunet' library on application startup. init { + /*try { + + System.loadLibrary("sqliteX"); + System.loadLibrary("gnunetsq") + System.loadLibrary("gnunetutil") + System.loadLibrary("gnunetblock") + System.loadLibrary("gnunetregexblock") + System.loadLibrary("gnunetblockgroup") + System.loadLibrary("gnunetgnsrecord") + System.loadLibrary("gnunetjson") + System.loadLibrary("gnunethello") + System.loadLibrary("gnunet_plugin_peerstore_sqlite"); + System.loadLibrary("gnunet") + } catch (e: UnsatisfiedLinkError) { + Log.e("NativeLoader", "Failed to load native library", e); + }*/ System.loadLibrary("gnunetti") } } diff --git a/android_studio/app/src/main/java/org/gnu/gnunet/core/GnunetCoreService.kt b/android_studio/app/src/main/java/org/gnu/gnunet/core/GnunetCoreService.kt @@ -0,0 +1,119 @@ +package org.gnu.gnunet.core + +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.content.res.AssetManager +import android.os.Build +import android.os.Handler +import android.os.HandlerThread +import android.os.IBinder +import android.util.Log +import androidx.core.app.NotificationCompat +import org.gnu.gnunet.R +import org.gnu.gnunet.MainActivity +import org.gnunet.gnunetmessenger.ipc.IAccountCallback +import org.gnunet.gnunetmessenger.ipc.IChatCallback + + +object NativeBridge { + init { + System.loadLibrary("gnunet") + } + external fun stringFromJNI(assets: AssetManager, path: String): String + @JvmStatic external fun initCfgFromAsset(assetManager: AssetManager, assetName: String): Long + @JvmStatic external fun destroyCfg(cfgPtr: Long) + @JvmStatic external fun nativeStartChatUsingCfg(cfgPtr: Long, appName: String, cb: IChatCallback): Long + @JvmStatic external fun nativeDisconnect(sessionHandle: Long) + @JvmStatic external fun nativeGetProfileName(sessionHandle: Long): String + @JvmStatic external fun nativeSetProfileName(sessionHandle: Long, name: String) + @JvmStatic external fun nativeCreateAccount(sessionHandle: Long, name: String): Int + @JvmStatic external fun nativeConnect(sessionHandle: Long, accountKey: String, accountName: String) + @JvmStatic external fun nativeIterateAccounts(sessionHandle: Long, cb: IAccountCallback) +} + +class GnunetCoreService : Service() { + + companion object { + private const val TAG = "GnunetCoreService" + private const val CHANNEL_ID = "gnunet_core_channel" + private const val NOTIF_ID = 1001 + } + + private lateinit var thread: HandlerThread + private lateinit var handler: Handler + + override fun onCreate() { + super.onCreate() + createNotificationChannel() + + // Vordergrunddienst starten (ab Android 8 Pflicht, wenn dauerhaft läuft) + startForeground(NOTIF_ID, buildOngoingNotification()) + + // Eigener Looper-Thread für GNUnet + thread = HandlerThread("gnunet-core") + thread.start() + handler = Handler(thread.looper) + + // GNUnet-Start in den Worker-Thread verschieben (niemals im UI-Thread!) + handler.post { + try { + val res = NativeBridge.stringFromJNI(assets, filesDir.absolutePath) + Log.d(TAG, "GNUnet started: $res") + } catch (t: Throwable) { + Log.e(TAG, "GNUnet start failed", t) + stopSelf() + } + } + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + // dauerhaft laufen lassen + return START_STICKY + } + + override fun onDestroy() { + super.onDestroy() + if (this::thread.isInitialized) { + thread.quitSafely() + } + } + + override fun onBind(intent: Intent?): IBinder? = null + + // ---- Notification Helfer ---- + + private fun buildOngoingNotification(): Notification { + // Optional: Tap öffnet deine App + val contentIntent = PendingIntent.getActivity( + this, + 0, + Intent(this, MainActivity::class.java), + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) + + return NotificationCompat.Builder(this, CHANNEL_ID) + .setSmallIcon(R.mipmap.ic_launcher) // eigenes Icon verwenden + .setContentTitle("GNUnet läuft") + .setContentText("Der GNUnet-Dienst ist aktiv.") + .setOngoing(true) + .setContentIntent(contentIntent) + .build() + } + + private fun createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val mgr = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val ch = NotificationChannel( + CHANNEL_ID, + "GNUnet Core", + NotificationManager.IMPORTANCE_LOW + ) + mgr.createNotificationChannel(ch) + } + } +} +\ No newline at end of file diff --git a/android_studio/app/src/main/java/org/gnu/gnunet/ipc/GnunetChatIpcService.kt b/android_studio/app/src/main/java/org/gnu/gnunet/ipc/GnunetChatIpcService.kt @@ -0,0 +1,307 @@ +package org.gnu.gnunet.ipc + +import android.app.Service +import android.content.Intent +import android.os.IBinder +import android.os.RemoteException +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import org.gnunet.gnunetmessenger.ipc.ChatAccountDto +import org.gnunet.gnunetmessenger.ipc.ChatContextDto +import org.gnunet.gnunetmessenger.ipc.ChatMessageDto +import org.gnunet.gnunetmessenger.ipc.IAccountCallback +import org.gnunet.gnunetmessenger.ipc.IChatCallback +import org.gnunet.gnunetmessenger.ipc.IGnunetChat +import android.util.Log +import org.gnu.gnunet.core.NativeBridge + +class GnunetChatIpcService : Service() { + + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) + private val sessions = mutableMapOf<Long, Session>() + private var nextHandle = 1L + @Volatile private var cfgPtr: Long = 0L + + data class Session( + val handle: Long, + val cb: IChatCallback, + val chan: Channel<Pair<ChatContextDto, ChatMessageDto>>, + val worker: Job, + var profileName: String = "GNUnet", + var connected: Boolean = false, + val accounts: MutableList<ChatAccountDto> = mutableListOf() + ) + + companion object { + private const val TAG = "GnunetChatIpcService" + private const val OK = 0 + private const val ERR_NO_SESSION = 1 + } + + override fun onCreate() { + super.onCreate() + // Optional: dauerhaft im Hintergrund + // startService(Intent(this, GnunetForegroundService::class.java)) + } + + override fun onBind(intent: Intent): IBinder { + return object : IGnunetChat.Stub() { + override fun getApiVersion(): Int = 100 + + override fun startChat(messengerApp: String, cb: IChatCallback): Long { + applicationContext.enforceAllowedCaller() // ggf. auskommentieren bis Whitelist steht + + // 1) Channel + Worker: entkoppelt native Events vom Binder zum Client + val handle = nextHandle++ // lokaler (Java/Kotlin) Handle – wir überschreiben ihn gleich mit dem nativen, wenn vorhanden + val chan = Channel<Pair<ChatContextDto, ChatMessageDto>>( + capacity = 256, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + val worker = scope.launch(Dispatchers.IO) { + for ((ctx, msg) in chan) { + val ok = try { + cb.onMessage(ctx, msg) // an den echten Client-Binder weiterreichen + true + } catch (t: Throwable) { + Log.e(TAG, "Remote callback to client failed", t) + false + } + if (!ok) { + stopSession(handle) // Session aufräumen, wenn Client tot ist + break + } + } + } + + // 2) Interner Callback für die NATIVEN Events: schiebt nur in den Channel + val nativeCb = object : IChatCallback.Stub() { + override fun onMessage(context: ChatContextDto, message: ChatMessageDto) { + // leichtgewichtig, kein UI, kein Binder zurück zum Client + if (!chan.trySend(context to message).isSuccess) { + Log.w(TAG, "Inbound buffer full; dropping oldest") + } + } + } + + val cfg = try { ensureCfg() } + catch (t: Throwable) { + Log.e(TAG, "ensureCfg failed", t) + worker.cancel() + chan.close() + return 0L + } + + // 4) Native Start – nutzt dieselbe Config und registriert unseren internen Callback + val nativeHandle = try { + NativeBridge.nativeStartChatUsingCfg(cfg, messengerApp, nativeCb) + } catch (t: Throwable) { + Log.e(TAG, "nativeStartChatUsingCfg failed", t) + NativeBridge.destroyCfg(cfg) + worker.cancel() + chan.close() + return 0L + } finally { + // Falls du die cfg NICHT global wiederverwenden willst, hier freigeben: + NativeBridge.destroyCfg(cfg) + } + + if (nativeHandle == 0L) { + Log.e(TAG, "GNUNET_CHAT_start returned 0 (failed to start)") + worker.cancel() + chan.close() + return 0L + } + + // 5) Session registrieren (wir speichern den NATIVEN Handle) + sessions[nativeHandle] = Session( + handle = nativeHandle, + cb = cb, // Binder zum Client + chan = chan, // Inbound-Puffer + worker = worker // Forwarder-Job + // profileName / connected / accounts bleiben wie bei dir + ) + + try { + cb.asBinder().linkToDeath( + { stopSession(handle) }, // wird aufgerufen, wenn Client stirbt + 0 + ) + } catch (t: RemoteException) { + // falls der Binder schon tot war + stopSession(handle) + } + + Log.d(TAG, "startChat ok -> nativeHandle=$nativeHandle, app=$messengerApp") + return nativeHandle + } + + override fun iterateAccounts(handle: Long, cb: IAccountCallback) { + Log.d(TAG, "iterateAccounts(handle=$handle)") + + applicationContext.enforceAllowedCaller() + Log.d(TAG, "hasSession=${sessions.containsKey(handle)}") + val sess = sessions[handle] + if (sess == null) { + cb.onError(404, "Unknown handle") + return + } + + // Nicht auf dem Main-Thread iterieren + scope.launch(Dispatchers.IO) { + try { + // TODO: Hier die echte GNUnet-Iteration aufrufen. + // Fürs erste: Dummy oder aus deiner GNUnet-Brücke lesen. + // Beispiel-Dummy: + val list = listOf( + ChatAccountDto().apply { key="acc-1"; name="Alice" }, + ChatAccountDto().apply { key="acc-2"; name="Bob" } + ) + + for (dto in list) { + try { + cb.onAccount(dto) // oneway: non-blocking + } catch (t: Throwable) { + Log.e(TAG, "iterateAccounts: callback failed", t) + cb.onError(500, "callback failed: ${t.message}") + return@launch + } + } + cb.onDone() + } catch (t: Throwable) { + Log.e(TAG, "iterateAccounts failed", t) + cb.onError(500, t.message ?: "unknown error") + } + } + } + + + + override fun createAccount(handle: Long, name: String): Int { + Log.d(TAG, "createAccount(handle=$handle)") + applicationContext.enforceAllowedCaller() + + val sess = sessions[handle] ?: return ERR_NO_SESSION + + // Später: echten GNUnet-Account erstellen (JNI) und Ergebnis zurückgeben. + // Vorläufig: "Account" lokal vormerken + val account = ChatAccountDto().apply { + key = "acc:${System.currentTimeMillis()}" + this.name = name + } + sess.accounts += account + + // Beispiel: optional dem Client via Callback signalisieren (nicht zwingend) + scope.launch(Dispatchers.IO) { + runCatching { + val ctx = ChatContextDto().apply { + chatContextType = 0; userPointer = null; isGroup = false; isPlatform = false + } + val msg = ChatMessageDto().apply { + text = "Account '$name' erstellt" + timestamp = System.currentTimeMillis() + kind = 0; type = -1; senderKey = "server" + } + sess.chan.trySend(ctx to msg) + Log.d(TAG, "createAccount send") + } + } + + return OK + } + + override fun connect(handle: Long, account: ChatAccountDto?) { + applicationContext.enforceAllowedCaller() + val sess = sessions[handle] ?: return + // Hier später GNUNET_CHAT_connect(handle, account) aufrufen + sess.connected = true + // Optional: Event rausschicken + val ctx = ChatContextDto().apply { + chatContextType = 0; userPointer = null; isGroup = false; isPlatform = false + } + val msg = ChatMessageDto().apply { + text = "Verbunden mit Account: ${account?.name ?: "(null)"}" + timestamp = System.currentTimeMillis() + kind = 0; type = -1; senderKey = "server" + } + scope.launch { sess.chan.trySend(ctx to msg) } + } + + override fun disconnect(handle: Long) { + applicationContext.enforceAllowedCaller() + stopSession(handle) // bestehende Utility bei dir, die worker cancelt, chan schließt, Map-Eintrag entfernt + } + + override fun getProfileName(handle: Long): String { + applicationContext.enforceAllowedCaller() + val sess = sessions[handle] ?: return "" + return sess.profileName + } + + override fun setProfileName(handle: Long, name: String) { + applicationContext.enforceAllowedCaller() + val sess = sessions[handle] ?: return + sess.profileName = name + + // optional: Event an Client + scope.launch(Dispatchers.IO) { + runCatching { + val ctx = ChatContextDto().apply { + chatContextType = 0; userPointer = null; isGroup = false; isPlatform = false + } + val msg = ChatMessageDto().apply { + text = "Profilname gesetzt: $name" + timestamp = System.currentTimeMillis() + kind = 0; type = -1; senderKey = "server" + } + sess.chan.trySend(ctx to msg) + } + } + } + } + } + + private fun stopSession(handle: Long) { + val sess = sessions.remove(handle) ?: return // idempotent + try { + // 1) JNI: native Seite trennen & Session freigeben + runCatching { NativeBridge.nativeDisconnect(handle) } + .onFailure { Log.w(TAG, "nativeDisconnect failed for $handle", it) } + + // 2) Worker/Channel schließen + sess.worker.cancel() + sess.chan.close() + + } catch (t: Throwable) { + Log.w(TAG, "stopSession cleanup error", t) + } + } + + override fun onDestroy() { + val ptr = cfgPtr + if (ptr != 0L) { + runCatching { NativeBridge.destroyCfg(ptr) } + cfgPtr = 0L + } + sessions.keys.toList().forEach { stopSession(it) } + scope.cancel() + super.onDestroy() + } + + // --- Öffentliche Hilfsfunktion für deine GNUnet-Bridge --- + fun emitToHandle(handle: Long, ctx: ChatContextDto, msg: ChatMessageDto) { + sessions[handle]?.chan?.trySend(ctx to msg) + } + + private fun ensureCfg(): Long { + var local = cfgPtr + if (local != 0L) return local + synchronized(this) { + if (cfgPtr == 0L) { + cfgPtr = NativeBridge.initCfgFromAsset(applicationContext.assets, "gnunet.conf") + require(cfgPtr != 0L) { "initCfgFromAsset failed (cfgPtr==0)" } + } + return cfgPtr + } + } +} +\ No newline at end of file diff --git a/android_studio/app/src/main/java/org/gnu/gnunet/ipc/GnunetForegroundService.kt b/android_studio/app/src/main/java/org/gnu/gnunet/ipc/GnunetForegroundService.kt @@ -0,0 +1,24 @@ +package org.gnu.gnunet.ipc + +import android.app.* +import android.content.Intent +import android.os.Build +import android.os.IBinder +import androidx.core.app.NotificationCompat + +class GnunetForegroundService : Service() { + override fun onCreate() { + super.onCreate() + if (Build.VERSION.SDK_INT >= 26) { + getSystemService(NotificationManager::class.java) + .createNotificationChannel(NotificationChannel("gnunet_srv","GNUnet", NotificationManager.IMPORTANCE_LOW)) + } + val notif = NotificationCompat.Builder(this, "gnunet_srv") + .setContentTitle("GNUnet läuft") + .setContentText("Bereit für Client-Verbindungen") + .setSmallIcon(android.R.drawable.stat_sys_download_done) + .build() + startForeground(1, notif) + } + override fun onBind(intent: Intent?): IBinder? = null +} +\ No newline at end of file diff --git a/android_studio/app/src/main/java/org/gnu/gnunet/ipc/Security.kt b/android_studio/app/src/main/java/org/gnu/gnunet/ipc/Security.kt @@ -0,0 +1,41 @@ +package org.gnu.gnunet.ipc + +import android.content.Context +import android.content.pm.PackageManager +import android.os.Binder +import android.util.Base64 +import java.security.MessageDigest +import java.security.cert.CertificateFactory +import java.security.cert.X509Certificate + +private val allowedPackages = setOf("org.gnunet.gnunetmessenger") + +// SHA-256 der Signing-Zertifikate erlaubter Clients (Base64 der DER-Bytes) +private val ALLOWED_CERT_SHA256: Set<String> = setOf( + // TODO: hier echten Fingerprint der Client-App(s) eintragen +) + +private fun X509Certificate.sha256Base64(): String { + val md = MessageDigest.getInstance("SHA-256") + return Base64.encodeToString(md.digest(encoded), Base64.NO_WRAP) +} + +private fun Context.packageCertsBase64(pkg: String): List<String> { + val info = packageManager.getPackageInfo(pkg, PackageManager.GET_SIGNING_CERTIFICATES) + val cf = CertificateFactory.getInstance("X.509") + return info.signingInfo.apkContentsSigners.map { sig -> + val cert = cf.generateCertificate(sig.toByteArray().inputStream()) as X509Certificate + cert.sha256Base64() + } +} + +fun Context.enforceAllowedCaller() { + val uid = Binder.getCallingUid() + val pkgs = packageManager.getPackagesForUid(uid)?.toList().orEmpty() + if (pkgs.isEmpty()) throw SecurityException("No package for uid=$uid") + else if ((pkgs intersect allowedPackages).isEmpty()) { + throw SecurityException("Caller not allowed. uid=$uid pkgs=$pkgs") + } + /*val ok = pkgs.any { pkg -> runCatching { packageCertsBase64(pkg) }.getOrNull()?.any { it in ALLOWED_CERT_SHA256 } == true } + if (!ok) throw SecurityException("Caller not allowed. uid=$uid pkgs=$pkgs")*/ +} +\ No newline at end of file diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_disk_lib.h b/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_disk_lib.h @@ -0,0 +1,823 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-2012 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * + * @file + * Disk IO APIs + * + * @defgroup disk Disk library + * Disk IO APIs + * @{ + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_DISK_LIB_H +#define GNUNET_DISK_LIB_H + +/** + * Handle used to manage a pipe. + */ +struct GNUNET_DISK_PipeHandle; + +/** + * Type of a handle. + */ +enum GNUNET_FILE_Type +{ + /** + * Handle represents an event. + */ + GNUNET_DISK_HANLDE_TYPE_EVENT, + + /** + * Handle represents a file. + */ + GNUNET_DISK_HANLDE_TYPE_FILE, + + /** + * Handle represents a pipe. + */ + GNUNET_DISK_HANLDE_TYPE_PIPE +}; + +/** + * Handle used to access files (and pipes). + */ +struct GNUNET_DISK_FileHandle +{ + /** + * File handle on Unix-like systems. + */ + int fd; +}; + + +/* we need size_t, and since it can be both unsigned int + or unsigned long long, this IS platform dependent; + but "stdlib.h" should be portable 'enough' to be + unconditionally available... */ + +#include <stdlib.h> +#include "gnunet_configuration_lib.h" +#include "gnunet_scheduler_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Specifies how a file should be opened. + */ +enum GNUNET_DISK_OpenFlags +{ + /** + * Open the file for reading + */ + GNUNET_DISK_OPEN_READ = 1, + + /** + * Open the file for writing + */ + GNUNET_DISK_OPEN_WRITE = 2, + + /** + * Open the file for both reading and writing + */ + GNUNET_DISK_OPEN_READWRITE = 3, + + /** + * Fail if file already exists + */ + GNUNET_DISK_OPEN_FAILIFEXISTS = 4, + + /** + * Truncate file if it exists + */ + GNUNET_DISK_OPEN_TRUNCATE = 8, + + /** + * Create file if it doesn't exist + */ + GNUNET_DISK_OPEN_CREATE = 16, + + /** + * Append to the file + */ + GNUNET_DISK_OPEN_APPEND = 32 +}; + +/** + * Specifies what type of memory map is desired. + */ +enum GNUNET_DISK_MapType +{ + /** + * Read-only memory map. + */ + GNUNET_DISK_MAP_TYPE_READ = 1, + + /** + * Write-able memory map. + */ + GNUNET_DISK_MAP_TYPE_WRITE = 2, + + /** + * Read-write memory map. + */ + GNUNET_DISK_MAP_TYPE_READWRITE = 3 +}; + + +/** + * File access permissions, UNIX-style. + */ +enum GNUNET_DISK_AccessPermissions +{ + /** + * Nobody is allowed to do anything to the file. + */ + GNUNET_DISK_PERM_NONE = 0, + + /** + * Owner can read. + */ + GNUNET_DISK_PERM_USER_READ = 1, + + /** + * Owner can write. + */ + GNUNET_DISK_PERM_USER_WRITE = 2, + + /** + * Owner can execute. + */ + GNUNET_DISK_PERM_USER_EXEC = 4, + + /** + * Group can read. + */ + GNUNET_DISK_PERM_GROUP_READ = 8, + + /** + * Group can write. + */ + GNUNET_DISK_PERM_GROUP_WRITE = 16, + + /** + * Group can execute. + */ + GNUNET_DISK_PERM_GROUP_EXEC = 32, + + /** + * Everybody can read. + */ + GNUNET_DISK_PERM_OTHER_READ = 64, + + /** + * Everybody can write. + */ + GNUNET_DISK_PERM_OTHER_WRITE = 128, + + /** + * Everybody can execute. + */ + GNUNET_DISK_PERM_OTHER_EXEC = 256 +}; + + +/** + * Constants for specifying how to seek. Do not change values or order, + * some of the code depends on the specific numeric values! + */ +enum GNUNET_DISK_Seek +{ + /** + * Seek an absolute position (from the start of the file). + */ + GNUNET_DISK_SEEK_SET = 0, + + /** + * Seek a relative position (from the current offset). + */ + GNUNET_DISK_SEEK_CUR = 1, + + /** + * Seek an absolute position from the end of the file. + */ + GNUNET_DISK_SEEK_END = 2 +}; + + +/** + * Enumeration identifying the two ends of a pipe. + */ +enum GNUNET_DISK_PipeEnd +{ + /** + * The reading-end of a pipe. + */ + GNUNET_DISK_PIPE_END_READ = 0, + + /** + * The writing-end of a pipe. + */ + GNUNET_DISK_PIPE_END_WRITE = 1 +}; + + +/** + * Checks whether a handle is invalid + * + * @param h handle to check + * @return #GNUNET_YES if invalid, #GNUNET_NO if valid + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h); + + +/** + * Check that fil corresponds to a filename + * (of a file that exists and that is not a directory). + * + * @param fil filename to check + * @return #GNUNET_YES if yes, #GNUNET_NO if not a file, #GNUNET_SYSERR if something + * else (will print an error message in that case, too). + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_test (const char *fil); + + +/** + * Check that fil corresponds to a filename and the file has read permissions. + * + * @param fil filename to check + * @return #GNUNET_YES if yes, #GNUNET_NO if file doesn't exist or + * has no read permissions, #GNUNET_SYSERR if something else + * (will print an error message in that case, too). + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_test_read (const char *fil); + + +/** + * Move a file out of the way (create a backup) by renaming it to "orig.NUM~" + * where NUM is the smallest number that is not used yet. + * + * @param fil name of the file to back up + * @return the backup file name (must be freed by caller) + */ +char* +GNUNET_DISK_file_backup (const char *fil); + + +/** + * Move the read/write pointer in a file + * @param h handle of an open file + * @param offset position to move to + * @param whence specification to which position the offset parameter relates to + * @return the new position on success, #GNUNET_SYSERR otherwise + */ +off_t +GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, + off_t offset, + enum GNUNET_DISK_Seek whence); + + +/** + * Get the size of the file (or directory) of the given file (in + * bytes). + * + * @param filename name of the file or directory + * @param size set to the size of the file (or, + * in the case of directories, the sum + * of all sizes of files in the directory) + * @param include_symbolic_links should symbolic links be + * included? + * @param single_file_mode #GNUNET_YES to only get size of one file + * and return #GNUNET_SYSERR for directories. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_size (const char *filename, + uint64_t *size, + int include_symbolic_links, + int single_file_mode); + + +/** + * Obtain some unique identifiers for the given file + * that can be used to identify it in the local system. + * This function is used between GNUnet processes to + * quickly check if two files with the same absolute path + * are actually identical. The two processes represent + * the same peer but may communicate over the network + * (and the file may be on an NFS volume). This function + * may not be supported on all operating systems. + * + * @param filename name of the file + * @param dev set to the device ID + * @param ino set to the inode ID + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_get_identifiers (const char *filename, + uint64_t *dev, + uint64_t *ino); + + +/** + * Create an (empty) temporary file on disk. If the given name is not + * an absolute path, the current 'TMPDIR' will be prepended. In any case, + * 6 random characters will be appended to the name to create a unique + * filename. + * + * @param pd project data to use to determine paths + * @param t component to use for the name; + * does NOT contain "XXXXXX" or "/tmp/". + * @return NULL on error, otherwise name of fresh + * file on disk in directory for temporary files + */ +char * +GNUNET_DISK_mktemp (const struct GNUNET_OS_ProjectData *pd, + const char *t); + + +/** + * Create an (empty) temporary directory on disk. If the given name is not an + * absolute path, the current 'TMPDIR' will be prepended. In any case, 6 + * random characters will be appended to the name to create a unique name. + * + * @param pd project data to use to determine paths + * @param t component to use for the name; + * does NOT contain "XXXXXX" or "/tmp/". + * @return NULL on error, otherwise name of freshly created directory + */ +char * +GNUNET_DISK_mkdtemp (const struct GNUNET_OS_ProjectData *pd, + const char *t); + + +/** + * Open a file. Note that the access permissions will only be + * used if a new file is created and if the underlying operating + * system supports the given permissions. + * + * @param fn file name to be opened + * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags + * @param perm permissions for the newly created file, use + * #GNUNET_DISK_PERM_NONE if a file could not be created by this + * call (because of flags) + * @return IO handle on success, NULL on error + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_file_open (const char *fn, + enum GNUNET_DISK_OpenFlags flags, + enum GNUNET_DISK_AccessPermissions perm); + + +/** + * Get the size of an open file. + * + * @param fh open file handle + * @param size where to write size of the file + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, + off_t *size); + + +/** + * Flags for #GNUNET_DISK_pipe(). + */ +enum GNUNET_DISK_PipeFlags +{ + + /** + * No special options, use non-blocking read/write operations. + */ + GNUNET_DISK_PF_NONE, + + /** + * Configure read end to block when reading if set. + */ + GNUNET_DISK_PF_BLOCKING_READ = 1, + + /** + * Configure write end to block when writing if set. + */ + GNUNET_DISK_PF_BLOCKING_WRITE = 2, + + /** + * Configure both pipe ends for blocking operations if set. + */ + GNUNET_DISK_PF_BLOCKING_RW = GNUNET_DISK_PF_BLOCKING_READ + | GNUNET_DISK_PF_BLOCKING_WRITE + +}; + + +/** + * Creates an interprocess channel + * + * @param pf how to configure the pipe + * @return handle to the new pipe, NULL on error + */ +struct GNUNET_DISK_PipeHandle * +GNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf); + + +/** + * Creates a pipe object from a couple of file descriptors. + * Useful for wrapping existing pipe FDs. + * + * @param pf how to configure the pipe + * @param fd an array of two fd values. One of them may be -1 for read-only or write-only pipes + * @return handle to the new pipe, NULL on error + */ +struct GNUNET_DISK_PipeHandle * +GNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, + int fd[2]); + + +/** + * Closes an interprocess channel + * @param p pipe + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p); + + +/** + * Closes one half of an interprocess channel + * + * @param p pipe to close end of + * @param end which end of the pipe to close + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd end); + + +/** + * Detaches one of the ends from the pipe. + * Detached end is a fully-functional FileHandle, it will + * not be affected by anything you do with the pipe afterwards. + * Each end of a pipe can only be detched from it once (i.e. + * it is not duplicated). + * + * @param p pipe to detach an end from + * @param end which end of the pipe to detach + * @return Detached end on success, NULL on failure + * (or if that end is not present or is closed). + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd end); + +/** + * Close an open file. + * + * @param h file handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h); + + +/** + * Get the handle to a particular pipe end + * + * @param p pipe + * @param n end to access + * @return handle for the respective end + */ +const struct GNUNET_DISK_FileHandle * +GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd n); + + +/** + * Update POSIX permissions mask of a file on disk. If both arguments + * are #GNUNET_NO, the file is made world-read-write-executable (777). + * Does nothing on W32. + * + * @param fn name of the file to update + * @param require_uid_match #GNUNET_YES means 700 + * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set + */ +void +GNUNET_DISK_fix_permissions (const char *fn, + int require_uid_match, + int require_gid_match); + + +/** + * Get a handle from a native integer FD. + * + * @param fno native integer file descriptor + * @return file handle corresponding to the descriptor + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_get_handle_from_int_fd (int fno); + + +/** + * Get a handle from a native FD. + * + * @param fd native file descriptor + * @return file handle corresponding to the descriptor + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_get_handle_from_native (FILE *fd); + + +/** + * Read the contents of a binary file into a buffer. + * + * @param h handle to an open file + * @param result the buffer to write the result to + * @param len the maximum number of bytes to read + * @return the number of bytes read on success, #GNUNET_SYSERR on failure + */ +ssize_t +GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, + void *result, + size_t len); + + +/** + * Read the contents of a binary file into a buffer. + * + * @param fn file name + * @param result the buffer to write the result to + * @param len the maximum number of bytes to read + * @return number of bytes read, #GNUNET_SYSERR on failure + */ +ssize_t +GNUNET_DISK_fn_read (const char *fn, + void *result, + size_t len); + + +/** + * Write a buffer to a file. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return number of bytes written on success, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a buffer to a file, blocking, if necessary. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return number of bytes written on success, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a buffer to a file atomically. The directory is created if + * necessary. Fail if @a filename already exists or if not exactly @a buf + * with @a buf_size bytes could be written to @a filename. + * + * @param fn file name + * @param buf the data to write + * @param buf_size number of bytes to write from @a buf + * @param mode file permissions + * @return #GNUNET_OK on success, + * #GNUNET_NO if a file existed under @a filename + * #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_fn_write (const char *fn, + const void *buf, + size_t buf_size, + enum GNUNET_DISK_AccessPermissions mode); + + +/** + * Copy a file. + * + * @param src file to copy + * @param dst destination file name + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_copy (const char *src, + const char *dst); + + +/** + * Scan a directory for files. + * + * @param dir_name the name of the directory + * @param callback the method to call for each file + * @param callback_cls closure for @a callback + * @return the number of files found, -1 on error + */ +int +GNUNET_DISK_directory_scan (const char *dir_name, + GNUNET_FileNameCallback callback, + void *callback_cls); + +/** + * Find all files matching a glob pattern. + * + * Currently, the glob_pattern only supports asterisks in the last + * path component. + * + * @param glob_pattern the glob pattern to search for + * @param callback the method to call for each file + * @param callback_cls closure for @a callback + * @return the number of files found, -1 on error + */ +int +GNUNET_DISK_glob (const char *glob_pattern, + GNUNET_FileNameCallback callback, + void *callback_cls); + + +/** + * Create the directory structure for storing + * a file. + * + * @param filename name of a file in the directory + * @returns #GNUNET_OK on success, #GNUNET_SYSERR on failure, + * #GNUNET_NO if directory exists but is not writeable + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_create_for_file (const char *filename); + + +/** + * Test if @a fil is a directory and listable. Optionally, also check if the + * directory is readable. Will not print an error message if the directory does + * not exist. Will log errors if #GNUNET_SYSERR is returned (i.e., a file exists + * with the same name). + * + * @param fil filename to test + * @param is_readable #GNUNET_YES to additionally check if @a fil is readable; + * #GNUNET_NO to disable this check + * @return #GNUNET_YES if yes, #GNUNET_NO if not; #GNUNET_SYSERR if it + * does not exist or `stat`ed + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_test (const char *fil, + int is_readable); + + +/** + * Remove all files in a directory (rm -rf). Call with caution. + * + * @param filename the file to remove + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_remove (const char *filename); + + +/** + * Remove the directory given under @a option in + * section [PATHS] in configuration under @a cfg_filename + * + * @param pd project data to use to determine paths + * @param cfg_filename configuration file to parse + * @param option option with the dir name to purge + */ +void +GNUNET_DISK_purge_cfg_dir (const struct GNUNET_OS_ProjectData *pd, + const char *cfg_filename, + const char *option); + + +/** + * Implementation of "mkdir -p" + * + * @param dir the directory to create + * @returns #GNUNET_SYSERR on failure, #GNUNET_OK otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_create (const char *dir); + + +/** + * @brief Removes special characters as ':' from a filename. + * @param fn the filename to canonicalize + */ +void +GNUNET_DISK_filename_canonicalize (char *fn); + + +/** + * @brief Change owner of a file + * @param filename file to change + * @param user new owner of the file + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_change_owner (const char *filename, + const char *user); + + +/** + * Opaque handle for a memory-mapping operation. + */ +struct GNUNET_DISK_MapHandle; + + +/** + * Map a file into memory. + * + * @param h open file handle + * @param m handle to the new mapping (will be set) + * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx + * @param len size of the mapping + * @return pointer to the mapped memory region, NULL on failure + */ +void * +GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, + struct GNUNET_DISK_MapHandle **m, + enum GNUNET_DISK_MapType access, + size_t len); + + +/** + * Unmap a file + * + * @param h mapping handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h); + + +/** + * Write file changes to disk + * + * @param h handle to an open file + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_DISK_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_disk_lib.h */ diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_json_lib.h b/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_json_lib.h @@ -0,0 +1,1074 @@ +/* + This file is part of GNUnet + Copyright (C) 2014, 2015, 2016, 2020, 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file gnunet_json_lib.h + * @brief functions to parse JSON objects into GNUnet objects + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#ifndef GNUNET_JSON_LIB_H +#define GNUNET_JSON_LIB_H + +#include "gnunet_util_lib.h" +#include <jansson.h> + +/* ****************** Generic parser interface ******************* */ + +/** + * @brief Entry in parser specification for #GNUNET_JSON_parse(). + */ +struct GNUNET_JSON_Specification; + + +/** + * Function called to parse JSON argument. + * + * @param cls closure + * @param root JSON to parse + * @param spec our specification entry with further details + * @return #GNUNET_SYSERR on error, + * #GNUNET_OK on success + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_JSON_Parser)(void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec); + + +/** + * Function called to clean up data from earlier parsing. + * + * @param cls closure + * @param spec our specification entry with data to clean. + */ +typedef void +(*GNUNET_JSON_Cleaner) (void *cls, + struct GNUNET_JSON_Specification *spec); + + +/** + * @brief Entry in parser specification for #GNUNET_JSON_parse(). + */ +struct GNUNET_JSON_Specification +{ + /** + * Function for how to parse this type of entry. + */ + GNUNET_JSON_Parser parser; + + /** + * Function for how to clean up this type of entry. + */ + GNUNET_JSON_Cleaner cleaner; + + /** + * Closure for @e parser and @e cleaner. + */ + void *cls; + + /** + * Name of the field to parse, use NULL to get the JSON + * of the main object instead of the JSON of an individual field. + */ + const char *field; + + /** + * Pointer, details specific to the @e parser. + */ + void *ptr; + + /** + * Pointer to set to true if this argument is + * indeed missing. Can be NULL. + */ + bool *missing; + + /** + * Where should we store the final size of @e ptr. + */ + size_t *size_ptr; + + /** + * Number of bytes available in @e ptr. + */ + size_t ptr_size; + + /** + * Set to true if this component is optional. + */ + bool is_optional; +}; + + +/** + * Navigate and parse data in a JSON tree. Tries to parse the @a root + * to find all of the values given in the @a spec. If one of the + * entries in @a spec cannot be found or parsed, the name of the JSON + * field is returned in @a error_json_name, and the offset of the + * entry in @a spec is returned in @a error_line. + * + * @param root the JSON node to start the navigation at. + * @param[in,out] spec parse specification array + * @param[out] error_json_name which JSON field was problematic + * @param[out] error_line which index into @a spec did we encounter an error + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_JSON_parse (const json_t *root, + struct GNUNET_JSON_Specification *spec, + const char **error_json_name, + unsigned int *error_line); + + +/** + * Frees all elements allocated during a #GNUNET_JSON_parse() + * operation. Convenience function to be called if cleaning + * up all heap-allocated data from a #GNUNET_JSON_parse() is + * desired. The function does not have to be called if no data + * was heap-allocated (e.g. only integers, strings and fixed-sized + * data was used), or if the application calls the respective + * code to free the heap (not always #GNUNET_free(), depends + * on the data type!) on the returned heap-allocated data itself. + * + * @param[in,out] spec specification of the parse operation + */ +void +GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec); + + +/* ****************** Canonical parser specifications ******************* */ + + +/** + * End of a parser specification. + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_end (void); + + +/** + * Set the "optional" flag for a parser specification entry. + * + * @param spec specification to modify + * @param[out] missing set to true if the argument is missing, NULL is allowed. + * @return spec copy of @a spec with optional bit set + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec, + bool *missing); + + +/** + * Variable size object (in network byte order, encoded using Crockford + * Base32hex encoding). + * + * @param name name of the JSON field + * @param[out] obj pointer where to write the data, must have @a size bytes + * @param size number of bytes expected in @a obj + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_fixed (const char *name, + void *obj, + size_t size); + + +/** + * Fixed size object (in network byte order, encoded using Crockford + * Base32hex encoding). + * + * @param name name of the JSON field + * @param obj pointer where to write the data (type of `*obj` will determine size) + */ +#define GNUNET_JSON_spec_fixed_auto(name, obj) \ + GNUNET_JSON_spec_fixed (name, (obj), sizeof(*(obj))) + + +/** + * Variable size object (in network byte order, encoded using base64 encoding). + * + * @param name name of the JSON field + * @param[out] obj pointer where to write the data, must have @a size bytes + * @param size number of bytes expected in @a obj + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_fixed64 (const char *name, + void *obj, + size_t size); + + +/** + * Fixed size object (in network byte order, encoded using base64 encoding). + * + * @param name name of the JSON field + * @param obj pointer where to write the data (type of `*obj` will determine size) + */ +#define GNUNET_JSON_spec_fixed64_auto(name, obj) \ + GNUNET_JSON_spec_fixed (name, (obj), sizeof(*(obj))) + + +/** + * Variable size object (in network byte order, encoded using + * Crockford Base32hex encoding). + * + * @param name name of the JSON field + * @param[out] obj pointer where to write the data, will be allocated + * @param[out] size where to store the number of bytes allocated for @a obj + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_varsize (const char *name, + void **obj, + size_t *size); + + +/** + * The expected field stores a string. + * + * @param name name of the JSON field + * @param strptr where to store a pointer to the field + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_string (const char *name, + const char **strptr); + + +/** + * The expected field stores a string. + * + * @param name name of the JSON field + * @param strptr where to store a pointer to the field + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_string_copy (const char *name, + char **strptr); + + +/** + * JSON object or array. Reference counter is + * incremented. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_json (const char *name, + json_t **jsonp); + + +/** + * JSON object, reference counter incremented. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_object_copy (const char *name, + json_t **jsonp); + + +/** + * JSON array, reference counter incremented. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_array_copy (const char *name, + json_t **jsonp); + + +/** + * JSON object, reference counter not incremented. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_object_const (const char *name, + const json_t **jsonp); + + +/** + * JSON array, reference counter not incremented. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_array_const (const char *name, + const json_t **jsonp); + + +/** + * boolean. + * + * @param name name of the JSON field + * @param[out] b where to store the boolean found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_bool (const char *name, + bool *b); + + +/** + * double. + * + * @param name name of the JSON field + * @param[out] f where to store the double found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_double (const char *name, + double *f); + + +/** + * 8-bit integer. + * + * @param name name of the JSON field + * @param[out] u8 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_uint8 (const char *name, + uint8_t *u8); + + +/** + * 16-bit integer. + * + * @param name name of the JSON field + * @param[out] u16 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_uint16 (const char *name, + uint16_t *u16); + + +/** + * 32-bit integer. + * + * @param name name of the JSON field + * @param[out] u32 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_uint32 (const char *name, + uint32_t *u32); + + +/** + * Unsigned integer. + * + * @param name name of the JSON field + * @param[out] ui where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_uint (const char *name, + unsigned int *ui); + +/** + * Unsigned long long. + * + * @param name name of the JSON field + * @param[out] ull where to store the unsigned long long found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_ull (const char *name, + unsigned long long *ull); + + +/** + * 64-bit integer. + * + * @param name name of the JSON field + * @param[out] u64 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_uint64 (const char *name, + uint64_t *u64); + + +/** + * 16-bit signed integer. + * + * @param name name of the JSON field + * @param[out] i16 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_int16 (const char *name, + int16_t *i16); + +/** + * 64-bit signed integer. + * + * @param name name of the JSON field + * @param[out] i64 where to store the integer found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_int64 (const char *name, + int64_t *i64); + + +/** + * Boolean (true mapped to #GNUNET_YES, false mapped to #GNUNET_NO). + * + * @param name name of the JSON field + * @param[out] boolean where to store the boolean found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_boolean (const char *name, + int *boolean); + + +/* ************ GNUnet-specific parser specifications ******************* */ + +/** + * Timestamp. + * + * @param name name of the JSON field + * @param[out] t at where to store the absolute time found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_timestamp (const char *name, + struct GNUNET_TIME_Timestamp *t); + + +/** + * Timestamp in network byte order. + * + * @param name name of the JSON field + * @param[out] tn where to store the absolute time found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_timestamp_nbo (const char *name, + struct GNUNET_TIME_TimestampNBO *tn); + + +/** + * Relative time. + * + * @param name name of the JSON field + * @param[out] rt where to store the relative time found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_relative_time (const char *name, + struct GNUNET_TIME_Relative *rt); + + +/** + * Specification for parsing an RSA public key. + * + * @param name name of the JSON field + * @param pk where to store the RSA key found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_rsa_public_key (const char *name, + struct GNUNET_CRYPTO_RsaPublicKey **pk); + + +/** + * Specification for parsing an RSA signature. + * + * @param name name of the JSON field + * @param sig where to store the RSA signature found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_rsa_signature (const char *name, + struct GNUNET_CRYPTO_RsaSignature **sig); + + +/** + * Specification for parsing a blinded message. + * + * @param name name of the JSON field + * @param sig where to store the blinded message found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_blinded_message (const char *name, + struct GNUNET_CRYPTO_BlindedMessage **msg); + + +/** + * Specification for parsing a blinded signature. + * + * @param name name of the JSON field + * @param sig where to store the blinded signature found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_blinded_signature ( + const char *field, + struct GNUNET_CRYPTO_BlindedSignature **b_sig); + + +/** + * Specification for parsing an unblinded signature. + * + * @param name name of the JSON field + * @param sig where to store the unblinded signature found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_unblinded_signature ( + const char *field, + struct GNUNET_CRYPTO_UnblindedSignature **ub_sig); + + +/* ****************** Generic generator interface ******************* */ + + +/** + * Convert binary data to a JSON string with the base32crockford + * encoding. + * + * @param data binary data + * @param size size of @a data in bytes + * @return json string that encodes @a data + */ +json_t * +GNUNET_JSON_from_data (const void *data, + size_t size); + + +/** + * Convert binary data to a JSON string with base64 + * encoding. + * + * @param data binary data + * @param size size of @a data in bytes + * @return json string that encodes @a data + */ +json_t * +GNUNET_JSON_from_data64 (const void *data, + size_t size); + + +/** + * Convert binary data to a JSON string with the base32crockford + * encoding. + * + * @param ptr binary data, sizeof (*ptr) must yield correct size + * @return json string that encodes @a data + */ +#define GNUNET_JSON_from_data_auto(ptr) \ + GNUNET_JSON_from_data (ptr, sizeof(*(ptr))) + + +/** + * Convert binary data to a JSON string with base64 + * encoding. + * + * @param ptr binary data, sizeof (*ptr) must yield correct size + * @return json string that encodes @a data + */ +#define GNUNET_JSON_from_data64_auto(ptr) \ + GNUNET_JSON_from_data64 (ptr, sizeof(*(ptr))) + + +/** + * Convert timestamp to a json string. + * + * @param stamp the time stamp + * @return a json string with the timestamp in @a stamp + */ +json_t * +GNUNET_JSON_from_timestamp (struct GNUNET_TIME_Timestamp stamp); + + +/** + * Convert timestamp to a json string. + * + * @param stamp the time stamp + * @return a json string with the timestamp in @a stamp + */ +json_t * +GNUNET_JSON_from_timestamp_nbo (struct GNUNET_TIME_TimestampNBO stamp); + + +/** + * Convert relative timestamp to a json string. + * + * @param stamp the time stamp + * @return a json string with the timestamp in @a stamp + */ +json_t * +GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp); + + +/** + * Convert RSA public key to JSON. + * + * @param pk public key to convert + * @return corresponding JSON encoding + */ +json_t * +GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk); + + +/** + * Convert RSA signature to JSON. + * + * @param sig signature to convert + * @return corresponding JSON encoding + */ +json_t * +GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig); + +/* ****************** GETOPT JSON helper ******************* */ + + +/** + * Allow user to specify a JSON input value. + * + * @param shortName short name of the option + * @param name long name of the option + * @param argumentHelp help text for the option argument + * @param description long help text for the option + * @param[out] val set to the JSON specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_JSON_getopt (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + json_t **json); + + +/* ****************** JSON PACK helper ******************* */ + + +/** + * Element in the array to give to the packer. + */ +struct GNUNET_JSON_PackSpec; + + +/** + * Function called to pack an element into the JSON + * object as part of #GNUNET_JSON_pack_(). + * + * @param se pack specification to execute + * @return json object to pack, NULL to pack nothing + */ +typedef json_t * +(*GNUNET_JSON_PackCallback)(const struct GNUNET_JSON_PackSpec *se); + + +/** + * Element in the array to give to the packer. + */ +struct GNUNET_JSON_PackSpec +{ + /** + * Name of the field to pack. If (and only if) @e object contains an actual + * JSON object, NULL will pack the keys in the top level of the resulting + * JSON object rather than under a field. + */ + const char *field_name; + + /** + * Object to pack. + */ + json_t *object; + + /** + * True if a NULL (or 0) argument is allowed. In this + * case, if the argument is NULL the @e packer should + * return NULL and the field should be skipped (omitted from + * the generated object) and not be serialized at all. + */ + bool allow_null; + + /** + * True if last element in the spec array. + */ + bool final; +}; + + +/** + * Pack a JSON object from a @a spec. Aborts if + * packing fails. + * + * @param spec specification object + * @return JSON object + */ +json_t * +GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]); + + +/** + * Pack a JSON object from a @a spec. Aborts if + * packing fails. + * + * @param ... list of specification objects + * @return JSON object + */ +#define GNUNET_JSON_PACK(...) \ + GNUNET_JSON_pack_ ((struct GNUNET_JSON_PackSpec[]) {__VA_ARGS__, \ + GNUNET_JSON_pack_end_ ()}) + + +/** + * Do not use directly. Use #GNUNET_JSON_PACK. + * + * @return array terminator + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_end_ (void); + + +/** + * Modify packer instruction to allow NULL as a value. + * + * @param in json pack specification to modify + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_allow_null (struct GNUNET_JSON_PackSpec in); + + +/** + * Generate packer instruction for a JSON field of type + * bool. + * + * @param name name of the field to add to the object + * @param b boolean value + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_bool (const char *name, + bool b); + + +/** + * Generate packer instruction for a JSON field of type + * double. + * + * @param name name of the field to add to the object + * @param f double value + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_double (const char *name, + double f); + + +/** + * Generate packer instruction for a JSON field of type + * string. + * + * @param name name of the field to add to the object + * @param s string value + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_string (const char *name, + const char *s); + + +/** + * Generate packer instruction for a JSON field of type + * unsigned integer. Note that the maximum allowed + * value is still limited by JSON and not UINT64_MAX. + * + * @param name name of the field to add to the object + * @param num numeric value + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_uint64 (const char *name, + uint64_t num); + + +/** + * Generate packer instruction for a JSON field of type + * signed integer. + * + * @param name name of the field to add to the object + * @param num numeric value + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_int64 (const char *name, + int64_t num); + + +/** + * Generate packer instruction for a JSON field of type + * JSON object where the reference is taken over by + * the packer. + * + * @param name name of the field to add to the object, if NULL, the keys of + * @a o will be placed in the top level of the resulting object + * @param o object to steal + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_object_steal (const char *name, + json_t *o); + + +/** + * Generate packer instruction for a JSON field of type JSON object where the + * reference counter is incremented by the packer. Note that a deep copy is + * not performed. + * + * @param name name of the field to add to the object, if NULL, the keys of + * @a o will be placed in the top level of the resulting object + * @param o object to increment reference counter of + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_object_incref (const char *name, + json_t *o); + + +/** + * Generate packer instruction for a JSON field of type + * JSON array where the reference is taken over by + * the packer. + * + * @param name name of the field to add to the object + * @param a array to steal + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_array_steal (const char *name, + json_t *a); + + +/** + * Generate packer instruction for a JSON field of type JSON array where the + * reference counter is incremented by the packer. Note that a deep copy is + * not performed. + * + * @param name name of the field to add to the object + * @param a array to increment reference counter of + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_array_incref (const char *name, + json_t *a); + + +/** + * Generate packer instruction for a JSON field of type + * variable size binary blob. + * + * @param name name of the field to add to the object + * @param blob binary data to pack + * @param blob_size number of bytes in @a blob + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_data_varsize (const char *name, + const void *blob, + size_t blob_size); + + +/** + * Generate packer instruction for a JSON field where the + * size is automatically determined from the argument. + * + * @param name name of the field to add to the object + * @param blob data to pack, must not be an array + * @return json pack specification + */ +#define GNUNET_JSON_pack_data_auto(name,blob) \ + GNUNET_JSON_pack_data_varsize (name, (blob), sizeof (*(blob))) + + +/** + * Generate packer instruction for a JSON field of type + * variable size binary blob. + * Use base64-encoding, instead of the more common + * Crockford base32-encoding. + * + * @param name name of the field to add to the object + * @param blob binary data to pack + * @param blob_size number of bytes in @a blob + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_data64_varsize (const char *name, + const void *blob, + size_t blob_size); + + +/** + * Generate packer instruction for a JSON field where the + * size is automatically determined from the argument. + * Use base64-encoding, instead of the more common + * Crockford base32-encoding. + * + * @param name name of the field to add to the object + * @param blob data to pack, must not be an array + * @return json pack specification + */ +#define GNUNET_JSON_pack_data64_auto(name,blob) \ + GNUNET_JSON_pack_data64_varsize (name, (blob), sizeof (*(blob))) + + +/** + * Generate packer instruction of a time rounder interval. + * + * @param name name of the field to add to the object + * @param ri rounder interval to add + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_time_rounder_interval (const char *name, + enum GNUNET_TIME_RounderInterval ri); + + +/** + * Provide specification to parse a time rounder interval. + * The value must be provided as a descriptive string. + * + * @param name name of the time rounder interval type in the JSON + * @param[out] ri where to store the time rounder interval + * @return spec for parsing trigger event type + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_time_rounder_interval ( + const char *name, + enum GNUNET_TIME_RounderInterval *ri); + + +/** + * Generate packer instruction for a JSON field of type + * timestamp. + * + * @param name name of the field to add to the object + * @param at timestamp pack, a value of 0 is only + * allowed with #GNUNET_JSON_pack_allow_null()! + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_timestamp (const char *name, + struct GNUNET_TIME_Timestamp at); + + +/** + * Generate packer instruction for a JSON field of type + * timestamp in network byte order. + * + * @param name name of the field to add to the object + * @param at timestamp to pack, a value of 0 is only + * allowed with #GNUNET_JSON_pack_allow_null()! + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_timestamp_nbo (const char *name, + struct GNUNET_TIME_TimestampNBO at); + + +/** + * Generate packer instruction for a JSON field of type + * relative time. + * + * @param name name of the field to add to the object + * @param rt relative time to pack + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_time_rel (const char *name, + struct GNUNET_TIME_Relative rt); + + +/** + * Generate packer instruction for a JSON field of type + * relative time in network byte order. + * + * @param name name of the field to add to the object + * @param rt relative time to pack + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_time_rel_nbo (const char *name, + struct GNUNET_TIME_RelativeNBO rt); + + +/** + * Generate packer instruction for a JSON field of type + * RSA public key. + * + * @param name name of the field to add to the object + * @param pk RSA public key + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_rsa_public_key (const char *name, + const struct GNUNET_CRYPTO_RsaPublicKey *pk); + + +/** + * Generate packer instruction for a JSON field of type + * RSA signature. + * + * @param name name of the field to add to the object + * @param sig RSA signature + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_rsa_signature (const char *name, + const struct GNUNET_CRYPTO_RsaSignature *sig); + + +/** + * Generate packer instruction for a JSON field of type + * unblinded signature. + * + * @param name name of the field to add to the object + * @param sig unblinded signature + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_unblinded_signature ( + const char *name, + const struct GNUNET_CRYPTO_UnblindedSignature *sig); + + +/** + * Generate packer instruction for a JSON field of type + * blinded message. + * + * @param name name of the field to add to the object + * @param msg blinded message + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_blinded_message ( + const char *name, + const struct GNUNET_CRYPTO_BlindedMessage *msg); + + +/** + * Generate packer instruction for a JSON field of type + * blinded signature. + * + * @param name name of the field to add to the object + * @param sig blinded signature + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +GNUNET_JSON_pack_blinded_sig (const char *name, + const struct GNUNET_CRYPTO_BlindedSignature *sig); + +#endif + +/* end of gnunet_json_lib.h */ diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_os_lib.h b/android_studio/distribution/gnunet/lib/arm64-v8a/include/gnunet_os_lib.h @@ -0,0 +1,715 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2011, 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * @author Krista Bennett + * @author Gerd Knorr <kraxel@bytesex.org> + * @author Ioana Patrascu + * @author Tzvetan Horozov + * @author Milan + * + * @file + * Low level process routines + * + * @defgroup os OS library + * Low level process routines. + * + * This code manages child processes. We can communicate with child + * processes using signals. Because signals are not supported on W32 + * and Java (at least not nicely), we can alternatively use a pipe + * to send signals to the child processes (if the child process is + * a full-blown GNUnet process that supports reading signals from + * a pipe, of course). Naturally, this also only works for 'normal' + * termination via signals, and not as a replacement for SIGKILL. + * Thus using pipes to communicate signals should only be enabled if + * the child is a Java process OR if we are on Windoze. + * + * @{ + */ + +#ifndef GNUNET_OS_LIB_H +#define GNUNET_OS_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Flags that determine which of the standard streams + * should be inherited by the child process. + */ +enum GNUNET_OS_InheritStdioFlags +{ + /** + * No standard streams should be inherited. + */ + GNUNET_OS_INHERIT_STD_NONE = 0, + + /** + * When this flag is set, the child process will + * inherit stdin of the parent. + */ + GNUNET_OS_INHERIT_STD_IN = 1, + + /** + * When this flag is set, the child process will + * inherit stdout of the parent. + */ + GNUNET_OS_INHERIT_STD_OUT = 2, + + /** + * When this flag is set, the child process will + * inherit stderr of the parent. + */ + GNUNET_OS_INHERIT_STD_ERR = 4, + + /** + * When these flags are set, the child process will + * inherit stdout and stderr of the parent. + */ + GNUNET_OS_INHERIT_STD_OUT_AND_ERR = 6, + + /** + * Use this option to have all of the standard streams + * (stdin, stdout and stderror) be inherited. + */ + GNUNET_OS_INHERIT_STD_ALL = 7, + + /** + * Should a pipe be used to send signals to the child? + */ + GNUNET_OS_USE_PIPE_CONTROL = 8 +}; + + +/** + * Process information (OS-dependent) + */ +struct GNUNET_OS_Process; + + +/** + * Possible installation paths to request + */ +enum GNUNET_OS_InstallationPathKind +{ + /** + * Return the "PREFIX" directory given to configure. + */ + GNUNET_OS_IPK_PREFIX, + + /** + * Return the directory where the program binaries are installed. (bin/) + */ + GNUNET_OS_IPK_BINDIR, + + /** + * Return the directory where libraries are installed. (lib/gnunet/) + */ + GNUNET_OS_IPK_LIBDIR, + + /** + * Return the directory where data is installed (share/gnunet/) + */ + GNUNET_OS_IPK_DATADIR, + + /** + * Return the directory where translations are installed (share/locale/) + */ + GNUNET_OS_IPK_LOCALEDIR, + + /** + * Return the installation directory of this application, not + * the one of the overall GNUnet installation (in case they + * are different). + */ + GNUNET_OS_IPK_SELF_PREFIX, + + /** + * Return the prefix of the path with application icons (share/icons/). + */ + GNUNET_OS_IPK_ICONDIR, + + /** + * Return the prefix of the path with documentation files, including the + * license (share/doc/gnunet/). + */ + GNUNET_OS_IPK_DOCDIR, + + /** + * Return the directory where helper binaries are installed (lib/gnunet/libexec/) + */ + GNUNET_OS_IPK_LIBEXECDIR +}; + + +/** + * Process status types + */ +enum GNUNET_OS_ProcessStatusType +{ + /** + * The process is not known to the OS (or at + * least not one of our children). + */ + GNUNET_OS_PROCESS_UNKNOWN, + + /** + * The process is still running. + */ + GNUNET_OS_PROCESS_RUNNING, + + /** + * The process is paused (but could be resumed). + */ + GNUNET_OS_PROCESS_STOPPED, + + /** + * The process exited with a return code. + */ + GNUNET_OS_PROCESS_EXITED, + + /** + * The process was killed by a signal. + */ + GNUNET_OS_PROCESS_SIGNALED +}; + + +/** + * Project-specific data used to help the OS subsystem + * find installation paths. + */ +struct GNUNET_OS_ProjectData +{ + /** + * Name of a library that is installed in the "lib/" directory of + * the project, such as "libgnunetutil". Used to locate the + * installation by scanning dependencies of the current process. + */ + const char *libname; + + /** + * Name of the project that is used in the "libexec" prefix, For + * example, "gnunet". Certain helper binaries are then expected to + * be installed in "$PREFIX/libexec/gnunet/" and resources in + * "$PREFIX/share/gnunet/". + */ + const char *project_dirname; + + /** + * Name of a project-specific binary that should be in "$PREFIX/bin/". + * Used to determine installation path from $PATH variable. + * For example "gnunet-arm". On W32, ".exe" should be omitted. + */ + const char *binary_name; + + /** + * Name of an environment variable that can be used to override + * installation path detection, for example "GNUNET_PREFIX". + */ + const char *env_varname; + + /** + * Alternative name of an environment variable that can be used to + * override installation path detection, if "env_varname" is not + * set. Again, for example, "GNUNET_PREFIX". + */ + const char *env_varname_alt; + + /** + * Name of an environment variable that can be used to override + * the location from which default configuration files are loaded + * from, for example "GNUNET_BASE_CONFIG". + */ + const char *base_config_varname; + + /** + * E-mail address for reporting bugs. + */ + const char *bug_email; + + /** + * Project homepage. + */ + const char *homepage; + + /** + * Configuration file name (in $XDG_CONFIG_HOME) to use. + */ + const char *config_file; + + /** + * Configuration file name to use (if $XDG_CONFIG_HOME is not set). + */ + const char *user_config_file; + + /** + * String identifying the current project version. + */ + const char *version; + + /** + * Non-zero means this project is part of GNU. + */ + int is_gnu; + + /** + * Gettext domain for localisation, e.g. the PACKAGE macro. + * Setting this field to NULL disables gettext. + */ + const char *gettext_domain; + + /** + * Gettext directory, e.g. the LOCALEDIR macro. + * If this field is NULL, the path is automatically inferred. + */ + const char *gettext_path; + + /** + * URL pointing to the source code of the application. Required for AGPL. + * Setting this to NULL disables the built-in mechanism, but you must + * provide it in some other way. If non-NULL, message type 1 and 2 are + * reserved. + */ + const char *agpl_url; +}; + + +/** + * Return default project data used by 'libgnunetutil' for GNUnet. + */ +const struct GNUNET_OS_ProjectData * +GNUNET_OS_project_data_gnunet (void); + + +/** + * Setup OS subsystem for the given project data and package. + * Initializes GNU Gettext. + * + * @param package_name name of the package for GNU gettext + * @param pd project data to use to determine paths + */ +void +GNUNET_OS_init (const char *package_name, + const struct GNUNET_OS_ProjectData *pd); + + +/** + * Get the path to a specific GNUnet installation directory or, with + * #GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation + * directory. + * + * @param pd project data to use to determine paths + * @param dirkind what kind of directory is desired? + * @return a pointer to the dir path (to be freed by the caller) + */ +char * +GNUNET_OS_installation_get_path (const struct GNUNET_OS_ProjectData *pd, + enum GNUNET_OS_InstallationPathKind dirkind); + + +/** + * Given the name of a gnunet-helper, gnunet-service or gnunet-daemon + * binary, try to prefix it with the libexec/-directory to get the + * full path. + * + * @param pd project data to use to determine paths + * @param progname name of the binary + * @return full path to the binary, if possible, otherwise copy of 'progname' + */ +char * +GNUNET_OS_get_libexec_binary_path (const struct GNUNET_OS_ProjectData *pd, + const char *progname); + + +/** + * Given the name of a helper, service or daemon binary construct the full + * path to the binary using the SUID_BINARY_PATH in the PATHS section of the + * configuration. If that option is not present, fall back to + * GNUNET_OS_get_libexec_binary_path. If @a progname is an absolute path, a + * copy of this path is returned. + * + * @param pd project data to use to determine paths + * @param cfg configuration to inspect + * @param progname name of the binary + * @return full path to the binary, if possible, a copy of @a progname + * otherwise + */ +char * +GNUNET_OS_get_suid_binary_path (const struct GNUNET_OS_ProjectData *pd, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *progname); + + +/** + * Callback function invoked for each interface found. + * + * @param cls closure + * @param name name of the interface (can be NULL for unknown) + * @param isDefault is this presumably the default interface + * @param addr address of this interface (can be NULL for unknown or unassigned) + * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) + * @param netmask the network mask (can be NULL for unknown or unassigned) + * @param addrlen length of the address + * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_OS_NetworkInterfaceProcessor)(void *cls, + const char *name, + int isDefault, + const struct sockaddr *addr, + const struct sockaddr *broadcast_addr, + const struct sockaddr *netmask, + socklen_t addrlen); + + +/** + * @brief Enumerate all network interfaces + * + * @param proc the callback function + * @param proc_cls closure for @a proc + */ +void +GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, + void *proc_cls); + +#ifndef HAVE_SYSCONF +#define HAVE_SYSCONF 0 +#endif + +/** + * @brief Get maximum string length returned by gethostname() + */ +#if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX) +#define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf ( \ + _SC_HOST_NAME_MAX); __sc_tmp <= \ + 0 ? 255 : __sc_tmp; }) +#elif defined(HOST_NAME_MAX) +#define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX +#else +#define GNUNET_OS_get_hostname_max_length() 255 +#endif + + +/** + * Get process structure for current process + * + * The pointer it returns points to static memory location and must not be + * deallocated/closed + * + * @return pointer to the process sturcutre for this process + */ +struct GNUNET_OS_Process * +GNUNET_OS_process_current (void); + + +/** + * Sends a signal to the process + * + * @param proc pointer to process structure + * @param sig signal + * @return 0 on success, -1 on error + */ +int +GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, + int sig); + + +/** + * Cleans up process structure contents (OS-dependent) and deallocates it + * + * @param proc pointer to process structure + */ +void +GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc); + + +/** + * Get the pid of the process in question + * + * @param proc the process to get the pid of + * + * @return the current process id + */ +pid_t +GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param argv NULL-terminated array of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_vap ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + char *const argv[]); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param ... NULL-terminated list of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + ...); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param va NULL-terminated list of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_va ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + va_list va); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param lsocks array of listen sockets to dup systemd-style (or NULL); + * must be NULL on platforms where dup is not supported + * @param filename name of the binary + * @param argv NULL-terminated list of arguments to the process, + * including the process name as the first argument + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_v ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + const int *lsocks, + const char *filename, + char *const argv[]); + + +/** + * Start a process. This function is similar to the GNUNET_OS_start_process_* + * except that the filename and arguments can have whole strings which contain + * the arguments. These arguments are to be separated by spaces and are parsed + * in the order they appear. Arguments containing spaces can be used by + * quoting them with @em ". + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param lsocks array of listen sockets to dup systemd-style (or NULL); + * must be NULL on platforms where dup is not supported + * @param filename name of the binary. It is valid to have the arguments + * in this string when they are separated by spaces. + * @param ... more arguments. Should be of type `char *`. It is valid + * to have the arguments in these strings when they are separated by + * spaces. The last argument MUST be NULL. + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_s ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + const int *lsocks, + const char *filename, + ...); + + +/** + * Handle to a command action. + */ +struct GNUNET_OS_CommandHandle; + + +/** + * Type of a function to process a line of output. + * + * @param cls closure + * @param line line of output from a command, NULL for the end + */ +typedef void +(*GNUNET_OS_LineProcessor) (void *cls, const char *line); + + +/** + * Stop/kill a command. + * + * @param cmd handle to the process + */ +void +GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd); + + +/** + * Run the given command line and call the given function + * for each line of the output. + * + * @param proc function to call for each line of the output + * @param proc_cls closure for proc + * @param timeout when to time out + * @param binary command to run + * @param ... arguments to command + * @return NULL on error + */ +struct GNUNET_OS_CommandHandle * +GNUNET_OS_command_run ( + GNUNET_OS_LineProcessor proc, + void *proc_cls, + struct GNUNET_TIME_Relative timeout, + const char *binary, + ...); + + +/** + * Retrieve the status of a process. + * Nonblocking version. + * + * @param proc pointer to process structure + * @param type status type + * @param code return code/signal number + * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, + enum GNUNET_OS_ProcessStatusType *type, + unsigned long *code); + + +/** + * Wait for a process to terminate. The return code is discarded. + * You must not use #GNUNET_OS_process_status() on the same process + * after calling this function! This function is blocking and should + * thus only be used if the child process is known to have terminated + * or to terminate very soon. + * + * @param proc pointer to process structure of the process to wait for + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc); + + +/** + * Retrieve the status of a process, waiting on it if dead. + * Blocking version. + * + * @param proc pointer to process structure + * @param type status type + * @param code return code/signal number + * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc, + enum GNUNET_OS_ProcessStatusType *type, + unsigned long *code); + + +/** + * Connects this process to its parent via pipe; + * essentially, the parent control handler will read signal numbers + * from the #GNUNET_OS_CONTROL_PIPE (as given in an environment + * variable) and raise those signals. + * + * @param cls closure (unused) + */ +void +GNUNET_OS_install_parent_control_handler (void *cls); + + +/** + * Check whether an executable exists and possibly + * if the suid bit is set on the file. + * Attempts to find the file using the current + * PATH environment variable as a search path. + * + * @param binary the name of the file to check. + * W32: must not have an .exe suffix. + * @param check_suid input true if the binary should be checked for SUID (*nix) + * W32: checks if the program has sufficient privileges by executing this + * binary with the -d flag. -d omits a programs main loop and only + * executes all privileged operations in an binary. + * @param params parameters used for w32 privilege checking (can be NULL for != w32, or when not checking for suid/permissions ) + * @return #GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32), + * #GNUNET_NO if not SUID (but binary exists), + * #GNUNET_SYSERR on error (no such binary or not executable) + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_check_helper_binary (const char *binary, + bool check_suid, + const char *params); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_OS_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_os_lib.h */ diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunet.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunet.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetblock.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetblock.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetblockgroup.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetblockgroup.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetgnsrecord.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetgnsrecord.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunethello.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunethello.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetjson.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetjson.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetregexblock.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetregexblock.so Binary files differ. diff --git a/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetutil.so b/android_studio/distribution/gnunet/lib/arm64-v8a/libgnunetutil.so Binary files differ. diff --git a/android_studio/distribution/gnunetblock/lib/arm64-v8a/include/gnunet_block_lib.h b/android_studio/distribution/gnunetblock/lib/arm64-v8a/include/gnunet_block_lib.h @@ -0,0 +1,304 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010, 2022 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup dht_libs DHT and support libraries + * @{ + * + * @author Christian Grothoff + * + * @file + * Library for data block manipulation + * + * @defgroup block Block library + * Library for data block manipulation + * @{ + */ +#ifndef GNUNET_BLOCK_LIB_H +#define GNUNET_BLOCK_LIB_H + + +#include "gnunet_util_lib.h" +#include "gnunet_dht_block_types.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Possible ways for how a block may relate to a query. + */ +enum GNUNET_BLOCK_ReplyEvaluationResult +{ + + /** + * Specified block type not supported by any plugin. + */ + GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED = -1, + + /** + * Valid result, but suppressed because it is a duplicate. + */ + GNUNET_BLOCK_REPLY_OK_DUPLICATE = 0, + + /** + * Block does not match xquery (valid result, not relevant for the request) + */ + GNUNET_BLOCK_REPLY_IRRELEVANT = 1, + + /** + * Valid result, and there may be more. + */ + GNUNET_BLOCK_REPLY_OK_MORE = 2, + + /** + * Last possible valid result. + */ + GNUNET_BLOCK_REPLY_OK_LAST = 3 + +}; + + +/** + * Handle to an initialized block library. + */ +struct GNUNET_BLOCK_Context; + + +/** + * Mingle hash with the mingle_number to produce different bits. + * + * @param in original hash code + * @param mingle_number number for hash permutation + * @param hc where to store the result. + */ +void +GNUNET_BLOCK_mingle_hash (const struct GNUNET_HashCode *in, + uint32_t mingle_number, + struct GNUNET_HashCode *hc); + + +/** + * Create a block context. Loads the block plugins. + * + * @param cfg configuration to use + * @return NULL on error + */ +struct GNUNET_BLOCK_Context * +GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Destroy the block context. + * + * @param ctx context to destroy + */ +void +GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx); + + +/** + * Handle for a group of elements that will be evaluated together. + * They must all be of the same type. A block group allows the + * plugin to keep some state across individual evaluations. + */ +struct GNUNET_BLOCK_Group; + + +/** + * Create a new block group. + * + * @param ctx block context in which the block group is created + * @param type type of the block for which we are creating the group + * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh + * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh + * @param ... type-specific additional data, can be empty + * @return block group handle, NULL if block groups are not supported + * by this @a type of block (this is not an error) + */ +struct GNUNET_BLOCK_Group * +GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const void *raw_data, + size_t raw_data_size, + ...); + + +/** + * Serialize state of a block group. + * + * @param bg group to serialize + * @param[out] raw_data set to the serialized state + * @param[out] raw_data_size set to the number of bytes in @a raw_data + * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not + * supported, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, + void **raw_data, + size_t *raw_data_size); + + +/** + * Destroy resources used by a block group. + * + * @param bg group to destroy, NULL is allowed + */ +void +GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg); + + +/** + * Function called to validate if a reply is good for a + * particular query. + * + * @param ctx block contxt + * @param type block type + * @param[in,out] group block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +enum GNUNET_BLOCK_ReplyEvaluationResult +GNUNET_BLOCK_check_reply (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size); + + +/** + * Function called to validate a request. + * + * @param ctx block contxt + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, + * #GNUNET_SYSERR if @a type is not supported + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size); + + +/** + * Function called to validate a block. + * + * @param ctx block contxt + * @param type block type + * @param block payload to put + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, + * #GNUNET_SYSERR if @a type is not supported + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size); + + +/** + * Function called to obtain the @a key for a @a block. + * If the @a block is malformed, the function should + * zero-out @a key and return #GNUNET_OK. + * + * @param ctx block context + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in @a block + * @param key set to the key (query) for the given block + * @return #GNUNET_YES on success, + * #GNUNET_NO if extracting a key from a block of this @a type does not work + * #GNUNET_SYSERR if @a type not supported + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + struct GNUNET_HashCode *key); + + +/** + * Update block group to filter out the given results. Note that the + * use of a hash for seen results implies that the caller magically + * knows how the specific block engine hashes for filtering + * duplicates, so this API may not always apply. + * + * @param bf_mutator mutation value to use + * @param seen_results results already seen + * @param seen_results_count number of entries in @a seen_results + * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, + const struct GNUNET_HashCode *seen_results, + unsigned int seen_results_count); + + +/** + * Try merging two block groups. Afterwards, @a bg1 should remain + * valid and contain the rules from both @a bg1 and @a bg2, and + * @a bg2 should be destroyed (as part of this call). The latter + * should happen even if merging is not supported. + * + * @param[in,out] bg1 first group to merge, is updated + * @param bg2 second group to merge, is destroyed + * @return #GNUNET_OK on success, + * #GNUNET_NO if merge failed due to different nonce + * #GNUNET_SYSERR if merging is not supported + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1, + struct GNUNET_BLOCK_Group *bg2); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_BLOCK_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_block_lib.h */ diff --git a/android_studio/distribution/gnunetblock/lib/arm64-v8a/include/gnunet_block_plugin.h b/android_studio/distribution/gnunetblock/lib/arm64-v8a/include/gnunet_block_plugin.h @@ -0,0 +1,297 @@ +/* + This file is part of GNUnet + Copyright (C) 2010, 2013, 2017, 2021, 2022 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup dht_libs DHT and support libraries + * @{ + * + * @author Christian Grothoff + * + * @file + * API for block plugins. + * + * @defgroup block-plugin Block plugin API + * To be implemented by applications storing data in the DHT. + * + * Each block plugin must conform to the API specified by this header. + * + * @{ + */ + +#ifndef PLUGIN_BLOCK_H +#define PLUGIN_BLOCK_H + + +#include "gnunet_util_lib.h" +#include "gnunet_block_lib.h" + + +/** + * Mark elements as "seen" using a hash of the element. Not supported + * by all block plugins. + * + * @param bg group to update + * @param seen_results results already seen + * @param seen_results_count number of entries in @a seen_results + */ +typedef void +(*GNUNET_BLOCK_GroupMarkSeenFunction)( + struct GNUNET_BLOCK_Group *bg, + const struct GNUNET_HashCode *seen_results, + unsigned int seen_results_count); + + +/** + * Merge two groups, if possible. Not supported by all block plugins, + * can also fail if the nonces were different. + * + * @param bg1 group to update + * @param bg2 group to merge into @a bg1 + * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus + * we failed. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_BLOCK_GroupMergeFunction)(struct GNUNET_BLOCK_Group *bg1, + const struct GNUNET_BLOCK_Group *bg2); + + +/** + * Serialize state of a block group. + * + * @param bg group to serialize + * @param[out] raw_data set to the serialized state + * @param[out] raw_data_size set to the number of bytes in @a raw_data + * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not + * supported, #GNUNET_SYSERR on error + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_BLOCK_GroupSerializeFunction)(struct GNUNET_BLOCK_Group *bg, + void **raw_data, + size_t *raw_data_size); + + +/** + * Destroy resources used by a block group. + * + * @param bg group to destroy, NULL is allowed + */ +typedef void +(*GNUNET_BLOCK_GroupDestroyFunction)(struct GNUNET_BLOCK_Group *bg); + + +/** + * Block group data. The plugin must initialize the callbacks + * and can use the @e internal_cls as it likes. + */ +struct GNUNET_BLOCK_Group +{ + /** + * Context owning the block group. Set by the main block library. + */ + struct GNUENT_BLOCK_Context *ctx; + + /** + * Type for the block group. Set by the main block library. + */ + enum GNUNET_BLOCK_Type type; + + /** + * Serialize the block group data, can be NULL if + * not supported. + */ + GNUNET_BLOCK_GroupSerializeFunction serialize_cb; + + /** + * Function to call to mark elements as seen in the group. + * Can be NULL if not supported. + */ + GNUNET_BLOCK_GroupMarkSeenFunction mark_seen_cb; + + /** + * Function to call to merge two groups. + * Can be NULL if not supported. + */ + GNUNET_BLOCK_GroupMergeFunction merge_cb; + + /** + * Function to call to destroy the block group. + * Must not be NULL. + */ + GNUNET_BLOCK_GroupDestroyFunction destroy_cb; + + /** + * Internal data structure of the plugin. + */ + void *internal_cls; +}; + + +/** + * Create a new block group. + * + * @param ctx block context in which the block group is created + * @param type type of the block for which we are creating the group + * @param nonce random value used to seed the group creation + * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh + * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh + * @param va variable arguments specific to @a type + * @return block group handle, NULL if block groups are not supported + * by this @a type of block (this is not an error) + */ +typedef struct GNUNET_BLOCK_Group * +(*GNUNET_BLOCK_GroupCreateFunction)(void *cls, + enum GNUNET_BLOCK_Type type, + const void *raw_data, + size_t raw_data_size, + va_list va); + + +/** + * Function called to validate a query. + * + * @param cls closure + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_BLOCK_QueryEvaluationFunction)(void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size); + + +/** + * Function called to validate a @a block for storage. + * + * @param cls closure + * @param type block type + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the @a block is fine, #GNUNET_NO if not, #GNUNET_SYSERR if the @a type is not supported + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_BLOCK_BlockEvaluationFunction)(void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size); + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +typedef enum GNUNET_BLOCK_ReplyEvaluationResult +(*GNUNET_BLOCK_ReplyEvaluationFunction)(void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size); + + +/** + * Function called to obtain the @a key for a block. + * If the @a block is malformed, the function should + * zero-out @a key and return #GNUNET_OK. + * + * @param cls closure + * @param type block type + * @param block block to get the @a key for + * @param block_size number of bytes in @a block + * @param[out] key set to the key (query) for the given block + * @return #GNUNET_YES on success, + * #GNUNET_NO if extracting a key for this @a type does not work + * #GNUNET_SYSERR if @a type not supported + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_BLOCK_GetKeyFunction)(void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + struct GNUNET_HashCode *key); + + +/** + * Each plugin is required to return a pointer to a struct of this + * type as the return value from its entry point. + */ +struct GNUNET_BLOCK_PluginFunctions +{ + /** + * Closure for all of the callbacks. + */ + void *cls; + + /** + * 0-terminated array of block types supported by this plugin. + */ + const enum GNUNET_BLOCK_Type *types; + + /** + * Obtain the key for a given block (if possible). + */ + GNUNET_BLOCK_GetKeyFunction get_key; + + /** + * Create a block group to process a bunch of blocks in a shared + * context (i.e. to detect duplicates). + */ + GNUNET_BLOCK_GroupCreateFunction create_group; + + /** + * Check that a query is well-formed. + */ + GNUNET_BLOCK_QueryEvaluationFunction check_query; + + /** + * Check that a block is well-formed. + */ + GNUNET_BLOCK_BlockEvaluationFunction check_block; + + /** + * Check that a reply block matches a query. + */ + GNUNET_BLOCK_ReplyEvaluationFunction check_reply; + +}; + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/gnunetblockgroup/lib/arm64-v8a/include/gnunet_block_group_lib.h b/android_studio/distribution/gnunetblockgroup/lib/arm64-v8a/include/gnunet_block_group_lib.h @@ -0,0 +1,113 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @author Christian Grothoff + * + * @file + * Library for creating block groups (to be used by block plugins) + * + * @defgroup block Block group library + * Library for data group management + * @{ + */ +#ifndef GNUNET_BLOCK_GROUP_LIB_H +#define GNUNET_BLOCK_GROUP_LIB_H + + +#include "gnunet_util_lib.h" +#include "gnunet_block_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * How many bytes should a bloomfilter be if we have already seen + * entry_count responses? Sized so that do not have to + * re-size the filter too often (to keep it cheap). + * + * Since other peers will also add entries but not resize the filter, + * we should generally pick a slightly larger size than what the + * strict math would suggest. + * + * @param entry_count expected number of entries in the Bloom filter + * @param k number of bits set per entry + * @return must be a power of two and smaller or equal to 2^15. + */ +size_t +GNUNET_BLOCK_GROUP_compute_bloomfilter_size (unsigned int entry_count, + unsigned int k); + + +/** + * Create a new block group that filters duplicates using a Bloom filter. + * + * @param ctx block context in which the block group is created + * @param bf_size size of the Bloom filter + * @param bf_k K-value for the Bloom filter + * @param type block type + * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh + * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh + * @return block group handle, NULL if block groups are not supported + * by this @a type of block (this is not an error) + */ +struct GNUNET_BLOCK_Group * +GNUNET_BLOCK_GROUP_bf_create (void *cls, + size_t bf_size, + unsigned int bf_k, + enum GNUNET_BLOCK_Type type, + const void *raw_data, + size_t raw_data_size); + + +/** + * Test if @a hc is contained in the Bloom filter of @a bg. If so, + * return #GNUNET_YES. If not, add @a hc to the Bloom filter and + * return #GNUNET_NO. + * + * @param bg block group to use for testing + * @param hc hash of element to evaluate + * @return #GNUNET_YES if @a hc is (likely) a duplicate + * #GNUNET_NO if @a hc was definitively not in @a bg (but now is) + */ +enum GNUNET_GenericReturnValue +GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg, + const struct GNUNET_HashCode *hc); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_BLOCK_GROUP_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/* end of gnunet_block_group_lib.h */ diff --git a/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_json_lib.h b/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_json_lib.h @@ -0,0 +1,87 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup GNS + * @{ + * + * @author Martin Schanzenbach + * + * @file + * API that can be used to manipulate JSON GNS record data + * + * @defgroup gnsrecord GNS Record library + * Manipulate GNS record data + * + * @see [Documentation](https://gnunet.org/gns-plugins) + * + * @{ + */ +#ifndef GNUNET_GNSRECORD_JSON_LIB_H +#define GNUNET_GNSRECORD_JSON_LIB_H + + +#include "gnunet_gnsrecord_lib.h" +#include "gnunet_json_lib.h" + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * JSON Specification for GNS Records. + * + * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_GNSRECORD_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, + unsigned int *rd_count, + char **name); + + +/** + * Convert GNS record to JSON. + * + * @param rname name of record + * @param rd record data + * @return corresponding JSON encoding + */ +json_t * +GNUNET_GNSRECORD_JSON_from_gnsrecord (const char*rname, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_lib.h b/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_lib.h @@ -0,0 +1,1001 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup GNS + * @{ + * + * @author Christian Grothoff + * + * @file + * API that can be used to manipulate GNS record data + * + * @defgroup gnsrecord GNS Record library + * Manipulate GNS record data + * + * @see [Documentation](https://gnunet.org/gns-plugins) + * + * @{ + */ +#ifndef GNUNET_GNSRECORD_LIB_H +#define GNUNET_GNSRECORD_LIB_H + + +#include "gnunet_common.h" +#include "gnunet_identity_service.h" + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * String we use to indicate an empty label (top-level + * entry in the zone). DNS uses "@", so do we. + */ +#define GNUNET_GNS_EMPTY_LABEL_AT "@" + +/** + * Maximum size of a value that can be stored in a GNS block. + */ +#define GNUNET_GNSRECORD_MAX_BLOCK_SIZE (63 * 1024) + + +/** + * Record type indicating any record/'*' + */ +#define GNUNET_GNSRECORD_TYPE_ANY 0 + +/** + * Include the record types generated from GANA + */ +#include "gnu_name_system_record_types.h" + +/** + * When comparing flags for record equality for removal, + * which flags should must match (in addition to the type, + * name, expiration value and data of the record)? All flags + * that are not listed here will be ignored for this purpose. + * (for example, we don't expect that users will remember to + * pass the '--private' option when removing a record from + * the namestore, hence we don't require this particular option + * to match upon removal). See also + * #GNUNET_GNSRECORD_records_cmp. + */ +#define GNUNET_GNSRECORD_RF_RCMP_FLAGS (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) + + +/** + * Flags that can be set for a record. + * The numbers in the registry correspond to the bit index as specified in + * LSD0001 Chapter "Resource Records". + * Each enum member represents the 16-bit integer value of the flags field if + * only that particular flag was set. + * The value can be used to efficiently compare the bitmask setting for the + * record flag in C. + * WARNING: The values are in host byte order! In order to correctly check + * against the flags field a record, the respective fields must + * also be converted to HBO (or the enum value to NBO). + */ +enum GNUNET_GNSRECORD_Flags +{ + /** + * Entry for no flags / cleared flags. + */ + GNUNET_GNSRECORD_RF_NONE = 0, + + + /** + * This record is critical. If it cannot be processed (for example because the record type is unknown) resolution MUST fail + */ + GNUNET_GNSRECORD_RF_CRITICAL = 1 << (15 - 15), + + + /** + * This record should not be used unless all (other) records in the set with an absolute expiration time have expired. + */ + GNUNET_GNSRECORD_RF_SHADOW = 1 << (15 - 14), + + + /** + * This is a supplemental record. + */ + GNUNET_GNSRECORD_RF_SUPPLEMENTAL = 1 << (15 - 13), + + /** + * Maintenance records. E.g. TOMBSTONEs + */ + GNUNET_GNSRECORD_RF_MAINTENANCE = 1 << (15 - 2), + + /** + * This expiration time of the record is a relative time (not an absolute time). Used in GNUnet implementation. + */ + GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 1 << (15 - 1), + + + /** + * This is a private record of this peer and it should thus not be published. + */ + GNUNET_GNSRECORD_RF_PRIVATE = 1 << (15 - 0), + +}; + + +/** + * Filter for GNUNET_GNSRECORD_normalize_record_set(). + */ +enum GNUNET_GNSRECORD_Filter +{ + /** + * No filter flags set. + * Private and public records are returned, + * maintenance records (TOMBSTONE etc) are not. + */ + GNUNET_GNSRECORD_FILTER_NONE = 0, + + /** + * Include maintenance records (TOMBSTONE etc). + */ + GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE = 1, + + /** + * Filter private records + */ + GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE = 2, + + /** + * Filter public records. + * FIXME: Not implemented + */ + // GNUNET_NAMESTORE_FILTER_OMIT_PUBLIC = 4, +}; + + +/** + * A GNS record. + */ +struct GNUNET_GNSRECORD_Data +{ + /** + * Binary value stored in the DNS record. Note: "data" must never + * be individually 'malloc'ed, but instead always points into some + * existing data area. + */ + const void *data; + + /** + * Expiration time for the DNS record. Can be relative + * or absolute, depending on @e flags. Measured in the same + * unit as GNUnet time (microseconds). + */ + uint64_t expiration_time; + + /** + * Number of bytes in @e data. + */ + size_t data_size; + + /** + * Type of the GNS/DNS record. + */ + uint32_t record_type; + + /** + * Flags for the record. + */ + enum GNUNET_GNSRECORD_Flags flags; +}; + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Data stored in a PLACE record. + */ +struct GNUNET_GNSRECORD_PlaceData +{ + /** + * Public key of the place. + */ + struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; + + /** + * Peer identity of the origin. + */ + struct GNUNET_PeerIdentity origin; + + /** + * Number of relays that follow. + */ + uint32_t relay_count GNUNET_PACKED; + + /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ +}; + +/** + * Information we have in an encrypted block with record data (i.e. in the DHT). + */ +struct GNUNET_GNSRECORD_EcdsaBlock +{ + /** + * Derived key used for signing; hash of this is the query. + */ + struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; + + /** + * Signature of the block. + */ + struct GNUNET_CRYPTO_EcdsaSignature signature; + + /** + * Expiration time of the block. + */ + struct GNUNET_TIME_AbsoluteNBO expiration_time; + + /* followed by encrypted data */ +}; + + +/** + * Information we have in an encrypted block with record data (i.e. in the DHT). + */ +struct GNUNET_GNSRECORD_EddsaBlock +{ + /** + * Derived key used for signing; hash of this is the query. + */ + struct GNUNET_CRYPTO_EddsaPublicKey derived_key; + + /** + * Signature of the block. + */ + struct GNUNET_CRYPTO_EddsaSignature signature; + + /** + * Expiration time of the block. + */ + struct GNUNET_TIME_AbsoluteNBO expiration_time; + + + /* followed by encrypted data */ +}; + + +struct GNUNET_GNSRECORD_Block +{ + /** + * Size of the block. + */ + uint32_t size; + + /** + * The zone type (GNUNET_GNSRECORD_TYPE_PKEY) + */ + uint32_t type; + + union + { + struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block; + struct GNUNET_GNSRECORD_EddsaBlock eddsa_block; + }; +}; + + +/** + * Record type used to box up SRV and TLSA records. For example, a + * TLSA record for "_https._tcp.foo.gnu" will be stored under + * "foo.gnu" as a BOX record with service 443 (https) and protocol 6 + * (tcp) and record_type "TLSA". When a BOX record is received, GNS + * unboxes it if the name contained "_SERVICE._PROTO", otherwise GNS + * leaves it untouched. This is done to ensure that TLSA (and SRV) + * records do not require a separate network request, thus making TLSA + * records inseparable from the "main" A/AAAA/VPN/etc. records. + */ +struct GNUNET_GNSRECORD_BoxRecord +{ + /** + * Protocol of the boxed record (6 = TCP, 17 = UDP, etc.). + * Yes, in IP protocols are usually limited to 8 bits. In NBO. + */ + uint16_t protocol GNUNET_PACKED; + + /** + * Service of the boxed record (aka port number), in NBO. + */ + uint16_t service GNUNET_PACKED; + + /** + * GNS record type of the boxed record. In NBO. + */ + uint32_t record_type GNUNET_PACKED; + + /* followed by the 'original' record */ +}; + + +/** + * Record type used to box up SMIMEA records. For example, a + * SMIMEA record for "c93f1e400f26708f98cb19d936620da35eec8f72e57 + * f9eec01c1afd6._smimecert.foo.gnu" will be stored under + * "foo.gnu" as a SBOX record with the local-path of the associated + * e-mails hash turnicated to 28 octets encoded as hex and protocol _smimecert + * and record_type "SMIMEA". When a BOX record is received, GNS + * unboxes it if the name contained "hash._PROTO", otherwise GNS + * leaves it untouched. This is done to ensure that SMIMEA + * records do not require a separate network request, thus making SMIMEA + * records inseparable from the "main" A/AAAA/VPN/etc. records. + */ +struct GNUNET_GNSRECORD_SBoxRecord +{ + /** + * GNS record type of the boxed record. In NBO. + */ + uint32_t record_type GNUNET_PACKED; + + /* followed by the zero terminated hostname prefix */ + /* followed by the 'original' record */ +}; + + +/** + * Record type used internally to keep track of reverse mappings into a + * namespace. + * The record contains data related to PKEY delegations from other namespaces to + * the namespace the record belongs to. + * It is exclusively found under the label ``+''. + */ +struct GNUNET_GNSRECORD_ReverseRecord +{ + /** + * The public key of the namespace the is delegating to our namespace + */ + struct GNUNET_CRYPTO_PublicKey pkey; + + /** + * The expiration time of the delegation + */ + struct GNUNET_TIME_Absolute expiration; + + /* followed by the name the delegator uses to refer to our namespace */ +}; + + +/** + * Process a records that were decrypted from a block. + * + * @param cls closure + * @param rd_count number of entries in @a rd array + * @param rd array of records with data to store + */ +typedef void (*GNUNET_GNSRECORD_RecordCallback) ( + void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); + + +/* ***************** API related to GNSRECORD plugins ************** */ + +/** + * Convert the binary value @a data of a record of + * type @a type to a human-readable string. + * + * @param type type of the record + * @param data value in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the value + */ +char * +GNUNET_GNSRECORD_value_to_string (uint32_t type, const void *data, + size_t data_size); + + +/** + * Convert human-readable version of the value @a s of a record + * of type @a type to the respective binary representation. + * + * @param type type of the record + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in @a data + * @return #GNUNET_OK on success + */ +int +GNUNET_GNSRECORD_string_to_value (uint32_t type, const char *s, void **data, + size_t *data_size); + + +/** + * Convert a type name (e.g. "AAAA") to the corresponding number. + * + * @param dns_typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_GNSRECORD_typename_to_number (const char *dns_typename); + + +/** + * Convert a type number to the corresponding type string (e.g. 1 to "A") + * + * @param type number of a type to convert + * @return corresponding typestring, NULL on error + */ +const char * +GNUNET_GNSRECORD_number_to_typename (uint32_t type); + + +/* convenience APIs for serializing / deserializing GNS records */ + +/** + * Calculate how many bytes we will need to serialize the given + * records. + * + * @param rd_count number of records in the @a rd array + * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements + * @return the required size to serialize, -1 on error + */ +ssize_t +GNUNET_GNSRECORD_records_get_size (unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd); + + +/** + * Serialize the given records to the given destination buffer. + * + * @param rd_count number of records in the @a rd array + * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements + * @param dest_size size of the destination array @a dst + * @param dest where to write the result + * @return the size of serialized records, -1 if records do not fit + */ +ssize_t +GNUNET_GNSRECORD_records_serialize (unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd, + size_t dest_size, char *dest); + +unsigned int +GNUNET_GNSRECORD_records_deserialize_get_size (size_t len, + const char *src); + +/** + * Deserialize the given records to the given destination. + * + * @param len size of the serialized record data + * @param src the serialized record data + * @param rd_count number of records in the @a dest array + * @param dest where to put the data + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_GNSRECORD_records_deserialize (size_t len, const char *src, + unsigned int rd_count, + struct GNUNET_GNSRECORD_Data *dest); + + +/* ******* general APIs relating to blocks, records and labels ******** */ + + +/** + * Test if a given record is expired. + * + * @param rd record to test + * @return #GNUNET_YES if the record is expired, + * #GNUNET_NO if not + */ +int +GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd); + + +/** + * Normalize a UTF-8 string to a GNS name + * + * @param src source string + * @return converted result + */ +char * +GNUNET_GNSRECORD_string_normalize (const char *src); + + +/** + * Convert a zone to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param z public key of a zone + * @return string form; will be overwritten by next call to + * #GNUNET_GNSRECORD_z2s. + */ +const char * +GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_PublicKey *z); + + +/** + * Convert public key to the respective absolute domain name in the + * ".zkey" pTLD. + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param pkey a public key with a point on the elliptic curve + * @return string "X.zkey" where X is the coordinates of the public + * key in an encoding suitable for DNS labels. + */ +const char * +GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_PublicKey *pkey); + + +/** + * Convert an absolute domain name to the + * respective public key. + * + * @param zkey string "X" where X is the public + * key in an encoding suitable for DNS labels. + * @param pkey set to a public key on the elliptic curve + * @return #GNUNET_SYSERR if @a zkey has the wrong syntax + */ +int +GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, + struct GNUNET_CRYPTO_PublicKey *pkey); + + +/** + * Calculate the DHT query for a given @a label in a given @a zone. + * + * @param zone private key of the zone + * @param label label of the record + * @param query hash to use for the query + */ +void +GNUNET_GNSRECORD_query_from_private_key ( + const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, + struct GNUNET_HashCode *query); + + +/** + * Calculate the DHT query for a given @a label in a given @a zone. + * FIXME: We may want to plugin-ize this at some point. + * + * @param pub public key of the zone + * @param label label of the record + * @param query hash to use for the query + */ +void +GNUNET_GNSRECORD_query_from_public_key ( + const struct GNUNET_CRYPTO_PublicKey *pub, const char *label, + struct GNUNET_HashCode *query); + + +/** + * Get size of buffer for block creation. + * + * @param key the zone key + * @param rd record data + * @param rd_count number of records + * @return -1 on error (otherwise the length of the block) + */ +ssize_t +GNUNET_GNSRECORD_block_calculate_size (const struct + GNUNET_CRYPTO_PrivateKey *key, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count); + +/** + * Sign a block create with #GNUNET_GNSRECORD_block_create_unsigned + * + * @param key the private key + * @param label the label of the block + * @param block the unsigned block + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_sign (const struct + GNUNET_CRYPTO_PrivateKey *key, + const char *label, + struct GNUNET_GNSRECORD_Block *block); + +/** + * Sign name and records + * + * @param key the private key + * @param expire block expiration + * @param label the name for the records + * @param rd record data + * @param rd_count number of records in @a rd + * @param result the block buffer. Will be allocated. + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_PrivateKey *key, + struct GNUNET_TIME_Absolute expire, + const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count, + struct GNUNET_GNSRECORD_Block **block); + + +/** + * Create name and records but do not sign! + * Sign later with #GNUNET_GNSRECORD_block_sign(). + * Cache derived public key (also keeps the + * private key in static memory, so do not use this function if + * keeping the private key in the process'es RAM is a major issue). + * + * @param key the private key + * @param expire block expiration + * @param label the name for the records + * @param rd record data + * @param rd_count number of records in @a rd + * @param result the block buffer. Will be allocated. + * @return GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_create_unsigned (const struct + GNUNET_CRYPTO_PrivateKey *key, + struct GNUNET_TIME_Absolute expire, + const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count, + struct GNUNET_GNSRECORD_Block **result); + + +/** + * Sign name and records, cache derived public key (also keeps the + * private key in static memory, so do not use this function if + * keeping the private key in the process'es RAM is a major issue). + * + * @param key the private key + * @param expire block expiration + * @param label the name for the records + * @param rd record data + * @param rd_count number of records in @a rd + * @param result the block buffer. Will be allocated. + * @return GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_PrivateKey *key, + struct GNUNET_TIME_Absolute expire, + const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count, + struct GNUNET_GNSRECORD_Block **result); + + +/** + * Check if a signature is valid. This API is used by the GNS Block + * to validate signatures received from the network. + * + * @param block block to verify + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block); + + +/** + * Decrypt block. + * + * @param block block to decrypt + * @param zone_key public key of the zone + * @param label the name for the records + * @param proc function to call with the result + * @param proc_cls closure for @a proc + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was + * not well-formed + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_decrypt ( + const struct GNUNET_GNSRECORD_Block *block, + const struct GNUNET_CRYPTO_PublicKey *zone_key, const char *label, + GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls); + + +/** + * Compares if two records are equal + * + * @param a a record + * @param b another record + * @return #GNUNET_YES if the records are equal, or #GNUNET_NO if not. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, + const struct GNUNET_GNSRECORD_Data *b); + + +/** + * Returns the expiration time of the given block of records. The block + * expiration time is the expiration time of the record with smallest + * expiration time. + * + * @param rd_count number of records given in @a rd + * @param rd array of records + * @param min minimum expiration time + * @return absolute expiration time + */ +struct GNUNET_TIME_Absolute +GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, + const struct + GNUNET_GNSRECORD_Data *rd, + struct GNUNET_TIME_Absolute min); + + +/** + * Returns the length of this block in bytes. + * Block length strongly depends on the zone type. + * + * @param block the block. + * @return the length of this block in bytes + */ +size_t +GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block); + +/** + * Returns the expiration of a block. + * + * @param block the block. + * @return the block expiration. + */ +struct GNUNET_TIME_Absolute +GNUNET_GNSRECORD_block_get_expiration (const struct + GNUNET_GNSRECORD_Block *block); + + +/** + * Builds the query hash from a block. + * + * @param block the block. + * @param query where to write the query hash. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block, + struct GNUNET_HashCode *query); + + +/** + * Build a #GNUNET_GNSRECORD_PublicKey from + * zone delegation resource record data. + * + * @param data the record data- + * @param data_size the data size. + * @param type the record type + * @param key the identity key to store the data in (must be allocated). + * @return GNUNET_OK if successful. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_identity_from_data (const char *data, + size_t data_size, + uint32_t type, + struct GNUNET_CRYPTO_PublicKey *key); + + +/** + * Create record data and size from an identity key. + * + * @param key the identity key to use. + * @param data the record data (will be allocated) + * @param data_size the allocated data size. + * @param type the resulting record type + * @return GNUNET_OK if successful. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_data_from_identity (const struct + GNUNET_CRYPTO_PublicKey *key, + char **data, + size_t *data_size, + uint32_t *type); + + +/** + * Check if this type is one of the supported GNS zone + * types. + * + * @param type the type to check + * @return GNUNET_YES if it is one of the supported types. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_is_zonekey_type (uint32_t type); + +/** + * Check if this type is a critical record. + * + * @param type the type to check + * @return GNUNET_YES if it is critical. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_is_critical (uint32_t type); + +/** + * Normalize namestore records: Check for consistency and + * expirations. Purge expired records. Returns a "clean" record set. + * Also returns the minimum expiration time this block should be + * published under. + * Also checks rules with respect to labels (e.g. no delegations under + * the empty label) + * + * @param label the label under which this set (supposed to be) stored. + * @param rd input records + * @param rd_count size of the @a rd and @a rd_public arrays + * @param rd_public where to write the converted records + * @param rd_count_public number of records written to @a rd_public + * @param min_expiry the minimum expiration of this set + * @param filter the record set filter, see GNUNET_GNSRECORD_Filter. + * @param emsg the error message if something went wrong + * @return GNUNET_OK if set could be normalized and is consistent + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_normalize_record_set (const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count, + struct GNUNET_GNSRECORD_Data *rd_public, + unsigned int *rd_count_public, + struct GNUNET_TIME_Absolute *min_expiry, + enum GNUNET_GNSRECORD_Filter filter, + char **emsg); + +/** + * Check label for invalid characters. + * + * @param label the label to check + * @param emsg an error message (NULL if label is valid). Will be allocated. + * @return GNUNET_OK if label is valid. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_label_check (const char*label, char **emsg); + +/** + * Maximum length of a revocation + */ +#define GNUNET_MAX_POW_SIZE sizeof(struct GNUNET_GNSRECORD_PowP) \ + + sizeof(struct GNUNET_CRYPTO_PublicKey) \ + + 1024 // FIXME max sig_len + +/** + * The proof-of-work narrowing factor. + * The number of PoWs that are calculates as part of revocation. + */ +#define POW_COUNT 32 + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Struct for a proof of work as part of the revocation. + */ +struct GNUNET_GNSRECORD_PowP +{ + /** + * The timestamp of the revocation + */ + struct GNUNET_TIME_AbsoluteNBO timestamp; + + /** + * The TTL of this revocation (purely informational) + */ + struct GNUNET_TIME_RelativeNBO ttl; + + /** + * The PoWs + */ + uint64_t pow[POW_COUNT] GNUNET_PACKED; + + /** followed by the public key type, the key and a signature **/ +}; + + +/** + * The signature object we use for the PoW + */ +struct GNUNET_GNSRECORD_SignaturePurposePS +{ + /** + * The signature purpose + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * The timestamp of the revocation + */ + struct GNUNET_TIME_AbsoluteNBO timestamp; + + /** Followed by the zone public key type and key **/ +}; + +GNUNET_NETWORK_STRUCT_END + + +/** + * Handle to a running proof-of-work calculation. + */ +struct GNUNET_GNSRECORD_PowCalculationHandle; + + +/** + * Check if the given proof-of-work is valid. + * + * @param pow proof of work + * @param matching_bits how many bits must match (configuration) + * @param epoch_duration length of single epoch in configuration + * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_check_pow (const struct GNUNET_GNSRECORD_PowP *pow, + unsigned int matching_bits, + struct GNUNET_TIME_Relative epoch_duration); + + +/** + * Initializes a fresh PoW computation. + * + * @param key the key to calculate the PoW for. + * @param pow the pow object to work with in the calculation. + */ +void +GNUNET_GNSRECORD_pow_init (const struct GNUNET_CRYPTO_PrivateKey *key, + struct GNUNET_GNSRECORD_PowP *pow); + + +/** + * Starts a proof-of-work calculation given the pow object as well as + * target epochs and difficulty. + * + * @param pow the PoW to based calculations on. + * @param epochs the number of epochs for which the PoW must be valid. + * @param difficulty the base difficulty of the PoW. + * @return a handle for use in PoW rounds + */ +struct GNUNET_GNSRECORD_PowCalculationHandle* +GNUNET_GNSRECORD_pow_start (struct GNUNET_GNSRECORD_PowP *pow, + int epochs, + unsigned int difficulty); + + +/** + * Calculate a single round in the key revocation PoW. + * + * @param pc handle to the PoW, initially called with NULL. + * @return GNUNET_YES if the @a pow is acceptable, GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_pow_round (struct GNUNET_GNSRECORD_PowCalculationHandle *pc); + +size_t +GNUNET_GNSRECORD_proof_get_size (const struct GNUNET_GNSRECORD_PowP *pow); + +/** + * Stop a PoW calculation + * + * @param pc the calculation to clean up + * @return #GNUNET_YES if pow valid, #GNUNET_NO if pow was set but is not + * valid + */ +void +GNUNET_GNSRECORD_pow_stop (struct GNUNET_GNSRECORD_PowCalculationHandle *pc); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_plugin.h b/android_studio/distribution/gnunetgnsrecord/lib/arm64-v8a/include/gnunet_gnsrecord_plugin.h @@ -0,0 +1,172 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup GNS + * @{ + * + * @author Christian Grothoff + * + * @file + * Plugin API for GNS record types + * + * @defgroup gnsrecord-plugin GNS Record plugin API + * To be implemented by applications defining new record types. + * + * @see [Documentation](https://gnunet.org/gns-plugins) + * + * @{ + */ +#ifndef GNUNET_GNSRECORD_PLUGIN_H +#define GNUNET_GNSRECORD_PLUGIN_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Function called to convert the binary value @a data of a record of + * type @a type to a human-readable string. + * + * @param cls closure + * @param type type of the record + * @param data value in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the value + */ +typedef char * +(*GNUNET_GNSRECORD_ValueToStringFunction) (void *cls, + uint32_t type, + const void *data, + size_t data_size); + + +/** + * Function called to convert human-readable version of the value @a s + * of a record of type @a type to the respective binary + * representation. + * + * @param cls closure + * @param type type of the record + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in @a data + * @return #GNUNET_OK on success + */ +typedef int +(*GNUNET_GNSRECORD_StringToValueFunction) (void *cls, + uint32_t type, + const char *s, + void **data, + size_t *data_size); + + +/** + * Function called to convert a type name (e.g. "AAAA") to the + * corresponding number. + * + * @param cls closure + * @param dns_typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +typedef uint32_t +(*GNUNET_GNSRECORD_TypenameToNumberFunction) (void *cls, + const char *dns_typename); + + +/** + * Function called to convert a type number to the + * corresponding type string (e.g. 1 to "A") + * + * @param cls closure + * @param type number of a type to convert + * @return corresponding typestring, NULL on error + */ +typedef const char * +(*GNUNET_GNSRECORD_NumberToTypenameFunction) (void *cls, + uint32_t type); + +/** + * Function called to check for critical records. + * + * @param cls closure + * @param type number of a type to check + * @return GNUNET_YES if critical, otherwise GNUNET_NO + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_GNSRECORD_IsCriticalFunction) (void *cls, + uint32_t type); + + + +/** + * Each plugin is required to return a pointer to a struct of this + * type as the return value from its entry point. + */ +struct GNUNET_GNSRECORD_PluginFunctions +{ + /** + * Closure for all of the callbacks. + */ + void *cls; + + /** + * Conversion to string. + */ + GNUNET_GNSRECORD_ValueToStringFunction value_to_string; + + /** + * Conversion to binary. + */ + GNUNET_GNSRECORD_StringToValueFunction string_to_value; + + /** + * Typename to number. + */ + GNUNET_GNSRECORD_TypenameToNumberFunction typename_to_number; + + /** + * Number to typename. + */ + GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename; + + /** + * Is critical. + */ + GNUNET_GNSRECORD_IsCriticalFunction is_critical; +}; + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/android_studio/distribution/gnunethello/lib/arm64-v8a/include/gnunet_hello_uri_lib.h b/android_studio/distribution/gnunethello/lib/arm64-v8a/include/gnunet_hello_uri_lib.h @@ -0,0 +1,371 @@ +/* + This file is part of GNUnet. + Copyright (C) 2022 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @addtogroup Backbone + * @{ + * + * @author Christian Grothoff + * @file + * Helper library for handling HELLO URIs + * + * @defgroup hello_uri Hello_Uri library + * Helper library for handling HELLO URIs + * + * @{ + */ + +#ifndef GNUNET_HELLO_URI_LIB_H +#define GNUNET_HELLO_URI_LIB_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" + + +/** + * Context for building HELLOs. + */ +struct GNUNET_HELLO_Builder; + +/** + * Context for parsing HELLOs. + */ +struct GNUNET_HELLO_Parser; + + +/** + * For how long are HELLO signatures valid? + */ +#define GNUNET_HELLO_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_DAYS, 2) + + +/** + * Allocate builder. + * + * @param pid peer the builder is for + * @return new builder + */ +struct GNUNET_HELLO_Builder * +GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid); + + +/** + * Allocate builder from parser. + * + * @param parser the parser + * @return new builder + */ +struct GNUNET_HELLO_Builder * +GNUNET_HELLO_builder_from_parser (const struct GNUNET_HELLO_Parser *parser); + +/** + * Get the PeerIdentity for this builder. + */ +const struct GNUNET_PeerIdentity * +GNUNET_HELLO_parser_get_id (const struct GNUNET_HELLO_Parser *parser); + + +/** + * Release resources of a @a builder. + * + * @param[in] builder to free + */ +void +GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder); + +/** + * Release resources of a @a builder. + * + * @param[in] builder to free + */ +void +GNUNET_HELLO_parser_free (struct GNUNET_HELLO_Parser *parser); + + +/** + * Parse @a msg. + * + * @param msg message to parse + * @return builder, NULL on failure + */ +struct GNUNET_HELLO_Parser * +GNUNET_HELLO_parser_from_msg (const struct GNUNET_MessageHeader *msg); + + +/** + * Parse @a block. + * + * @param block DHT block to parse + * @param block_size number of bytes in @a block + * @return builder, NULL on failure + */ +struct GNUNET_HELLO_Parser * +GNUNET_HELLO_parser_from_block (const void *block, + size_t block_size); + + +/** + * Parse GNUnet HELLO @a url. + * + * @param url URL to parse + * @return builder, NULL on failure + */ +struct GNUNET_HELLO_Parser * +GNUNET_HELLO_parser_from_url (const char *url); + + +/** + * Get the expiration time for this HELLO. + * + * @param msg The hello msg. + * @return The expiration time. + */ +struct GNUNET_TIME_Absolute +GNUNET_HELLO_get_expiration_time_from_msg (const struct + GNUNET_MessageHeader *msg); + + +/** + * Generate envelope with GNUnet HELLO message (including + * peer ID) from a @a builder + * + * @param builder builder to serialize + * @param priv private key to use to sign the result + * @return HELLO message matching @a builder + */ +struct GNUNET_MQ_Envelope * +GNUNET_HELLO_builder_to_env (const struct GNUNET_HELLO_Builder *builder, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct GNUNET_TIME_Relative expiration_time); + + +/** + * Generate envelope with GNUnet HELLO message (including + * peer ID) from a @a parser + * + * @param builder builder to serialize + * @return HELLO message matching @a parser + */ +struct GNUNET_MQ_Envelope * +GNUNET_HELLO_parser_to_env (const struct GNUNET_HELLO_Parser *parser); + +/** + * Generate DHT HELLO message (without peer ID) from a @a builder + * + * @param builder builder to serialize + * @param priv private key to use to sign the result + * @return HELLO message matching @a builder + */ +struct GNUNET_MessageHeader * +GNUNET_HELLO_builder_to_dht_hello_msg ( + const struct GNUNET_HELLO_Builder *builder, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct GNUNET_TIME_Relative expiration_time); + +/** + * Generate GNUnet HELLO URI from a @a parser + * + * @param parser HELLO parser to serialize + * @return hello URI + */ +char * +GNUNET_HELLO_parser_to_url (const struct GNUNET_HELLO_Parser *parser); + +/** + * Generate GNUnet HELLO URI from a @a builder + * + * @param builder builder to serialize + * @param priv private key to use to sign the result + * @return hello URI + */ +char * +GNUNET_HELLO_builder_to_url (const struct GNUNET_HELLO_Builder *builder, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); + +/** + * Generate GNUnet HELLO URI from a @a builder + * + * @param builder builder to serialize + * @param priv private key to use to sign the result + * @param expiration_time the expiration time to use. + * @return hello URI + */ +char * +GNUNET_HELLO_builder_to_url2 (const struct GNUNET_HELLO_Builder *builder, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct GNUNET_TIME_Relative expiration_time); + +/** + * Generate DHT block from a @a builder + * + * @param builder the builder to serialize + * @param priv private key to use to sign the result + * @param[out] block where to write the block, NULL to only calculate @a block_size + * @param[in,out] block_size input is number of bytes available in @a block, + * output is number of bytes needed in @a block + * @return #GNUNET_OK on success, #GNUNET_NO if @a block_size was too small + * or if @a block was NULL + */ +enum GNUNET_GenericReturnValue +GNUNET_HELLO_builder_to_block (const struct GNUNET_HELLO_Builder *builder, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + void *block, + size_t *block_size, + struct GNUNET_TIME_Relative expiration_time); + + +/** + * Generate DHT block from a @a parser + * + * @param builder the builder to serialize + * @param[out] block where to write the block, NULL to only calculate @a block_size + * @param[in,out] block_size input is number of bytes available in @a block, + * output is number of bytes needed in @a block + * @return #GNUNET_OK on success, #GNUNET_NO if @a block_size was too small + * or if @a block was NULL + */ +enum GNUNET_GenericReturnValue +GNUNET_HELLO_parser_to_block(const struct GNUNET_HELLO_Parser *parser, + void *block, size_t *block_size); + +/** + * Add individual @a address to the @a builder + * + * @param[in,out] builder to update + * @param address address URI to add + * @return #GNUNET_OK on success, #GNUNET_NO if @a address was already + * in @a builder + */ +enum GNUNET_GenericReturnValue +GNUNET_HELLO_builder_add_address (struct GNUNET_HELLO_Builder *builder, + const char *address); + + +/** + * Remove individual @a address from the @a builder + * + * @param[in,out] builder to update + * @param address address URI to remove + * @return #GNUNET_OK on success, #GNUNET_NO if @a address was not + * in @a builder + */ +enum GNUNET_GenericReturnValue +GNUNET_HELLO_builder_del_address (struct GNUNET_HELLO_Builder *builder, + const char *address); + + +/** + * Callback function used to extract URIs from a builder. + * + * @param cls closure + * @param uri one of the URIs + */ +typedef void +(*GNUNET_HELLO_UriCallback) (void *cls, + const struct GNUNET_PeerIdentity *pid, + const char *uri); + + +/** + * Iterate over URIs in a parser. + * + * @param builder builder to iterate over + * @param uc callback invoked for each URI, can be NULL + * @param uc_cls closure for @a addrgen + * @return pid of the peer the @a builder is for, can be NULL + */ +const struct GNUNET_PeerIdentity * +GNUNET_HELLO_parser_iterate (const struct GNUNET_HELLO_Parser *parser, + GNUNET_HELLO_UriCallback uc, + void *uc_cls); + + +/** + * Convert a DHT @a hello message to a HELLO @a block. + * + * @param hello the HELLO message + * @param pid peer that created the @a hello + * @param[out] block set to the HELLO block + * @param[out] block_size set to number of bytes in @a block + * @param[out] block_expiration set to expiration time of @a block + * @return #GNUNET_OK on success, + * #GNUNET_NO if the @a hello is expired (@a block is set!) + * #GNUNET_SYSERR if @a hello is invalid (@a block will be set to NULL) + */ +enum GNUNET_GenericReturnValue +GNUNET_HELLO_dht_msg_to_block (const struct GNUNET_MessageHeader *hello, + const struct GNUNET_PeerIdentity *pid, + void **block, + size_t *block_size, + struct GNUNET_TIME_Absolute *block_expiration); + + +/** + * Given an address as a string, extract the prefix that identifies + * the communicator offering transmissions to that address. + * + * @param address a peer's address + * @return NULL if the address is mal-formed, otherwise the prefix + */ +char * +GNUNET_HELLO_address_to_prefix (const char *address); + +/** + * Build address record by signing raw information with private key. + * + * @param address text address to sign + * @param nt network type of @a address + * @param mono_time when was @a address valid + * @param private_key signing key to use + * @param[out] result where to write address record (allocated) + * @param[out] result_size set to size of @a result + */ +void +GNUNET_HELLO_sign_address ( + const char *address, + enum GNUNET_NetworkType nt, + struct GNUNET_TIME_Absolute mono_time, + const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key, + void **result, + size_t *result_size); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_HELLO_URI_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_hello_uri_lib.h */ diff --git a/android_studio/distribution/gnunetsq/lib/arm64-v8a/libgnunetsq.so b/android_studio/distribution/gnunetsq/lib/arm64-v8a/libgnunetsq.so Binary files differ. diff --git a/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_crypto_lib.h b/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_crypto_lib.h @@ -1030,7 +1030,7 @@ GNUNET_CRYPTO_hash_from_string2 (const char *enc, * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding */ #define GNUNET_CRYPTO_hash_from_string(enc, result) \ - GNUNET_CRYPTO_hash_from_string2 (enc, strlen (enc), result) + GNUNET_CRYPTO_hash_from_string2 (enc, strlen (enc), result) /** @@ -2753,15 +2753,15 @@ GNUNET_CRYPTO_eddsa_sign_ ( * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_eddsa_sign(priv,ps,sig) do { \ - /* check size is set correctly */ \ - GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)); \ - /* check 'ps' begins with the purpose */ \ - GNUNET_static_assert (((void*) (ps)) == \ - ((void*) &(ps)->purpose)); \ - GNUNET_assert (GNUNET_OK == \ - GNUNET_CRYPTO_eddsa_sign_ (priv, \ - &(ps)->purpose, \ - sig)); \ + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)); \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)); \ + GNUNET_assert (GNUNET_OK == \ + GNUNET_CRYPTO_eddsa_sign_ (priv, \ + &(ps)->purpose, \ + sig)); \ } while (0) @@ -2815,15 +2815,15 @@ GNUNET_CRYPTO_eddsa_sign_raw ( * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_ecdsa_sign(priv,ps,sig) do { \ - /* check size is set correctly */ \ - GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ - /* check 'ps' begins with the purpose */ \ - GNUNET_static_assert (((void*) (ps)) == \ - ((void*) &(ps)->purpose)); \ - GNUNET_assert (GNUNET_OK == \ - GNUNET_CRYPTO_ecdsa_sign_ (priv, \ - &(ps)->purpose, \ - sig)); \ + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)); \ + GNUNET_assert (GNUNET_OK == \ + GNUNET_CRYPTO_ecdsa_sign_ (priv, \ + &(ps)->purpose, \ + sig)); \ } while (0) /** @@ -2862,15 +2862,15 @@ GNUNET_CRYPTO_edx25519_sign_ ( * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_edx25519_sign(priv,ps,sig) do { \ - /* check size is set correctly */ \ - GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ - /* check 'ps' begins with the purpose */ \ - GNUNET_static_assert (((void*) (ps)) == \ - ((void*) &(ps)->purpose)); \ - GNUNET_assert (GNUNET_OK == \ - GNUNET_CRYPTO_edx25519_sign_ (priv, \ - &(ps)->purpose, \ - sig)); \ + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)); \ + GNUNET_assert (GNUNET_OK == \ + GNUNET_CRYPTO_edx25519_sign_ (priv, \ + &(ps)->purpose, \ + sig)); \ } while (0) diff --git a/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_disk_lib.h b/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_disk_lib.h @@ -0,0 +1,823 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-2012 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * + * @file + * Disk IO APIs + * + * @defgroup disk Disk library + * Disk IO APIs + * @{ + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_DISK_LIB_H +#define GNUNET_DISK_LIB_H + +/** + * Handle used to manage a pipe. + */ +struct GNUNET_DISK_PipeHandle; + +/** + * Type of a handle. + */ +enum GNUNET_FILE_Type +{ + /** + * Handle represents an event. + */ + GNUNET_DISK_HANLDE_TYPE_EVENT, + + /** + * Handle represents a file. + */ + GNUNET_DISK_HANLDE_TYPE_FILE, + + /** + * Handle represents a pipe. + */ + GNUNET_DISK_HANLDE_TYPE_PIPE +}; + +/** + * Handle used to access files (and pipes). + */ +struct GNUNET_DISK_FileHandle +{ + /** + * File handle on Unix-like systems. + */ + int fd; +}; + + +/* we need size_t, and since it can be both unsigned int + or unsigned long long, this IS platform dependent; + but "stdlib.h" should be portable 'enough' to be + unconditionally available... */ + +#include <stdlib.h> +#include "gnunet_configuration_lib.h" +#include "gnunet_scheduler_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Specifies how a file should be opened. + */ +enum GNUNET_DISK_OpenFlags +{ + /** + * Open the file for reading + */ + GNUNET_DISK_OPEN_READ = 1, + + /** + * Open the file for writing + */ + GNUNET_DISK_OPEN_WRITE = 2, + + /** + * Open the file for both reading and writing + */ + GNUNET_DISK_OPEN_READWRITE = 3, + + /** + * Fail if file already exists + */ + GNUNET_DISK_OPEN_FAILIFEXISTS = 4, + + /** + * Truncate file if it exists + */ + GNUNET_DISK_OPEN_TRUNCATE = 8, + + /** + * Create file if it doesn't exist + */ + GNUNET_DISK_OPEN_CREATE = 16, + + /** + * Append to the file + */ + GNUNET_DISK_OPEN_APPEND = 32 +}; + +/** + * Specifies what type of memory map is desired. + */ +enum GNUNET_DISK_MapType +{ + /** + * Read-only memory map. + */ + GNUNET_DISK_MAP_TYPE_READ = 1, + + /** + * Write-able memory map. + */ + GNUNET_DISK_MAP_TYPE_WRITE = 2, + + /** + * Read-write memory map. + */ + GNUNET_DISK_MAP_TYPE_READWRITE = 3 +}; + + +/** + * File access permissions, UNIX-style. + */ +enum GNUNET_DISK_AccessPermissions +{ + /** + * Nobody is allowed to do anything to the file. + */ + GNUNET_DISK_PERM_NONE = 0, + + /** + * Owner can read. + */ + GNUNET_DISK_PERM_USER_READ = 1, + + /** + * Owner can write. + */ + GNUNET_DISK_PERM_USER_WRITE = 2, + + /** + * Owner can execute. + */ + GNUNET_DISK_PERM_USER_EXEC = 4, + + /** + * Group can read. + */ + GNUNET_DISK_PERM_GROUP_READ = 8, + + /** + * Group can write. + */ + GNUNET_DISK_PERM_GROUP_WRITE = 16, + + /** + * Group can execute. + */ + GNUNET_DISK_PERM_GROUP_EXEC = 32, + + /** + * Everybody can read. + */ + GNUNET_DISK_PERM_OTHER_READ = 64, + + /** + * Everybody can write. + */ + GNUNET_DISK_PERM_OTHER_WRITE = 128, + + /** + * Everybody can execute. + */ + GNUNET_DISK_PERM_OTHER_EXEC = 256 +}; + + +/** + * Constants for specifying how to seek. Do not change values or order, + * some of the code depends on the specific numeric values! + */ +enum GNUNET_DISK_Seek +{ + /** + * Seek an absolute position (from the start of the file). + */ + GNUNET_DISK_SEEK_SET = 0, + + /** + * Seek a relative position (from the current offset). + */ + GNUNET_DISK_SEEK_CUR = 1, + + /** + * Seek an absolute position from the end of the file. + */ + GNUNET_DISK_SEEK_END = 2 +}; + + +/** + * Enumeration identifying the two ends of a pipe. + */ +enum GNUNET_DISK_PipeEnd +{ + /** + * The reading-end of a pipe. + */ + GNUNET_DISK_PIPE_END_READ = 0, + + /** + * The writing-end of a pipe. + */ + GNUNET_DISK_PIPE_END_WRITE = 1 +}; + + +/** + * Checks whether a handle is invalid + * + * @param h handle to check + * @return #GNUNET_YES if invalid, #GNUNET_NO if valid + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h); + + +/** + * Check that fil corresponds to a filename + * (of a file that exists and that is not a directory). + * + * @param fil filename to check + * @return #GNUNET_YES if yes, #GNUNET_NO if not a file, #GNUNET_SYSERR if something + * else (will print an error message in that case, too). + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_test (const char *fil); + + +/** + * Check that fil corresponds to a filename and the file has read permissions. + * + * @param fil filename to check + * @return #GNUNET_YES if yes, #GNUNET_NO if file doesn't exist or + * has no read permissions, #GNUNET_SYSERR if something else + * (will print an error message in that case, too). + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_test_read (const char *fil); + + +/** + * Move a file out of the way (create a backup) by renaming it to "orig.NUM~" + * where NUM is the smallest number that is not used yet. + * + * @param fil name of the file to back up + * @return the backup file name (must be freed by caller) + */ +char* +GNUNET_DISK_file_backup (const char *fil); + + +/** + * Move the read/write pointer in a file + * @param h handle of an open file + * @param offset position to move to + * @param whence specification to which position the offset parameter relates to + * @return the new position on success, #GNUNET_SYSERR otherwise + */ +off_t +GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, + off_t offset, + enum GNUNET_DISK_Seek whence); + + +/** + * Get the size of the file (or directory) of the given file (in + * bytes). + * + * @param filename name of the file or directory + * @param size set to the size of the file (or, + * in the case of directories, the sum + * of all sizes of files in the directory) + * @param include_symbolic_links should symbolic links be + * included? + * @param single_file_mode #GNUNET_YES to only get size of one file + * and return #GNUNET_SYSERR for directories. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_size (const char *filename, + uint64_t *size, + int include_symbolic_links, + int single_file_mode); + + +/** + * Obtain some unique identifiers for the given file + * that can be used to identify it in the local system. + * This function is used between GNUnet processes to + * quickly check if two files with the same absolute path + * are actually identical. The two processes represent + * the same peer but may communicate over the network + * (and the file may be on an NFS volume). This function + * may not be supported on all operating systems. + * + * @param filename name of the file + * @param dev set to the device ID + * @param ino set to the inode ID + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_get_identifiers (const char *filename, + uint64_t *dev, + uint64_t *ino); + + +/** + * Create an (empty) temporary file on disk. If the given name is not + * an absolute path, the current 'TMPDIR' will be prepended. In any case, + * 6 random characters will be appended to the name to create a unique + * filename. + * + * @param pd project data to use to determine paths + * @param t component to use for the name; + * does NOT contain "XXXXXX" or "/tmp/". + * @return NULL on error, otherwise name of fresh + * file on disk in directory for temporary files + */ +char * +GNUNET_DISK_mktemp (const struct GNUNET_OS_ProjectData *pd, + const char *t); + + +/** + * Create an (empty) temporary directory on disk. If the given name is not an + * absolute path, the current 'TMPDIR' will be prepended. In any case, 6 + * random characters will be appended to the name to create a unique name. + * + * @param pd project data to use to determine paths + * @param t component to use for the name; + * does NOT contain "XXXXXX" or "/tmp/". + * @return NULL on error, otherwise name of freshly created directory + */ +char * +GNUNET_DISK_mkdtemp (const struct GNUNET_OS_ProjectData *pd, + const char *t); + + +/** + * Open a file. Note that the access permissions will only be + * used if a new file is created and if the underlying operating + * system supports the given permissions. + * + * @param fn file name to be opened + * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags + * @param perm permissions for the newly created file, use + * #GNUNET_DISK_PERM_NONE if a file could not be created by this + * call (because of flags) + * @return IO handle on success, NULL on error + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_file_open (const char *fn, + enum GNUNET_DISK_OpenFlags flags, + enum GNUNET_DISK_AccessPermissions perm); + + +/** + * Get the size of an open file. + * + * @param fh open file handle + * @param size where to write size of the file + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, + off_t *size); + + +/** + * Flags for #GNUNET_DISK_pipe(). + */ +enum GNUNET_DISK_PipeFlags +{ + + /** + * No special options, use non-blocking read/write operations. + */ + GNUNET_DISK_PF_NONE, + + /** + * Configure read end to block when reading if set. + */ + GNUNET_DISK_PF_BLOCKING_READ = 1, + + /** + * Configure write end to block when writing if set. + */ + GNUNET_DISK_PF_BLOCKING_WRITE = 2, + + /** + * Configure both pipe ends for blocking operations if set. + */ + GNUNET_DISK_PF_BLOCKING_RW = GNUNET_DISK_PF_BLOCKING_READ + | GNUNET_DISK_PF_BLOCKING_WRITE + +}; + + +/** + * Creates an interprocess channel + * + * @param pf how to configure the pipe + * @return handle to the new pipe, NULL on error + */ +struct GNUNET_DISK_PipeHandle * +GNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf); + + +/** + * Creates a pipe object from a couple of file descriptors. + * Useful for wrapping existing pipe FDs. + * + * @param pf how to configure the pipe + * @param fd an array of two fd values. One of them may be -1 for read-only or write-only pipes + * @return handle to the new pipe, NULL on error + */ +struct GNUNET_DISK_PipeHandle * +GNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, + int fd[2]); + + +/** + * Closes an interprocess channel + * @param p pipe + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p); + + +/** + * Closes one half of an interprocess channel + * + * @param p pipe to close end of + * @param end which end of the pipe to close + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd end); + + +/** + * Detaches one of the ends from the pipe. + * Detached end is a fully-functional FileHandle, it will + * not be affected by anything you do with the pipe afterwards. + * Each end of a pipe can only be detched from it once (i.e. + * it is not duplicated). + * + * @param p pipe to detach an end from + * @param end which end of the pipe to detach + * @return Detached end on success, NULL on failure + * (or if that end is not present or is closed). + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd end); + +/** + * Close an open file. + * + * @param h file handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h); + + +/** + * Get the handle to a particular pipe end + * + * @param p pipe + * @param n end to access + * @return handle for the respective end + */ +const struct GNUNET_DISK_FileHandle * +GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, + enum GNUNET_DISK_PipeEnd n); + + +/** + * Update POSIX permissions mask of a file on disk. If both arguments + * are #GNUNET_NO, the file is made world-read-write-executable (777). + * Does nothing on W32. + * + * @param fn name of the file to update + * @param require_uid_match #GNUNET_YES means 700 + * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set + */ +void +GNUNET_DISK_fix_permissions (const char *fn, + int require_uid_match, + int require_gid_match); + + +/** + * Get a handle from a native integer FD. + * + * @param fno native integer file descriptor + * @return file handle corresponding to the descriptor + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_get_handle_from_int_fd (int fno); + + +/** + * Get a handle from a native FD. + * + * @param fd native file descriptor + * @return file handle corresponding to the descriptor + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_get_handle_from_native (FILE *fd); + + +/** + * Read the contents of a binary file into a buffer. + * + * @param h handle to an open file + * @param result the buffer to write the result to + * @param len the maximum number of bytes to read + * @return the number of bytes read on success, #GNUNET_SYSERR on failure + */ +ssize_t +GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, + void *result, + size_t len); + + +/** + * Read the contents of a binary file into a buffer. + * + * @param fn file name + * @param result the buffer to write the result to + * @param len the maximum number of bytes to read + * @return number of bytes read, #GNUNET_SYSERR on failure + */ +ssize_t +GNUNET_DISK_fn_read (const char *fn, + void *result, + size_t len); + + +/** + * Write a buffer to a file. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return number of bytes written on success, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a buffer to a file, blocking, if necessary. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return number of bytes written on success, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a buffer to a file atomically. The directory is created if + * necessary. Fail if @a filename already exists or if not exactly @a buf + * with @a buf_size bytes could be written to @a filename. + * + * @param fn file name + * @param buf the data to write + * @param buf_size number of bytes to write from @a buf + * @param mode file permissions + * @return #GNUNET_OK on success, + * #GNUNET_NO if a file existed under @a filename + * #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_fn_write (const char *fn, + const void *buf, + size_t buf_size, + enum GNUNET_DISK_AccessPermissions mode); + + +/** + * Copy a file. + * + * @param src file to copy + * @param dst destination file name + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_copy (const char *src, + const char *dst); + + +/** + * Scan a directory for files. + * + * @param dir_name the name of the directory + * @param callback the method to call for each file + * @param callback_cls closure for @a callback + * @return the number of files found, -1 on error + */ +int +GNUNET_DISK_directory_scan (const char *dir_name, + GNUNET_FileNameCallback callback, + void *callback_cls); + +/** + * Find all files matching a glob pattern. + * + * Currently, the glob_pattern only supports asterisks in the last + * path component. + * + * @param glob_pattern the glob pattern to search for + * @param callback the method to call for each file + * @param callback_cls closure for @a callback + * @return the number of files found, -1 on error + */ +int +GNUNET_DISK_glob (const char *glob_pattern, + GNUNET_FileNameCallback callback, + void *callback_cls); + + +/** + * Create the directory structure for storing + * a file. + * + * @param filename name of a file in the directory + * @returns #GNUNET_OK on success, #GNUNET_SYSERR on failure, + * #GNUNET_NO if directory exists but is not writeable + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_create_for_file (const char *filename); + + +/** + * Test if @a fil is a directory and listable. Optionally, also check if the + * directory is readable. Will not print an error message if the directory does + * not exist. Will log errors if #GNUNET_SYSERR is returned (i.e., a file exists + * with the same name). + * + * @param fil filename to test + * @param is_readable #GNUNET_YES to additionally check if @a fil is readable; + * #GNUNET_NO to disable this check + * @return #GNUNET_YES if yes, #GNUNET_NO if not; #GNUNET_SYSERR if it + * does not exist or `stat`ed + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_test (const char *fil, + int is_readable); + + +/** + * Remove all files in a directory (rm -rf). Call with caution. + * + * @param filename the file to remove + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_remove (const char *filename); + + +/** + * Remove the directory given under @a option in + * section [PATHS] in configuration under @a cfg_filename + * + * @param pd project data to use to determine paths + * @param cfg_filename configuration file to parse + * @param option option with the dir name to purge + */ +void +GNUNET_DISK_purge_cfg_dir (const struct GNUNET_OS_ProjectData *pd, + const char *cfg_filename, + const char *option); + + +/** + * Implementation of "mkdir -p" + * + * @param dir the directory to create + * @returns #GNUNET_SYSERR on failure, #GNUNET_OK otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_directory_create (const char *dir); + + +/** + * @brief Removes special characters as ':' from a filename. + * @param fn the filename to canonicalize + */ +void +GNUNET_DISK_filename_canonicalize (char *fn); + + +/** + * @brief Change owner of a file + * @param filename file to change + * @param user new owner of the file + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_change_owner (const char *filename, + const char *user); + + +/** + * Opaque handle for a memory-mapping operation. + */ +struct GNUNET_DISK_MapHandle; + + +/** + * Map a file into memory. + * + * @param h open file handle + * @param m handle to the new mapping (will be set) + * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx + * @param len size of the mapping + * @return pointer to the mapped memory region, NULL on failure + */ +void * +GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, + struct GNUNET_DISK_MapHandle **m, + enum GNUNET_DISK_MapType access, + size_t len); + + +/** + * Unmap a file + * + * @param h mapping handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h); + + +/** + * Write file changes to disk + * + * @param h handle to an open file + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_DISK_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_disk_lib.h */ diff --git a/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_nat_lib.h b/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_nat_lib.h @@ -0,0 +1,248 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +#include "gnunet_common.h" +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +/** + * @addtogroup Backbone + * @{ + * + * @file NAT traversal + * @author t3sserakt + * + * @defgroup nat NAT traversal + * + * @{ + */ +#ifndef GNUNET_NAT_LIB_H +#define GNUNET_NAT_LIB_H + +GNUNET_NETWORK_STRUCT_BEGIN +/** + * Wrapper struct with the average RTT of message to some peer + * and if this peer und us is ready to sync. + */ +struct GNUNET_BurstSync +{ + /** + * The average RTT for the peer to communicate with. + */ + struct GNUNET_TIME_RelativeNBO rtt_average; + + /** + * Is this peer already ready to sync. + */ + enum GNUNET_GenericReturnValue sync_ready; +}; + +/** + * Message send during burst mode. + */ +struct GNUNET_BurstMessage +{ + /** + * The peer who send the msg. + */ + struct GNUNET_PeerIdentity peer; + + /** + * The local port the message was send from. + */ + unsigned int local_port; +}; +GNUNET_NETWORK_STRUCT_END + +/** + * Struct wrapping information we use for starting the burst. + */ +struct GNUNET_StartBurstCls +{ + /** + * A Context which can be inserted into this struct, which is specific for the caller. + */ + void *context; + + /** + * The average RTT between the peers. + */ + struct GNUNET_TIME_Relative rtt; + + /** + * The delay - calculate from the RTT and which peer was ready to sync first, after + * we will start the burst. + */ + struct GNUNET_TIME_Relative delay; + + /** + * Peerstore request to start burst with natted addresses only. + */ + struct GNUNET_PEERSTORE_Monitor *mo; + + /** + * The VirtualLink of the peer to which we like to burst with. + */ + struct VirtualLink *vl; + + /** + * We are ready to start the burst. + */ + unsigned int sync_ready; +}; + +struct GNUNET_UdpSocketInfo; + +typedef void (*GNUNET_NotifyUdpSocket) (struct GNUNET_UdpSocketInfo *sock_info); + +/** + * Struct with the socket we like to use to send messages to another peer. + */ +struct GNUNET_UdpSocketInfo +{ + /** + * This is a linked list. + */ + struct GNUNET_UdpSocketInfo *prev; + + /** + * This is a linked list. + */ + struct GNUNET_UdpSocketInfo *next; + + // The peer the socket is for. + const struct GNUNET_PeerIdentity *peer; + + // The socket to send message with to the peer. + struct GNUNET_NETWORK_Handle *udp_sock; + + /** + * The actual RTT between the peers. + */ + struct GNUNET_TIME_Relative rtt; + + /** + * The peer we like to connect to. + */ + struct GNUNET_PeerIdentity *pid; + + /** + * The notify function to call if burst mode was successful. + */ + GNUNET_NotifyUdpSocket nus; + + /** + * The read task for retrieving a burst message for this socket. + */ + struct GNUNET_SCHEDULER_Task *read_task; + + /** + * Timeout task for this socket. + */ + struct GNUNET_SCHEDULER_Task *timeout_task; + + /** + * The address of the other peer without port. + */ + char *address; + + /** + * Our address without port. + */ + const char *bind_address; + + /** + * The port we are bound to. + */ + unsigned int port; + + /** + * The address of the other peer we received a burst message from. + */ + struct sockaddr *actual_address; + + /** + * Default local port we are bound to. + */ + unsigned int std_port; + + /** + * Flag indicating, if the address is without port information. + */ + enum GNUNET_GenericReturnValue has_port; +}; + + +/** + * Create @a GNUNET_BurstSync message. + * + * @param rtt_average The average RTT for the peer to communicate with. + * @param sync_ready Is this peer already ready to sync. + * + * @return The GNUNET_BurstSync message to send to the other peer. + */ +struct GNUNET_BurstSync * +GNUNET_get_burst_sync_msg (struct GNUNET_TIME_Relative rtt_average, + enum GNUNET_GenericReturnValue sync_ready); + + +/** + * Checks if we are ready and starts burst when we and the other peer is ready. + * + * @param rtt_average The average RTT for the peer to communicate with. + * @param sync_ready Is this peer already ready to sync. + * @param burst_sync The GNUNET_BurstSync from the other peer. + * @param task Task to be executed if both peers are ready. + * @param task_cls Closure for the task. + * + * @return Are we burst ready. This is independent from the other peer being ready. + */ +void +GNUNET_is_burst_ready (struct GNUNET_TIME_Relative rtt_average, + struct GNUNET_BurstSync *burst_sync, + GNUNET_SCHEDULER_TaskCallback task, + struct GNUNET_StartBurstCls *task_cls); + + +/** + * Method to get a UDP socket for a peer that is natted. + * + * @param sock_info Struct with information correlated to a specific port at the other peer. + * @param nus Callback to give the caller the struct GNUNET_UdpSocketInfo to use to connect the other peer. + * @return The initial read task to read from the default socket. + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_get_udp_socket (struct GNUNET_UdpSocketInfo *sock_info, + GNUNET_NotifyUdpSocket nus); + +/** + * Method to stop all sockets we established to the other peer. + * + * @param do_not_touch The network handle we will use to connect to the other peer. This socket must not be closed. + */ +void +GNUNET_stop_burst (struct GNUNET_NETWORK_Handle *do_not_touch); + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition to backbone */ diff --git a/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_os_lib.h b/android_studio/distribution/gnunetutil/lib/arm64-v8a/include/gnunet_os_lib.h @@ -0,0 +1,730 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2011, 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * @author Krista Bennett + * @author Gerd Knorr <kraxel@bytesex.org> + * @author Ioana Patrascu + * @author Tzvetan Horozov + * @author Milan + * + * @file + * Low level process routines + * + * @defgroup os OS library + * Low level process routines. + * + * This code manages child processes. We can communicate with child + * processes using signals. Because signals are not supported on W32 + * and Java (at least not nicely), we can alternatively use a pipe + * to send signals to the child processes (if the child process is + * a full-blown GNUnet process that supports reading signals from + * a pipe, of course). Naturally, this also only works for 'normal' + * termination via signals, and not as a replacement for SIGKILL. + * Thus using pipes to communicate signals should only be enabled if + * the child is a Java process OR if we are on Windoze. + * + * @{ + */ + +#ifndef GNUNET_OS_LIB_H +#define GNUNET_OS_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Flags that determine which of the standard streams + * should be inherited by the child process. + */ +enum GNUNET_OS_InheritStdioFlags +{ + /** + * No standard streams should be inherited. + */ + GNUNET_OS_INHERIT_STD_NONE = 0, + + /** + * When this flag is set, the child process will + * inherit stdin of the parent. + */ + GNUNET_OS_INHERIT_STD_IN = 1, + + /** + * When this flag is set, the child process will + * inherit stdout of the parent. + */ + GNUNET_OS_INHERIT_STD_OUT = 2, + + /** + * When this flag is set, the child process will + * inherit stderr of the parent. + */ + GNUNET_OS_INHERIT_STD_ERR = 4, + + /** + * When these flags are set, the child process will + * inherit stdout and stderr of the parent. + */ + GNUNET_OS_INHERIT_STD_OUT_AND_ERR = 6, + + /** + * Use this option to have all of the standard streams + * (stdin, stdout and stderror) be inherited. + */ + GNUNET_OS_INHERIT_STD_ALL = 7, + + /** + * Should a pipe be used to send signals to the child? + */ + GNUNET_OS_USE_PIPE_CONTROL = 8 +}; + + +/** + * Process information (OS-dependent) + */ +struct GNUNET_OS_Process; + + +/** + * Possible installation paths to request + */ +enum GNUNET_OS_InstallationPathKind +{ + /** + * Return the "PREFIX" directory given to configure. + */ + GNUNET_OS_IPK_PREFIX, + + /** + * Return the directory where the program binaries are installed. (bin/) + */ + GNUNET_OS_IPK_BINDIR, + + /** + * Return the directory where libraries are installed. (lib/gnunet/) + */ + GNUNET_OS_IPK_LIBDIR, + + /** + * Return the directory where data is installed (share/gnunet/) + */ + GNUNET_OS_IPK_DATADIR, + + /** + * Return the directory where translations are installed (share/locale/) + */ + GNUNET_OS_IPK_LOCALEDIR, + + /** + * Return the installation directory of this application, not + * the one of the overall GNUnet installation (in case they + * are different). + */ + GNUNET_OS_IPK_SELF_PREFIX, + + /** + * Return the prefix of the path with application icons (share/icons/). + */ + GNUNET_OS_IPK_ICONDIR, + + /** + * Return the prefix of the path with documentation files, including the + * license (share/doc/gnunet/). + */ + GNUNET_OS_IPK_DOCDIR, + + /** + * Return the directory where helper binaries are installed (lib/gnunet/libexec/) + */ + GNUNET_OS_IPK_LIBEXECDIR +}; + + +/** + * Process status types + */ +enum GNUNET_OS_ProcessStatusType +{ + /** + * The process is not known to the OS (or at + * least not one of our children). + */ + GNUNET_OS_PROCESS_UNKNOWN, + + /** + * The process is still running. + */ + GNUNET_OS_PROCESS_RUNNING, + + /** + * The process is paused (but could be resumed). + */ + GNUNET_OS_PROCESS_STOPPED, + + /** + * The process exited with a return code. + */ + GNUNET_OS_PROCESS_EXITED, + + /** + * The process was killed by a signal. + */ + GNUNET_OS_PROCESS_SIGNALED +}; + + +/** + * Project-specific data used to help the OS subsystem + * find installation paths. + */ +struct GNUNET_OS_ProjectData +{ + /** + * Name of a library that is installed in the "lib/" directory of + * the project, such as "libgnunetutil". Used to locate the + * installation by scanning dependencies of the current process. + */ + const char *libname; + + /** + * Name of the project that is used in the "libexec" prefix, For + * example, "gnunet". Certain helper binaries are then expected to + * be installed in "$PREFIX/libexec/gnunet/" and resources in + * "$PREFIX/share/gnunet/". + */ + const char *project_dirname; + + /** + * Name of a project-specific binary that should be in "$PREFIX/bin/". + * Used to determine installation path from $PATH variable. + * For example "gnunet-arm". On W32, ".exe" should be omitted. + */ + const char *binary_name; + + /** + * Name of an environment variable that can be used to override + * installation path detection, for example "GNUNET_PREFIX". + */ + const char *env_varname; + + /** + * Alternative name of an environment variable that can be used to + * override installation path detection, if "env_varname" is not + * set. Again, for example, "GNUNET_PREFIX". + */ + const char *env_varname_alt; + + /** + * Name of an environment variable that can be used to override + * the location from which default configuration files are loaded + * from, for example "GNUNET_BASE_CONFIG". + */ + const char *base_config_varname; + + /** + * E-mail address for reporting bugs. + */ + const char *bug_email; + + /** + * Project homepage. + */ + const char *homepage; + + /** + * Configuration file name (in $XDG_CONFIG_HOME) to use. + */ + const char *config_file; + + /** + * Configuration file name to use (if $XDG_CONFIG_HOME is not set). + */ + const char *user_config_file; + + /** + * String identifying the current project version. + */ + const char *version; + + /** + * Non-zero means this project is part of GNU. + */ + int is_gnu; + + /** + * Gettext domain for localisation, e.g. the PACKAGE macro. + * Setting this field to NULL disables gettext. + */ + const char *gettext_domain; + + /** + * Gettext directory, e.g. the LOCALEDIR macro. + * If this field is NULL, the path is automatically inferred. + */ + const char *gettext_path; + + /** + * URL pointing to the source code of the application. Required for AGPL. + * Setting this to NULL disables the built-in mechanism, but you must + * provide it in some other way. If non-NULL, message type 1 and 2 are + * reserved. + */ + const char *agpl_url; + + /** + * In case we do not have environment variables to determine the install path, + * the install path can be set explicitly. + */ + const char *install_path_override; +}; + + +/** + * Return default project data used by 'libgnunetutil' for GNUnet. + */ +const struct GNUNET_OS_ProjectData * +GNUNET_OS_project_data_gnunet (void); + + +/** + * Setting project data used by 'libgnunetutil' for GNUnet. + * + * @param project_data data to set instead of default. + */ +void +GNUNET_OS_project_data_gnunet_set (const struct GNUNET_OS_ProjectData *project_data); + + +/** + * Setup OS subsystem for the given project data and package. + * Initializes GNU Gettext. + * + * @param package_name name of the package for GNU gettext + * @param pd project data to use to determine paths + */ +void +GNUNET_OS_init (const char *package_name, + const struct GNUNET_OS_ProjectData *pd); + + +/** + * Get the path to a specific GNUnet installation directory or, with + * #GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation + * directory. + * + * @param pd project data to use to determine paths + * @param dirkind what kind of directory is desired? + * @return a pointer to the dir path (to be freed by the caller) + */ +char * +GNUNET_OS_installation_get_path (const struct GNUNET_OS_ProjectData *pd, + enum GNUNET_OS_InstallationPathKind dirkind); + + +/** + * Given the name of a gnunet-helper, gnunet-service or gnunet-daemon + * binary, try to prefix it with the libexec/-directory to get the + * full path. + * + * @param pd project data to use to determine paths + * @param progname name of the binary + * @return full path to the binary, if possible, otherwise copy of 'progname' + */ +char * +GNUNET_OS_get_libexec_binary_path (const struct GNUNET_OS_ProjectData *pd, + const char *progname); + + +/** + * Given the name of a helper, service or daemon binary construct the full + * path to the binary using the SUID_BINARY_PATH in the PATHS section of the + * configuration. If that option is not present, fall back to + * GNUNET_OS_get_libexec_binary_path. If @a progname is an absolute path, a + * copy of this path is returned. + * + * @param pd project data to use to determine paths + * @param cfg configuration to inspect + * @param progname name of the binary + * @return full path to the binary, if possible, a copy of @a progname + * otherwise + */ +char * +GNUNET_OS_get_suid_binary_path (const struct GNUNET_OS_ProjectData *pd, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *progname); + + +/** + * Callback function invoked for each interface found. + * + * @param cls closure + * @param name name of the interface (can be NULL for unknown) + * @param isDefault is this presumably the default interface + * @param addr address of this interface (can be NULL for unknown or unassigned) + * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) + * @param netmask the network mask (can be NULL for unknown or unassigned) + * @param addrlen length of the address + * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_OS_NetworkInterfaceProcessor)(void *cls, + const char *name, + int isDefault, + const struct sockaddr *addr, + const struct sockaddr *broadcast_addr, + const struct sockaddr *netmask, + socklen_t addrlen); + + +/** + * @brief Enumerate all network interfaces + * + * @param proc the callback function + * @param proc_cls closure for @a proc + */ +void +GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, + void *proc_cls); + +#ifndef HAVE_SYSCONF +#define HAVE_SYSCONF 0 +#endif + +/** + * @brief Get maximum string length returned by gethostname() + */ +#if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX) +#define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf ( \ + _SC_HOST_NAME_MAX); __sc_tmp <= \ + 0 ? 255 : __sc_tmp; }) +#elif defined(HOST_NAME_MAX) +#define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX +#else +#define GNUNET_OS_get_hostname_max_length() 255 +#endif + + +/** + * Get process structure for current process + * + * The pointer it returns points to static memory location and must not be + * deallocated/closed + * + * @return pointer to the process sturcutre for this process + */ +struct GNUNET_OS_Process * +GNUNET_OS_process_current (void); + + +/** + * Sends a signal to the process + * + * @param proc pointer to process structure + * @param sig signal + * @return 0 on success, -1 on error + */ +int +GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, + int sig); + + +/** + * Cleans up process structure contents (OS-dependent) and deallocates it + * + * @param proc pointer to process structure + */ +void +GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc); + + +/** + * Get the pid of the process in question + * + * @param proc the process to get the pid of + * + * @return the current process id + */ +pid_t +GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param argv NULL-terminated array of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_vap ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + char *const argv[]); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param ... NULL-terminated list of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + ...); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param pipe_stdin pipe to use to send input to child process (or NULL) + * @param pipe_stdout pipe to use to get output from child process (or NULL) + * @param pipe_stderr pipe to use to get error output from child process (or NULL) + * @param filename name of the binary + * @param va NULL-terminated list of arguments to the process + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_va ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + struct GNUNET_DISK_PipeHandle *pipe_stdin, + struct GNUNET_DISK_PipeHandle *pipe_stdout, + struct GNUNET_DISK_PipeHandle *pipe_stderr, + const char *filename, + va_list va); + + +/** + * Start a process. + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param lsocks array of listen sockets to dup systemd-style (or NULL); + * must be NULL on platforms where dup is not supported + * @param filename name of the binary + * @param argv NULL-terminated list of arguments to the process, + * including the process name as the first argument + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_v ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + const int *lsocks, + const char *filename, + char *const argv[]); + + +/** + * Start a process. This function is similar to the GNUNET_OS_start_process_* + * except that the filename and arguments can have whole strings which contain + * the arguments. These arguments are to be separated by spaces and are parsed + * in the order they appear. Arguments containing spaces can be used by + * quoting them with @em ". + * + * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags + * @param lsocks array of listen sockets to dup systemd-style (or NULL); + * must be NULL on platforms where dup is not supported + * @param filename name of the binary. It is valid to have the arguments + * in this string when they are separated by spaces. + * @param ... more arguments. Should be of type `char *`. It is valid + * to have the arguments in these strings when they are separated by + * spaces. The last argument MUST be NULL. + * @return pointer to process structure of the new process, NULL on error + */ +struct GNUNET_OS_Process * +GNUNET_OS_start_process_s ( + enum GNUNET_OS_InheritStdioFlags std_inheritance, + const int *lsocks, + const char *filename, + ...); + + +/** + * Handle to a command action. + */ +struct GNUNET_OS_CommandHandle; + + +/** + * Type of a function to process a line of output. + * + * @param cls closure + * @param line line of output from a command, NULL for the end + */ +typedef void +(*GNUNET_OS_LineProcessor) (void *cls, const char *line); + + +/** + * Stop/kill a command. + * + * @param cmd handle to the process + */ +void +GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd); + + +/** + * Run the given command line and call the given function + * for each line of the output. + * + * @param proc function to call for each line of the output + * @param proc_cls closure for proc + * @param timeout when to time out + * @param binary command to run + * @param ... arguments to command + * @return NULL on error + */ +struct GNUNET_OS_CommandHandle * +GNUNET_OS_command_run ( + GNUNET_OS_LineProcessor proc, + void *proc_cls, + struct GNUNET_TIME_Relative timeout, + const char *binary, + ...); + + +/** + * Retrieve the status of a process. + * Nonblocking version. + * + * @param proc pointer to process structure + * @param type status type + * @param code return code/signal number + * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, + enum GNUNET_OS_ProcessStatusType *type, + unsigned long *code); + + +/** + * Wait for a process to terminate. The return code is discarded. + * You must not use #GNUNET_OS_process_status() on the same process + * after calling this function! This function is blocking and should + * thus only be used if the child process is known to have terminated + * or to terminate very soon. + * + * @param proc pointer to process structure of the process to wait for + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc); + + +/** + * Retrieve the status of a process, waiting on it if dead. + * Blocking version. + * + * @param proc pointer to process structure + * @param type status type + * @param code return code/signal number + * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc, + enum GNUNET_OS_ProcessStatusType *type, + unsigned long *code); + + +/** + * Connects this process to its parent via pipe; + * essentially, the parent control handler will read signal numbers + * from the #GNUNET_OS_CONTROL_PIPE (as given in an environment + * variable) and raise those signals. + * + * @param cls closure (unused) + */ +void +GNUNET_OS_install_parent_control_handler (void *cls); + + +/** + * Check whether an executable exists and possibly + * if the suid bit is set on the file. + * Attempts to find the file using the current + * PATH environment variable as a search path. + * + * @param binary the name of the file to check. + * W32: must not have an .exe suffix. + * @param check_suid input true if the binary should be checked for SUID (*nix) + * W32: checks if the program has sufficient privileges by executing this + * binary with the -d flag. -d omits a programs main loop and only + * executes all privileged operations in an binary. + * @param params parameters used for w32 privilege checking (can be NULL for != w32, or when not checking for suid/permissions ) + * @return #GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32), + * #GNUNET_NO if not SUID (but binary exists), + * #GNUNET_SYSERR on error (no such binary or not executable) + */ +enum GNUNET_GenericReturnValue +GNUNET_OS_check_helper_binary (const char *binary, + bool check_suid, + const char *params); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_OS_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_os_lib.h */ diff --git a/android_studio/distribution/gnunetutil/lib/arm64-v8a/libgnunetutil.so b/android_studio/distribution/gnunetutil/lib/arm64-v8a/libgnunetutil.so Binary files differ. diff --git a/android_studio/distribution/libgnunetutil/lib/arm64-v8a/libgnunetutil.so b/android_studio/distribution/libgnunetutil/lib/arm64-v8a/libgnunetutil.so Binary files differ. diff --git a/android_studio/settings.gradle.kts b/android_studio/settings.gradle.kts @@ -16,6 +16,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + mavenLocal() } }